【框架】广度优先搜索 BFS

广度优先搜索算法由于其横向扫描树的叶子节点的特性,所以一旦发现解便是最优解,故适用于“最少多少次”,“最少数量”等问题,需要使用的数据结构是队列。

相关题目:

LeetCode 111.二叉树的最小深度

给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。说明:叶子节点是指没有子节点的节点。

示例 1:

输入:root = [3,9,20,null,null,15,7](根节点为3,根节点的左节点为9,根节点的右节点为20,9节点的左右节点都为null,20节点的左节点为15,20节点的右节点为7)
输出:2
示例 2:

输入:root = [2,null,3,null,4,null,5,null,6](一直右子树)
输出:5

class Solution {
    public int minDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root);
        int depth = 1;
        while(!q.isEmpty()){
            int len = q.size();
            for(int i = 0; i < len; i++){
                TreeNode temp = q.poll();
                if(temp.left == null && temp.right == null){
                    return depth;
                }
                if(temp.left != null){
                    q.offer(temp.left);
                }
                if(temp.right != null){
                    q.offer(temp.right);
                }
            }
            depth = depth + 1;
        }
        return depth;
    }
}

leetcode 279 完全平方数

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

示例 1:

输入: n = 12
输出: 3 
解释: 12 = 4 + 4 + 4.
示例 2:

输入: n = 13
输出: 2
解释: 13 = 4 + 9

代码及注释如下:

class Solution {
    public int numSquares(int n) {
        if(n==1 || n==0){ //特殊情况
            return 1;
        }
        List<Integer> temp_list = new ArrayList<>(); //用于存储需要用到的完全平方数
        Set<Integer> sets = new HashSet<>(); //用于存储已计算的情况,剪枝
        for(int i = 1; i < n; i++){
            if(i*i<=n){
                temp_list.add(i*i);
            }
        }
        int depth = 0;
        Queue<Integer> queue = new LinkedList<>(); //用于实现BFS的队列
        queue.add(0);
        queue.add(-1); // -1 用于计算当前处于树的第几层
        while(!queue.isEmpty()){
            int temp = queue.poll();
            if(temp == -1){ //若从队列中取出的数为-1,说明本层结束了
                depth = depth + 1;
                if(queue.peek() == null){ //若取出队列顶部的元素后队列为空,问题无解,跳出循环
                    break;
                }
                else if (queue.peek() != -1) //否则添加-1至队尾,表示该层叶子节点已全部入队
                    queue.add(-1);
            }else{
                for(int i = 0; i < temp_list.size(); i++){
                    if(temp + temp_list.get(i) < n){
                        if(!sets.contains(temp + temp_list.get(i))){ //若当前计算的解(即访问至某叶子节点的路径)满足问题条件且未曾计算
                            queue.add(temp + temp_list.get(i)); //则将其加入队列末尾,以供将来下一层叶子节点的计算
                            sets.add(temp + temp_list.get(i)); //并将其添加至已访问路径集合,用于剪枝
                        } 
                    }else if(temp + temp_list.get(i) == n){ //找到解,返回
                        return depth+1;
                    }
                }
            }
        }
        return 0;
    }
}

leetcode 752 打开转盘锁

