给定一个正整数的N x N矩阵,我需要找到从矩阵的第一个单元格到矩阵的最后一个单元格的最短路径。我可以从任何单元格中精确地移动x步,其中x是单元格的值。可能的移动是向右还是向下,即从任何单元格M [i] [j]我可以移动到位置M [i + M [i] [j]] [j]或M [i] [j + M [i] ] [j]]。
例如:
int[][] matrix =
{
{1, 2, 1},
{1, 1, 1},
{1, 1, 1}
};
将其作为字符串列表返回,输出为:[[0,0),(0,1),(2,1),(2,2)]
我已经实现了一个可行的解决方案,但是我想知道我是否可以改善时间复杂度?
下面是代码
class Node {
// queue node used in BFS
// (x, y) represents coordinates of a cell in matrix
int x, y;
// maintain a parent node for printing final path
Node parent;
Node(int x, int y, Node parent) {
this.x = x;
this.y = y;
this.parent = parent;
}
@Override
public String toString() {
return "(" + x + ", " + y + ')';
}
}
class Solution {
LinkedList<String> shortestPathList = new LinkedList<>();
public List<String> getShortestPath(int[][] matrix) {
if (matrix == null) {
return Collections.emptyList();
}
Node node = findPath(matrix, 0, 0);
AddToPath(node);
return shortestPathList;
}
// possible movements
private static int[] row = {0, 1};
private static int[] col = {1, 0};
// The function returns false if is not a valid position
private static boolean isValid(int x, int y, int matrixLength) {
return (x >= 0 && x < matrixLength) && (y >= 0 && y < matrixLength);
}
// Find shortest route in the matrix from source cell (x, y) to
// destination cell (N - 1, N - 1)
public static Node findPath(int matrix[][], int x, int y) {
int matrixLength = matrix.length;
// create a queue and enqueue first node
Queue<Node> q = new ArrayDeque<>();
Node src = new Node(x, y, null);
q.add(src);
// set to check if matrix cell is visited before or not
Set<String> visited = new HashSet<>();
String key = src.x + "," + src.y;
visited.add(key);
// run till queue is not empty
while (!q.isEmpty()) {
// pop front node from queue and process it
Node curr = q.poll();
int i = curr.x, j = curr.y;
// return if destination is found
if (i == matrixLength - 1 && j == matrixLength - 1) {
return curr;
}
// value of current cell
int n = matrix[i][j];
// check both 2 possible movements from current cell
// and recur for each valid movement
for (int k = 0; k < 2; k++) {
// get next position coordinates using value of current cell
x = i + row[k] * n;
y = j + col[k] * n;
// check if it is possible to go to next position
// from current position
if (isValid(x, y, matrixLength)) {
// construct next cell node
Node next = new Node(x, y, curr);
key = next.x + "," + next.y;
// if it not visited yet
if (!visited.contains(key)) {
// push it into the queue and mark it as visited
q.add(next);
visited.add(key);
}
}
}
}
// return null if path is not possible
return null;
}
//function to get path from start to end
private void AddToPath(Node node) {
if (node == null) {
return;
}
shortestPathList.addFirst(node.toString());
printPath(node.parent);
}
}