LeetCode[Java-BFS模板]

279.完全平方数
  给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。

  给你一个整数 n ,返回和为 n 的完全平方数的 最少数量 。

  完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。

问题分析
  可以将每个整数看成图中的一个节点,如果两个整数之差为一个平方数,那么这两个整数所在的节点就有一条边。

  要求解最小的平方数数量,就是求解从节点 n 到节点 0 的最短路径。

class Solution {
    public int numSquares(int n) {
        List<Integer> squares = generateSquares(n);
        Queue<Integer> queue = new LinkedList<>();
        boolean[] marked = new boolean[n + 1];
        queue.add(n);
        marked[n] = true;
        int level = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            level++;
            while (size-- > 0) {
                int cur = queue.poll();
                for (int s : squares) {
                    int next = cur - s;
                    if (next < 0) {
                        break;
                    }
                    if (next == 0) {
                        return level;
                    }
                    if (marked[next]) {
                        continue;
                    }
                    marked[next] = true;
                    queue.add(next);
                }
            }
        }
        return n;
    }

    /**
    * 生成小于 n 的平方数序列
    * @return 1,4,9,...
    */
    private List<Integer> generateSquares(int n) {
        List<Integer> squares = new ArrayList<>();
        int square = 1;
        int diff = 3;
        while (square <= n) {
            squares.add(square);
            square += diff;
            diff += 2;
        }
        return squares;
    }
}

1091. 二进制矩阵中的最短路径
问题
  给你一个 n x n 的二进制矩阵 grid 中,返回矩阵中最短 畅通路径 的长度。如果不存在这样的路径,返回 -1 。

  二进制矩阵中的 畅通路径 是一条从 左上角 单元格(即,(0, 0))到 右下角 单元格(即,(n - 1, n - 1))的路径,该路径同时满足下述要求:

  • 路径途经的所有单元格都的值都是 0 。
  • 路径中所有相邻的单元格应当在 8 个方向之一 上连通(即,相邻两单元之间彼此不同且共享一条边或者一个角)。

  畅通路径的长度 是该路径途经的单元格总数。

代码

class Solution{
    public int shortestPathBinaryMatrix(int[][] grids) {
        if (grids == null || grids.length == 0 || grids[0].length == 0) {
            return -1;
        }
        int[][] direction = {{1, -1}, {1, 0}, {1, 1}, {0, -1}, {0, 1}, {-1, -1}, {-1, 0}, {-1, 1}};
        int m = grids.length, n = grids[0].length;
        Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
        queue.add(new Pair<>(0, 0));
        int pathLength = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            pathLength++;
            while (size-- > 0) {
                Pair<Integer, Integer> cur = queue.poll();
                int cr = cur.getKey(), cc = cur.getValue();
                if (grids[cr][cc] == 1) {
                    continue;
                }
                if (cr == m - 1 && cc == n - 1) {
                    return pathLength;
                }
                grids[cr][cc] = 1; // 标记
                for (int[] d : direction) {
                    int nr = cr + d[0], nc = cc + d[1];
                    if (nr < 0 || nr >= m || nc < 0 || nc >= n) {
                        continue;
                    }
                    queue.add(new Pair<>(nr, nc));
                }
            }
        }
        return -1;
    }
}
// 下面的为超时代码
// class Solution {
//     int[][] d = {{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
//     int max = -1;
//     public int shortestPathBinaryMatrix(int[][] grid) {
//         int[][] find = new int[grid.length][grid.length];
//         for(int i = 0; i < grid.length; ++i){
//             Arrays.fill(find[i], 0);
//         }
//         if(grid[0][0] == 1) {
//             return -1;
//         }
//         trace(grid,find,1,0,0);
//         return max;
//     }

//     public void trace(int[][] grid, int[][] find, int cur, int x, int y){
//         if(x == grid.length-1 && y == grid.length-1){
//             max = (max == -1 || max > cur) ? cur : max;
//             //System.out.println(max);
//         }
//         if(max != -1 && cur > max){
//             return ;
//         }
//         for(int[] num : d){
//             if(help(grid, find, x+num[0], y+num[1])){
//                 find[x+num[0]][y+num[1]] = 1;
//                 trace(grid, find, cur + 1, x+num[0], y+num[1]);
//                 find[x+num[0]][y+num[1]] = 0;
//             }
//         }
//         return ;
//     }

//     public boolean help(int[][] grid, int[][] find, int x, int y){
//         if(x < 0 || x >= grid.length || y < 0 || y >= grid.length){
//             return false;
//         }
//         if(find[x][y] == 1 || grid[x][y] == 1){
//             return false;
//         }
//         return true;
//     }
// }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值