1. 程式人生 > 其它 >劍指offer: JZ13 機器人的運動範圍

劍指offer: JZ13 機器人的運動範圍

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;
            }
        }
    }