简体   繁体   中英

Generate the steps for a given string by traversing a graph

You have the following grid.

 ABCD EFGH IJKL MNOP QRST UVWX YZ 

You cursor starts at A always and you have the operation Left (L), Right (R), Up (U), Down (D) and Enter (E). QUESTION: Given a string, print the sequence of operation to generate the string?

For example :

> INPUT : CGH 
> OUTPUT : R R E D E R E

This question was asked to me in the interview.

My approach : I thought to solve this by calculating the manhattan distance and do a BFS on the graph, but i think so it is not optimal. and even i need to change the manhattan distance for every letter. Thanks in advance

Naive approach one can start from. Hint: look at the initial sequence as a matrix, every letter has a position: row and column indeces.

Step 1.

Build a hashtable: key - is letter, value - is indeces in the 2d matrix. You would use this for fast lookup, for example given letter 'C' what is its matrix indeces? It is [0,2].

Building takes O(N) time and O(N) space as you need to iterate over the input and store it. Resolving a letter takes O(1) in average case + if you use a good hash function the worst case of O(N) wouldn't be a problem.

Step 2.

Given 2 letters from the input resolve the offset. This will give you the desired chunk of the output sequence.

This takes O(1) time and O(1) space.

Step 3.

Repeat step 2 until you reach the end of sequence.

This takes O(N) time and O(N) space that is used for building the output.

Summary.

This solution uses hashtable for fast letter look up. Offset for resolving the paths (L/R/U/D/E) It also takes O(N) time complexity and O(N) space complexity.

First of all the position of the letter in the grid is easy to compute:

function get_pos( c : char)
begin
  int col ← (c-'A') modulo 4
  int row ← (c-'A') div 4
  return (row,col)
end

Assuming positions (6,2) and (6,3) can be used

We can simply define a subtraction between cell coordinates as:

function subtract( pos1, pos2 : position )
begin
  return (pos2.row-pos1.row, pos2.col-pos1.col)
end

If the subtraction yields a pair (x,y) then the path is simply x times the chararacter 'R' if x is positive or 'L' if x is negative possibliy nothing if x is zero, and similarly y times the character 'D' if y is positive or 'U' if y is negative possibly nothing if y is zero, then we end with the character 'E'.

function print_row_path( pos1, pos2 : position )
begin
  path ← subtract(pos1,pos2)
  if path.row > 0 then
    print_times_char(path.row,'R')
  else if path.row < 0
    print_times_char(-path.row,'L')
  end if
end


function print_col_path( pos1, pos2 : position )
begin
  path ← subtract(pos1,pos2)
  if path.col > 0 then
    print_times_char(path.col,'D')
  else if path.col < 0
    print_times_char(-path.col,'U')
  end if
end

function print_path_direction( pos1, pos2 : position ; first_direction : direction )
begin
  if (first_direction = FIRST_MOVE_ROW) then
    print_row_path(pos1,pos2)
    print_col_path(pos1,pos2)
  else
    print_col_path(pos1,pos2)
    print_row_path(pos1,pos2)
  end if
  print 'E'
end

function print_path(start, end : char)
begin
  position pos1 ← get_pos(start)
  position pos2 ← get_pos(end)
  print_path_direction(pos1,pos2, FIRST_MOVE_ROW)
end

Where print_times_char(t,c) is a function which prints t times the character c. I defined two "flavours" of path printing, one printing the row movements first and another printing column movements first.

Assuming positions (6,2) and (6,3) are forbiden

If we're not allowed to use positions (6,2) and (6,3) then:

  • if 'A' ≤ start,end ≤ 'X' or 'Y' ≤ start,end ≤ 'Z' : (6,2) or (6.3) will never be used in the path
  • if 'A' ≤ start ≤ 'X' and 'Y' ≤ end ≤ 'Z' : to ensure to not use forbidden cells print columns movements first
  • if 'A' ≤ end ≤ 'X' and 'Y' ≤ start ≤ 'Z' : this time we have to print row movements first

In pseudo code:

function print_path_wo_forbidden(start, end : char)
begin
  position pos1 ← get_pos(start)
  position pos2 ← get_pos(end)
  if if 'A' ≤ start ≤ 'X' and 'Y' ≤ end ≤ 'Z' then
    print_path_direction(pos1,pos2, FIRST_MOVE_COLUMN)
  else
    print_path_direction(pos1,pos2, FIRST_MOVE_COLUMN)
  end if
end

Complexity

Printing the path between two positions is clearly in O(1), so for a string of length n we can build an O(n) algorithm.

您可以将字母表示为坐标对A = [0,0], F = [1,1]等,然后您只需计算当前字母与所需字母之间的偏移量并使用它即可。

What oleski said, but honestly, a hashtable is too much needless programming work, especially if your language doesn't have a native one.

It's often much easier to use an array to map your grid locations like so:

struct point{
   int x; 
   int y;
};

point map[256];
point['C'] = (0,2);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM