</pre><p>起点到终点的最短拐弯路径(需要小于等于2)</p>广度优先遍历: 需要一个栈,需要判断是否访问过(bool数组实现)。数据结构: 定义遍历中走过的节点数据结构为Station。 最终需要的结果是路径,但是广度优先遍历中,各路径是同时走的,所以不容易通过一个全局的变量来构建各条不相关的路径,所以直接在Station保存从起点过来的路径。同时保存从起点过来的拐弯数量。 如何判断拐弯:假如路径是a->b->c,只需判断a和c是否x值和y值都不相同。 终止条件: 1.超过图边界。 2.拐弯大于2 3.没有访问过 4.不是障碍 5.终点不适用于以上3和4条<p> </p><p><pre name="code" class="java"> public static final int N = 4;
//图抽象化
public static int[][] ARR = { {0,1,3,5},
{2,4,0,0},
{3,2,0,4},
{2,4,0,1}};
//路径移动抽象化
public static int[][] MOVE = {
{0,-1},
{-1,0},
{0, 1},
{1, 0}
};
public static List<Node> findPath(Node a, Node b){
Station best = null;
boolean[][] visit = new boolean[N][N];
Queue<Station> queue = new ArrayDeque<Station>();
List<Node> firstPath = new ArrayList<Node>();
firstPath.add(a);
queue.add(new Station(a.x,a.y,firstPath,0));
while (queue.size() != 0){
Station station = queue.poll();
for (int i = 0; i < 4; i++) {
int moveX = MOVE[i][0];
int moveY = MOVE[i][1];
//广度优先搜索实现
int x = station.x + moveX;
if(x<0 || x>N-1)
continue;
int y = station.y + moveY;
if(y<0 || y>N-1)
continue;
if(visit[x][y])
continue;
if(x!=b.x || y!=b.y){//不是终点
visit[x][y] = true;
//障碍条件判断
if(ARR[x][y] != 0)
continue;
}
//计算路径和拐弯
Node curr = new Node(x,y);
List<Node> oldPath = station.getPath();
int corner = station.corner;
if(oldPath.size() > 1){
Node pre = oldPath.get(oldPath.size()-2);
Node last = curr;
if(last.x != pre.x && last.y != pre.y) {//拐弯了
corner++;
}
if(corner > 2)
continue;
}
List<Node> path = new ArrayList<Node>();
path.addAll(oldPath);
path.add(curr);
//判断是否找到目标点
if(x==b.x && y==b.y){
if(best==null || corner<best.corner)//拐弯最少的胜出
best = new Station(x, y,path,corner);
}else{
queue.add(new Station(x, y,path,corner));
}
}
}
return best==null ? null : best.getPath();
}
public static void main(String[] args) throws InterruptedException {
System.out.println(findPath(new Node(1,1),new Node(2,3)));
}
@Data
@AllArgsConstructor
public static class Node{
int x;
int y;
}
@Data
@AllArgsConstructor
public static class Station{
int x;
int y;
List<Node> path;
int corner;
}
判断死锁:在遍历中添加当前节点和起点是否是同一类节点的判断,有的话直接返回true,死锁时返回false。