leetcode 994, 934, 752, 310, 1654 (BFS)

Thoughts on leetcode 994

Loading...

  1. About queue in java:
  •  Deque<int[]> queue = new ArrayDeque();
  •  queue.add(new int[]{i, j});
  • queue.poll();

2. check whether there is a fresh orange left in the while loop (in case there are rotten oranges inserted into the queue but there is no more fresh oranges left)

3. check whether there is a fresh orange left in the end to see whether -1 need to be returned

Pay attention for (while queue.size() != 0 && fresh != 0) 

for example only one rotten but no remaining fresh, so the day is 0

Solution for leetcode 994

class Solution {
    public int orangesRotting(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        int fresh = 0;
        int[][] directions = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        Deque<int[]> queue = new ArrayDeque();
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(grid[i][j] == 2){
                    queue.add(new int[]{i, j});
                }
                else if(grid[i][j] == 1){
                    fresh++;
                }
            }
        }
        int day = 0;
        while(queue.size() != 0 && fresh != 0){
            int size = queue.size();
            day += 1;
            while(size != 0){
                int[] cur = queue.poll();
                size--;
                for(int i = 0; i < directions.length; i++){
                    int curx = cur[0] + directions[i][0];
                    int cury = cur[1] + directions[i][1];
                    if(curx >= 0 && cury >= 0 && curx < m && cury < n && grid[curx][cury] == 1){
                        //don't forget to set this
                        grid[curx][cury] = 2;
                        fresh--;
                        queue.add(new int[]{curx, cury});   
                    }   
                } 
            }
        }
        return fresh > 0 ?  -1 : day; 
    }
}

Thoughts on leetcode 934

Loading...

Use dfs to find the first island and insert every cell of it into a queue. In this way, we can use bfs later to find the shortest distance from a certain cell of the first island to the other island. We should remember both the dfs template and bfs template of this problem. 

Some useful tricks:

  1. when we are inserting the cells into the queue, we already mark it as visited(2) to get rid of duplicate insertions, this also applies to dfs
  2. use flag to not further go through the loop 
  3. when doing dfs, we can add surrounding 0 to the queue so that there is one less layer in bfs

Solution for leetcode 934

class Solution {
    int[][] directions = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    Deque<int[]> queue = new ArrayDeque();
    public int shortestBridge(int[][] grid) {
        boolean flag = false;
        for(int i = 0; i < grid.length && flag == false;i++){
            for(int j = 0; j < grid[0].length; j++){
                if(grid[i][j] == 1){
                    dfs(grid, i, j);
                    flag = true;
                    break;
                }
            }
        }
        int num = 0;
        while(queue.size() != 0){
            int size = queue.size();
            num += 1;
            while(size != 0){
                int[] cur = queue.poll();
                size--;
                int x = cur[0];
                int y = cur[1];
                for(int[] direction: directions){
                    int newx = x + direction[0];
                    int newy = y + direction[1];
                    if(newx >= 0 && newy >= 0 && newx < grid.length && newy < grid[0].length){
                        if(grid[newx][newy] == 1){
                            return num;
                        }
                        if(grid[newx][newy] == 0){
                            queue.add(new int[]{newx, newy});
                            grid[newx][newy] = 2;
                        }
                    }
                }
            }
        }
        return num;
    }
    
    public void dfs(int[][]grid, int i, int j){
        if(i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] == 2){
            return;
        }
        if(grid[i][j] == 0){
            queue.add(new int[]{i, j});
            return;
            
        }
        grid[i][j] = 2;
        for(int[] direction: directions){
            dfs(grid, i + direction[0], j + direction[1]);
        }
    }
}

Thoughts on leetcode 752

Loading...

The only thing that is new is the way to generate the next string from the current string.

Also, we need to insert the deadends into a set so that the route containing the deadends will not be added to the queue.

Solution for leetcode 752

class Solution {
    public int openLock(String[] deadends, String target) {
        HashSet<String> dead = new HashSet<>(Arrays.asList(deadends));
        Set<String> visited = new HashSet<>();
        String start="0000";
        Deque<String> dq = new ArrayDeque();
        dq.add(start);
        visited.add(start);
        if(dead.contains(target) ||dead.contains("0000")){
            return -1;
        }
        int step = 0;
        while(dq.size() != 0){
            int size = dq.size();
            while(size != 0){
                size--;
                String cur = dq.poll();
                if(cur.equals(target)){
                        return step;
                }
                List<String> list = getNexts(cur);
                for(int i = 0; i < list.size(); i++){
                    String potential = list.get(i);
                    if(!dead.contains(potential) && !visited.contains(potential)){
                        dq.add(potential);
                        visited.add(potential); 
                    }
                }
            }
            step++;
        }
        return -1;   
    }
    //for every slot in the current lock, move forward or move back to construct the next step
    //pay attention to the edge case: 0 & 9
     public static List<String> getNexts(String cur){
       List<String> list = new ArrayList<>();
       for(int i = 0; i < 4; i++){
           StringBuilder cursb = new StringBuilder(cur);
           cursb.setCharAt(i, cur.charAt(i) == '0' ? '9' : (char)(cur.charAt(i) - 1));
           list.add(cursb.toString());
           cursb.setCharAt(i, cur.charAt(i) == '9' ? '0' : (char)(cur.charAt(i) + 1));
           list.add(cursb.toString());  
       }
       return list;
    }
}

Thoughts on leetcode 310

