劍指offer: JZ13 機器人的運動範圍
阿新 • • 發佈:2021-11-03
DFS、BFS解決JZ13機器人的運動範圍
描述
地上有一個 rows 行和 cols 列的方格。座標從 [0,0] 到 [rows-1,cols-1] 。一個機器人從座標 [0,0] 的格子開始移動,每一次只能向左,右,上,下四個方向移動一格,但是不能進入行座標和列座標的數位之和大於 threshold 的格子。 例如,當 threshold 為 18 時,機器人能夠進入方格 [35,37] ,因為 3+5+3+7 = 18。但是,它不能進入方格 [35,38] ,因為 3+5+3+8 = 19 。請問該機器人能夠達到多少個格子? 輸入:1,2,3返回值:3
分析
通過列印這個地圖的座標(0代表可行走1代表不可行走)可以看出,通過回溯dfs的方法就可以計算出所能走的路徑,以及不斷計算節點周圍能走動的節點得出答案bfs,本人採用了兩種方案分別實現了本題目
程式碼
/** * JZ13 機器人的運動範圍 * @param threshold * @param rows * @param cols * @return */ public int movingCount(int threshold, int rows, int cols) { int maps[][] = new int[rows][cols]; //通過輸入的值進行地圖的二維陣列初始化 for (int i = 0;i<maps.length;i++) { for (int j = 0;j<maps[0].length;j++) { if ((i/100+i/10+i % 10) + (j/100+j/10+j%10)>threshold) maps[i][j] = 1; } } //列印地圖供理解 for (int i = 0;i<maps.length;i++) { for (int j = 0;j< maps[i].length;j++) { System.out.print(maps[i][j]); } System.out.println(); } //初始化地圖的每個節點 MoveMapNode nodesMap[][] = new MoveMapNode[rows][cols]; for (int i = 0;i<maps.length;i++) { for (int j =0;j<maps[i].length;j++) { MoveMapNode node = new MoveMapNode(maps[i][j],i,j,maps); nodesMap[i][j] = node; } } return movingCountBFS(nodesMap); } /** * bfs實現 * @param nodesMap * @return */ public int movingCountBFS(MoveMapNode nodesMap[][]) { Queue<MoveMapNode> nodesQueue = new LinkedList<>(); nodesQueue.offer(nodesMap[0][0]); int count = 1; nodesMap[0][0].canVisit = false; while (nodesQueue.size()>0) { //上 if (nodesQueue.peek().x > 0 && nodesMap[nodesQueue.peek().x - 1][nodesQueue.peek().y].canVisit == true) { nodesMap[nodesQueue.peek().x - 1][nodesQueue.peek().y].canVisit = false; nodesQueue.offer(nodesMap[nodesQueue.peek().x - 1][nodesQueue.peek().y]); count ++; } //下 if (nodesQueue.peek().x < nodesMap.length - 1 && nodesMap[nodesQueue.peek().x + 1][nodesQueue.peek().y].canVisit == true) { nodesMap[nodesQueue.peek().x + 1][nodesQueue.peek().y].canVisit = false; nodesQueue.offer(nodesMap[nodesQueue.peek().x + 1][nodesQueue.peek().y]); count ++; } //左 if (nodesQueue.peek().y > 0 && nodesMap[nodesQueue.peek().x][nodesQueue.peek().y - 1].canVisit == true) { nodesMap[nodesQueue.peek().x][nodesQueue.peek().y - 1].canVisit = false; nodesQueue.offer(nodesMap[nodesQueue.peek().x][nodesQueue.peek().y - 1]); count ++; } //右 if (nodesQueue.peek().y < nodesMap[0].length - 1 && nodesMap[nodesQueue.peek().x][nodesQueue.peek().y + 1].canVisit == true) { nodesMap[nodesQueue.peek().x][nodesQueue.peek().y + 1].canVisit = false; nodesQueue.offer(nodesMap[nodesQueue.peek().x][nodesQueue.peek().y + 1]); count ++; } nodesQueue.poll(); } return count; } /** * dfs實現 * @param nodesMap * @return */ public int movingCountDFS(MoveMapNode nodesMap[][]) { Stack<MoveMapNode> stack = new Stack<>(); stack.push(nodesMap[0][0]); int count = 1; while (stack.size() > 0) { if (stack.peek().x - 1 > 0 && nodesMap[stack.peek().x - 1][stack.peek().y].canVisit == true) { //向上判斷 stack.push(nodesMap[stack.peek().x - 1][stack.peek().y]); stack.peek().canVisit = false; count ++; }else if (stack.peek().x + 1 <nodesMap.length && nodesMap[stack.peek().x + 1][stack.peek().y].canVisit == true) { //向下判斷 stack.push(nodesMap[stack.peek().x + 1][stack.peek().y]); stack.peek().canVisit = false; count ++; }else if (stack.peek().y - 1 > 0 && nodesMap[stack.peek().x][stack.peek().y - 1].canVisit == true) { //向左判斷 stack.push(nodesMap[stack.peek().x][stack.peek().y - 1]); stack.peek().canVisit = false; count ++; }else if (stack.peek().y + 1 < nodesMap[0].length && nodesMap[stack.peek().x][stack.peek().y + 1].canVisit == true) { //向右判斷 stack.push(nodesMap[stack.peek().x][stack.peek().y + 1]); stack.peek().canVisit = false; count ++; }else { stack.pop(); } } return count; } /** * 每個節點的實體類 */ class MoveMapNode{ int number; int x; int y; boolean canVisit = true; //如果當前節點為1就代表不能走動,置canVisit為false MoveMapNode(int number,int x,int y,int[][]map) { this.number = number; this.x = x; this.y = y; if (number == 1) { canVisit = false; } } }