class Solution {
    public int openLock(String[] deadends, String target) {
        char[] lock = {'0','1','2','3','4','5','6','7','8','9'};
        int depth = 0;
        Queue<int[]> queue = new LinkedList<>();
        Set<String> sets = new HashSet<String>(Arrays.asList(deadends));
        if(sets.contains("0000")){
            return -1;
        }if(target.equals("0000")){
            return 0;
        }
        queue.add(new int[]{0,0,0,0});
        queue.add(new int[]{100});
        while(!queue.isEmpty()){
            int[] temp = queue.poll();
            if(temp[0] == 100){
                depth = depth + 1;
                if(queue.peek() == null){
                    break;
                }
                else if (queue.peek()[0] != 100)
                    queue.add(new int[]{100});
            }else{
                String temp_str1 = "" + lock[(temp[0]+1)%10] + lock[temp[1]] + lock[temp[2]] + lock[temp[3]];
                String temp_str2 = "" + lock[(temp[0]+10-1)%10] + lock[temp[1]] + lock[temp[2]] + lock[temp[3]];
                String temp_str3 = "" + lock[temp[0]] + lock[(temp[1]+1)%10] + lock[temp[2]] + lock[temp[3]];
                String temp_str4 = "" + lock[temp[0]] + lock[(temp[1]+10-1)%10] + lock[temp[2]] + lock[temp[3]];
                String temp_str5 = "" + lock[temp[0]] + lock[temp[1]] + lock[(temp[2]+1)%10] + lock[temp[3]];
                String temp_str6 = "" + lock[temp[0]] + lock[temp[1]] + lock[(temp[2]+10-1)%10] + lock[temp[3]];
                String temp_str7 = "" + lock[temp[0]] + lock[temp[1]] + lock[temp[2]] + lock[(temp[3]+1)%10];
                String temp_str8 = "" + lock[temp[0]] + lock[temp[1]] + lock[temp[2]] + lock[(temp[3]+10-1)%10];

                if(temp_str1.equals(target) || temp_str2.equals(target) || temp_str3.equals(target) || temp_str4.equals(target) || temp_str5.equals(target) || temp_str6.equals(target) || temp_str7.equals(target) || temp_str8.equals(target)) {
                    return depth + 1;
                }
                if(!sets.contains(temp_str1)){
                    queue.add(new int[]{(temp[0]+1)%10, temp[1], temp[2], temp[3]});
                    sets.add(temp_str1);
                }if(!sets.contains(temp_str2)){
                    queue.add(new int[]{(temp[0]+10-1)%10, temp[1], temp[2], temp[3]});
                    sets.add(temp_str2);
                }if(!sets.contains(temp_str3)){
                    queue.add(new int[]{temp[0], (temp[1]+1)%10, temp[2], temp[3]});
                    sets.add(temp_str3);
                }if(!sets.contains(temp_str4)){
                    queue.add(new int[]{temp[0], (temp[1]+10-1)%10, temp[2], temp[3]});
                    sets.add(temp_str4);
                }if(!sets.contains(temp_str5)){
                    queue.add(new int[]{temp[0], temp[1], (temp[2]+1)%10, temp[3]});
                    sets.add(temp_str5);
                }if(!sets.contains(temp_str6)){
                    queue.add(new int[]{temp[0], temp[1], (temp[2]+10-1)%10, temp[3]});
                    sets.add(temp_str6);
                }if(!sets.contains(temp_str7)){
                    queue.add(new int[]{temp[0], temp[1], temp[2], (temp[3]+1)%10});
                    sets.add(temp_str7);
                }if(!sets.contains(temp_str8)){
                    queue.add(new int[]{temp[0], temp[1], temp[2], (temp[3]+10-1)%10});
                    sets.add(temp_str8);
                }
            }
        }
        return -1;
    }
}

leetcode 200 岛屿数量

class Solution {
    public int numIslands(char[][] grid) {
        int count = 0;
        int row = grid.length, col = grid[0].length;
        for(int i = 0; i < row; i++){
            for(int j = 0; j < col; j++){
                if(grid[i][j]=='1'){
                    count = count + 1;
                    grid[i][j] = 0;
                    Queue<int[]> queue = new LinkedList<int[]>();
                    queue.add(new int[]{i,j});
                    while(!queue.isEmpty()){
                        int[] temp = queue.poll();
                        if(temp[0]+1<row && grid[temp[0]+1][temp[1]]=='1'){
                            queue.add(new int[]{temp[0]+1,temp[1]});
                            grid[temp[0]+1][temp[1]]='0';
                        }if(temp[1]+1<col && grid[temp[0]][temp[1]+1]=='1'){
                            queue.add(new int[]{temp[0],temp[1]+1});
                            grid[temp[0]][temp[1]+1]='0';
                        }if(temp[1]-1>=0 && grid[temp[0]][temp[1]-1]=='1'){
                            queue.add(new int[]{temp[0],temp[1]-1});
                            grid[temp[0]][temp[1]-1]='0';
                        }if(temp[0]-1>=0 && grid[temp[0]-1][temp[1]]=='1'){
                            queue.add(new int[]{temp[0]-1,temp[1]});
                            grid[temp[0]-1][temp[1]]='0';
                        }
                    }
                }
            }
        }
        return count;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值