Loading...

Any node that has already been a leaf cannot be the root of a MHT, because its adjacent non-leaf node will always be a better candidate. What we basically do is removing the leaves, updating the degrees of inner vertexes, and then remove the new leaves. Doing so level by level until there are 2 or 1 nodes left. What's left is our answer!

Solution for leetcode 310

class Solution {
    public List<Integer> findMinHeightTrees(int n, int[][] edges) {
        int[] degree = new int[n];
        List<Integer> res = new ArrayList<>();
        if (n == 1) {
            res.add(0);
            return res;
        }
        //create a hashmap to store the edge relationship
        HashMap<Integer, List<Integer>> map = new HashMap();
        Deque<Integer> q = new ArrayDeque();
        for(int[] edge : edges){
            for(int i = 0; i < 2; i++){
                int cur = edge[i];
                degree[cur]++;
                List<Integer> list = map.getOrDefault(cur,new ArrayList());
                list.add(edge[1-i]);
                map.put(cur, list);
            }
        }
        //insert the leaf nodes
        for(int i = 0; i < n; i++){
            if(degree[i] == 1){
                q.add(i);
            }
        }
        while(q.size() != 0){
            res = new ArrayList<>();
            int size = q.size();
            while(size != 0){
                size--;
                int cur = q.poll();
                res.add(cur);
                List<Integer> neighbours = map.get(cur);
                for(int nb : neighbours){
                    degree[nb]--;
                    if(degree[nb] == 1){
                        q.add(nb);
                    }
                }
            }
        }
        //res is the last nodes remaining
        return res;   
    }
}

 Thoughts on leetcode 1654

Loading...

We need to keep an extra integer for the element in the queue to check what the previous step is, because we can't go backward twice.

We need to add (pos + a) < 6000 because we can go beyond the end and come back

Check if the position is forbidden(visited)

If a position is reached by the forward movement, we mark it as forbidden(visited) because both pos + a and pos - b will be considered

If a position is reached by the backward movement, we don't mark it as forbidden because pos - b case will not be considered. We can reach this position again by the forward movement and explore the pos - b case.

class Solution {
    public int minimumJumps(int[] forbidden, int a, int b, int x) {
        if(x == 0){
            return 0;
        }
        Set<Integer> forbiddenSet = new HashSet();
        Deque<int[]> queue = new ArrayDeque();
        for(int forbid : forbidden){
            forbiddenSet.add(forbid);
        }
        int output = 0;
        //-1 stands for backward and 1 stands for forward
        queue.add(new int[]{0, -1});
        while(!queue.isEmpty()){
            int size = queue.size();
            output++;
            while(size != 0){
                size--;
                int[] cur = queue.poll();
                int curx = cur[0];
                int curdir = cur[1];
                if(curdir == 1){
                    if(curx - b >= 0 && !forbiddenSet.contains(curx - b)){
                        if(curx - b == x){
                            return output;
                        }
                        queue.add(new int[]{curx - b, -1});
                        //this is unnecessary because we will not backward twice
                        // forbiddenSet.add(curx - b);
                    }
                }
                //cur + a < 6000 is necessary because we can go beyond and come back
                if(!forbiddenSet.contains(curx + a) && curx + a < 6000){
                    if(curx + a == x){
                        return output;
                    }
                    queue.add(new int[]{curx + a, 1});
                    forbiddenSet.add(curx + a);
                }
            }
        }
        return -1;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!对于LeetCode上的问题994.腐烂的橘子,你可以使用Python来解决。下面是一个示例代码: ```python from collections import deque def orangesRotting(grid): # 记录网格的行数和列数 row, col = len(grid), len(grid[0]) # 定义四个方向:上、下、左、右 directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # 使用队列来保存腐烂的橘子的位置 queue = deque() # 记录新鲜橘子的数量 fresh_count = 0 # 遍历整个网格,初始化队列和新鲜橘子的数量 for i in range(row): for j in range(col): if grid[i][j] == 2: # 腐烂的橘子 queue.append((i, j)) elif grid[i][j] == 1: # 新鲜橘子 fresh_count += 1 # 如果新鲜橘子的数量为0,直接返回0 if fresh_count == 0: return 0 # 初始化分钟数 minutes = 0 # 开始进行BFS,直到队列为空 while queue: # 记录当前分钟数下,队列中的元素数量 size = len(queue) # 遍历当前分钟数下的所有腐烂的橘子 for _ in range(size): x, y = queue.popleft() # 遍历四个方向 for dx, dy in directions: nx, ny = x + dx, y + dy # 判断新位置是否在网格内,并且是新鲜橘子 if 0 <= nx < row and 0 <= ny < col and grid[nx][ny] == 1: # 将新鲜橘子变为腐烂状态 grid[nx][ny] = 2 # 将新鲜橘子的位置加入队列 queue.append((nx, ny)) # 新鲜橘子的数量减1 fresh_count -= 1 # 如果当前分钟数下,没有新鲜橘子了,结束循环 if fresh_count == 0: break # 每遍历完一层,分钟数加1 minutes += 1 # 如果最后还有新鲜橘子,返回-1,否则返回分钟数 return -1 if fresh_count > 0 else minutes ``` 你可以将给定的网格作为参数传递给`orangesRotting`函数来测试它。请注意,该代码使用了BFS算法来遍历橘子,并计算腐烂的分钟数。希望能对你有所帮助!如果有任何疑问,请随时问我。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值