《五月集训》(第17天)——广度优先搜索

前言:

五月集训,前面为学习内容,想要一起学习的可以看一看,最后的才是五月集训每天的作业。

一、知识点

广搜的本质就是暴力枚举,对坐标点所有可尝试的方向进行不断尝试,直到到达目的地,一般我们使用队列来实现代码。

二、课堂习题

这里的题均出自《算法零基础100讲》
英雄哥的专栏适合等不及的同学们O(∩_∩)O

三、作业

LCP 44. 开幕式焰火
102. 二叉树的层序遍历
1609. 奇偶树
1263. 推箱子
解题思路:
1.本质上就是遍历二叉树,将出现的值用哈希表标注,然后进行计数,这里用dfs或bfs都是可以的;
2.在bfs模板的基础上,加上每一层需要找的节点数量,以方便进行层序遍历;
3.跟上一题差不多,知识奇数层和偶数层多了两个判定条件;
4.dfs+bfs,没能力说清楚,就暴力吧
代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    int[] hash = new int[1010];
    public int numColor(TreeNode root) {
        int ans = 0;
        Queue<TreeNode> queue = new ArrayDeque<>();
        if(root != null){
            queue.offer(root);
        }
        while(!queue.isEmpty()){
            TreeNode node = queue.poll();
            hash[node.val]++;
            if(node.left !=null){
                queue.offer(node.left);
            }
            if(node.right !=null){
                queue.offer(node.right);
            }
        }   
        for(int i = 0;i < 1010;i++){
            if(hash[i] != 0){
                ans++;
            }
        } 
        return ans;
    }

}
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> ans = new ArrayList<>();
        Queue<TreeNode> queue = new ArrayDeque<>();
        if(root != null){
            queue.offer(root);
        }
        while(!queue.isEmpty()){
            List<Integer> temp = new ArrayList<>();
            int n = queue.size();
            for(int i = 0;i < n;i++){
                TreeNode node = queue.poll();
                temp.add(node.val);
                if(node.left != null){
                    queue.add(node.left);
                }
                if(node.right != null){
                    queue.add(node.right);
                }
            }
            ans.add(new ArrayList(temp));
        }
        return ans;
    }

}

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isEvenOddTree(TreeNode root) {
        boolean level = true;
        Deque<TreeNode> q = new ArrayDeque<>();
        if(root != null){
            q.offer(root);
        }
        while (!q.isEmpty()) {
            int prev = level ? 0 : Integer.MAX_VALUE;
            int n = q.size();
            for (int i = 0; i < n;i++) {
                TreeNode node = q.poll();
                if (level && (prev >= node.val || node.val % 2 == 0)) {
                    return false;
                }
                if (!level && (prev <= node.val || node.val % 2 == 1)) {
                    return false;
                }
                prev = node.val;
                if (node.left != null) {
                    q.offer(node.left);
                }
                if (node.right != null) {
                    q.offer(node.right);
                }
            }
            level = !level;
        }
        return true;
    }
}
class Solution {
    int n;
    int m;
    boolean[][] reachable;
    int[][] vecs = new int[][]{{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

    public int minPushBox(char[][] grid) {
        n = grid.length;
        m = grid[0].length;
        reachable = new boolean[n][m];

        int tx = -1, ty = -1, x = -1, y = -1;

        for (int i = 0; i < n; ++ i) {
            for (int j = 0; j < m; ++ j) {
                if (grid[i][j] == 'B') {
                    tx = i; ty = j;
                }
                if (grid[i][j] == 'S') {
                    x = i; y = j;
                }
            }
        }
        Deque<int[]> dq = new ArrayDeque<>();
        Set<Integer> v = new HashSet<>();
        int cost = 0;
        dq.offer(new int[]{x, y, tx, ty});
        while (!dq.isEmpty()) {
            int ls = dq.size();
            while (ls -- > 0) {
                int[] cur = dq.poll();
                if (grid[cur[2]][cur[3]] == 'T') return cost;
                for (boolean[] arr : reachable) Arrays.fill(arr, false);
                dfs(grid, cur[0], cur[1], cur[2], cur[3]);
                for (int[] vec : vecs) {
                    int px = cur[2] - vec[0], py = cur[3] - vec[1];
                    int nx = cur[2] + vec[0], ny = cur[3] + vec[1];
                    if (px < 0 || py < 0 || px == n || py == m || !reachable[px][py])   continue;
                    if (nx < 0 || ny < 0 || nx == n || ny == m || grid[nx][ny] == '#')  continue;

                    int[] nxt = new int[]{cur[2], cur[3], nx, ny};
                    int val = hash(nxt);
                    if (v.contains(val))    continue;
                    dq.offerLast(nxt);
                    v.add(val);
                }
            }
            ++ cost;
        }
        return -1;
    }

    public void dfs(char[][] grid, int x, int y, int bx, int by) {
        if (x < 0 || y < 0 || x == n || y == m || reachable[x][y])  return;
        if (grid[x][y] == '#' || (x == bx && y == by))  return;
        reachable[x][y] = true;
        for (int[] v : vecs)    dfs(grid, x + v[0], y + v[1], bx, by);
    }

    public int hash(int[] stat) {
        int res = 0;
        for (int i = 0; i < stat.length; ++ i) res = (res << 5) + stat[i];
        return res;
    }
}

四、总结

对于算法的掌握还是不够熟练,需要进行反复训练!
另外,剩下的课堂训练题目留到下个月的集训啦(●ˇ∀ˇ●)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值