下面给出的代码适用于大小小于13的国际象棋,但在此之后需要花费太多时间并且永远运行。 我想减少到达终点节点的时间。 此代码还找到从starti,startj到endi,endj的最小路径,其中starti和startj的值从1到n-1。
以下是我要解决的问题:
https://www.hackerrank.com/challenges/knightl-on-chessboard/problem
计划:
import java.util.LinkedList;<br>
import java.util.Scanner;
class Node {
int x,y,dist;
Node(int x, int y, int dist) {
this.x = x;
this.y = y;
this.dist = dist;
}
public String toString() {
return "x: "+ x +" y: "+y +" dist: "+dist;
}
}
class Solution {
public static boolean checkBound(int x, int y, int n) {
if(x >0 && y>0 && x<=n && y<=n)
return true;
return false;
}
public static void printAnswer(int answer[][], int n) {
for(int i=0; i<n-1; i++) {
for(int j=0; j<n-1; j++) {
System.out.print(answer[i][j]+" ");
}
System.out.println();
}
}
public static int findMinimumStep(int n, int[] start, int[] end, int a, int b) {
LinkedList<Node> queue = new LinkedList();
boolean visited[][] = new boolean[n+1][n+1];
queue.add(new Node(start[0],start[1],0));
int x,y;
int[] dx = new int[] {a, -a, a, -a, b, -b, b, -b};
int[] dy = new int[] {b, b, -b, -b, a, a, -a, -a};
while(!queue.isEmpty()) {
Node z = queue.removeFirst();
visited[z.x][z.y] = true;
if(z.x == end[0] && z.y == end[1])
return z.dist;
for(int i=0; i<8; i++)
{
x = z.x + dx[i];
y = z.y + dy[i];
if(checkBound(x,y,n) && !visited[x][y])
queue.add(new Node(x,y,z.dist+1));
}
}
return -1;
}
public static void main(String args[]) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int start[] = new int[] {1,1};
int goal[] = new int[] {n,n};
int answer[][] = new int[n-1][n-1];
for(int i=1; i<n; i++) {
for(int j=i; j<n; j++) {
int result = findMinimumStep(n, start, goal, i, j);
answer[i-1][j-1] = result;
answer[j-1][i-1] = result;
}
}
printAnswer(answer,n);
}
}
答案 0 :(得分:2)
您设置visited
太晚了,并且将相同的单元格多次添加到队列中,然后您从队列中弹出它们而不检查其访问状态会使事情变得更糟。这导致队列的快速增长。
您需要在将visited
添加到队列后立即设置Node
:
if(checkBound(x,y,n) && !visited[x][y]) {
queue.add(new Node(x,y,z.dist+1));
visited[x][y] = true;
}
答案 1 :(得分:0)
答案 2 :(得分:0)
您问题中最有效的解决方案是Dijkstra's algorithm。将方块视为节点并将边缘绘制为骑士可以访问的其他方块/节点。然后运行此图的算法。它在对数时间内执行,因此它可以很好地解决大问题。
MrSmith提出的A *搜索建议,是一种启发式方法,因此我不会就此类问题提出建议。
Dijkstra是一个重要的算法,实现它将帮助您在将来解决许多类似的问题,例如您也可以用相同的逻辑解决this problem问题。