The lexicographically smallest path in the N * M grid

I met this in a recent interview. We are given a N * M grid consisting of numbers, and the path in the grid is the nodes that you go through. We are given a restriction that we can only move to the right or down in the grid. Therefore, given this grid, we need to find the smallest path lehographically, after sorting, in order to reach from the upper left to the lower right points of the grid
. For example. if the grid is 2 * 2
4 3
5 1
then the lessographically smallest path on the subject is β€œ1 3 4”. How to do it? Code is welcome. Thanks in advance.

+4
source share
3 answers

. f(i, j) - ( ) (i, j) (N, M), . :

f(i, j) = sort( a(i, j) + smallest(f(i + 1, j), f(i, j + 1)))

a(i, j) - (i, j), smallest (x, y) x y. + , sort(str) str .

:

f(N, M) = a(N, M)

i = N j = M (, ).

, C++:

//-- the 200 is just the array size. It can be modified

string a[200][200];             //-- represent the input grid
string f[200][200];             //-- represent the array used for memoization
bool calculated[200][200];      //-- false if we have not calculate the value before, and true if we have
int N = 199, M = 199;           //-- Number of rows, Number of columns


//-- sort the string str and return it
string srt(string &str){
    sort(str.begin(), str.end());
    return str;
}


//-- return the smallest of x and y
string smallest(string & x, string &y){
    for (int i = 0; i < x.size(); i++){
        if (x[i] < y[i]) return x;
        if (x[i] > y[i]) return y;
    }
    return x;
}



string solve(int i, int j){
    if (i == N && j == M) return a[i][j];       //-- if we have reached the buttom right cell (I assumed the array is 1-indexed
    if (calculated[i][j]) return f[i][j];       //-- if we have calculated this before 
    string ans;
    if (i == N) ans = srt(a[i][j] + solve(i, j + 1));       //-- if we are at the buttom boundary
    else if (j == M) ans = srt(a[i][j] + solve(i + 1, j));  //-- if we are at the right boundary
    else ans = srt(a[i][j] + smallest(solve(i, j + 1), solve(i + 1, j)));       
    calculated[i][j] = true;        //-- to fetch the calculated result in future calls
    f[i][j] = ans;
    return ans;
}


string calculateSmallestPath(){
    return solve(1, 1);
}
+4

O(N * M * (N + M)) .

, N - , M - , (0, 0), .

, . 0 , . .

:

path[0][0] <- a[0][0]
path[i][0] <- insert(a[i][0], path[i - 1][0])
path[0][j] <- insert(a[0][j], path[0][j - 1])
path[i][j] <- insert(a[i][j], min(path[i - 1][j], path[i][j - 1])
0

, O (NM log (NM)).

:

, (a,b) (c,d) G(a,b,c,d). , , G. , , (i,j), G(i,b,c,j) G(a,j,i,d) min ( ). . ? , , G(a,b,c,d) ( (i,j)). (i,j), , , .

enter image description here

, min G(1,1,m,n). , (i,j). . min G(1,1,i,j) G(i,j,m,n) . , m+n-1 , . G(1,1,m,n) , .

:

G . , ? - Dict, (i,j), (i,j). , .

, . G(1,1,m,n).

S.

, T(G), G(a,b,c,d) in T, G.left = G(a,b,i,j) G.right = G(i,j,c,d), (i,j) = location of min val in G(a,b,c,d)

:

for each val in sorted key set S do
    (i,j) <- Dict(val)
    Grid G <- Root(T)
    do while (i,j) in G
       if G has no child do
           G.left <- G(a,b,i,j)
           G.right <- G(i,j,c,d)
       else if (i,j) in G.left
           G <- G.left
       else if (i,j) in G.right
           G <- G.right
       else 
           dict(val) <- null
           end do
       end if-else
    end do
end for
for each val in G(1,1,m,n)
    if dict(val) not null
        solution.append(val)
    end if
end for
return solution

Java:

class Grid{
    int a, b, c, d;
    Grid left, right;
    Grid(int a, int b, int c, int d){
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
        left = right = null;
    }
    public boolean isInGrid(int e, int f){
        return (e >= a && e <= c && f >= b && f <= d);
    }
    public boolean hasNoChild(){
        return (left == null && right == null);
    }
}
public static int[] findPath(int[][] arr){
        int row = arr.length;
        int col = arr[0].length;
        int[][] index = new int[row*col+1][2];
        HashMap<Integer,Point> map = new HashMap<Integer,Point>();
        for(int i = 0; i < row; i++){
            for(int j = 0; j < col; j++){
                map.put(arr[i][j], new Point(i,j));
            }
        }
        Grid root = new Grid(0,0,row-1,col-1);
        SortedSet<Integer> keys = new TreeSet<Integer>(map.keySet());
        for(Integer entry : keys){
            Grid temp = root;
            int x = map.get(entry).x, y = map.get(entry).y;
            while(temp.isInGrid(x, y)){
                if(temp.hasNoChild()){
                    temp.left = new Grid(temp.a,temp.b,x, y);
                    temp.right = new Grid(x, y,temp.c,temp.d);
                    break;
                }
                if(temp.left.isInGrid(x, y)){
                    temp = temp.left;
                }
                else if(temp.right.isInGrid(x, y)){
                    temp = temp.right;
                }
                else{
                    map.get(entry).x = -1;
                    break;
                }
            }

        }
        int[] solution = new int[row+col-1];
        int count = 0;
        for(int i = 0 ; i < row; i++){
            for(int j = 0; j < col; j++){
                if(map.get(arr[i][j]).x >= 0){
                    solution[count++] = arr[i][j];
                }
            }
        }
        return solution;
    }

- O(NM) - O(N+M). : O(NM)

, - O(NM log(NM)); NM - O(NM log(N+M)). - O(NM log(NM)).

, , , (i,j) , .

FYI: , , , - , , 1 to NM. O(NM log(N+M)), ( .)

0

All Articles