Brush Questions Diary 08 "BFS"

concept

Breadth-first search algorithm (also known as breadth-first search) is one of the easiest graph search algorithms, and this algorithm is also the prototype of many important graph algorithms. Both Dijkstra's single-source shortest path algorithm and Prim's minimum spanning tree algorithm use ideas similar to breadth-first search. Its alias is also called BFS, which belongs to a blind search method, the purpose is to systematically expand and check all nodes in the graph to find the result. In other words, it exhaustively searches the entire graph until it finds a result, regardless of where the result might be.

template

// 计算从起点 start 到终点 target 的最近距离
int BFS(Node start, Node target) {
    Queue<Node> q; // 核心数据结构
    Set<Node> visited; // 避免走回头路
    
    q.offer(start); // 将起点加入队列
    visited.add(start);

    while (q not empty) {
        int sz = q.size();
        /* 将当前队列中的所有节点向四周扩散 */
        for (int i = 0; i < sz; i++) {
            Node cur = q.poll();
            /* 划重点:这里判断是否到达终点 */
            if (cur is target)
                return step;
            /* 将 cur 的相邻节点加入队列 */
            for (Node x : cur.adj()) {
                if (x not in visited) {
                    q.offer(x);
                    visited.add(x);
                }
            }
        }
    }
    // 如果走到这里,说明在图中没有找到目标节点
}

Paradigm topic

topic

Leetcode icon-default.png?t=N6B9https://leetcode.cn/problems/open-the-lock/

You have a turntable lock with four circular thumbwheels. Each trackwheel has 10 numbers: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' . Each wheel can be rotated freely: eg turning '9' into '0' and '0' into '9'. Only one digit of one trackwheel can be rotated per rotation.

The initial number of the lock is '0000', a string representing the numbers of the four thumbwheels.

The list deadends contains a set of dead numbers. Once the number of the dial is the same as any element in the list, the lock will be permanently locked and cannot be rotated any more.

The string target represents the number that can be unlocked. You need to give the minimum number of rotations required to unlock it. If it cannot be unlocked anyway, return -1.

Example 1:

Input: deadends = ["0201","0101","0102","1212","2002"], target = "0202" Output: 6 Explanation: The possible sequence of moves is "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "
0202
"
.
Note that the sequence "0000" -> "0001" -> "0002" -> "0102" -> "0202" cannot be unlocked, because the lock will be locked when it is toggled to "0102"
.
Example 2:

Input: deadends = ["8888"], target = "0009"
Output: 1
Explanation: Rotate the last digit once to get "0000" -> "0009".
Example 3:

Input: deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"], target = "8888" Output: -1 Explanation: Unable to rotate to the target number and not
locked
.

 

hint:

1 <= deadends.length <= 500
deadends[i].length == 4
target.length == 4
target is not in deadends
target and deadends[i] are only composed of several digits

problem solving ideas

For each element in the element queue, we need to perform +1 and -1 operations on each bit, so that each newly generated number will be added to the element queue after judging that it has not been added to the queue before. For each number added to the element queue, judge whether it is in the forbidden number queue. If it is, continue the element, and if it is not, judge whether this element is the final result. If it is not the final result, use this element to perform +1 and -1 operations. Note: every time we add an element to the queue, we only need to judge whether the element has been visited at the beginning, and when cur points to the element, then judge whether it is in deads (to avoid timeout caused by repeated judgment))

example code

class Solution {
    public int openLock(String[] deadends, String target) {
        int res=0;//定义计数器
        //定义两个队列
        HashSet<String>visited=new HashSet<>();
        HashSet<String>deads=new HashSet<>();
        LinkedList<String>elements=new LinkedList<>();
        //求+1和-1
        //加入队列
        for(String s:deadends){
            deads.add(s);
        }
        if(deads.contains("0000")){
            return -1;
        }
        elements.offer("0000");
        visited.add("00000");
        while(elements.size()!=0){
            int n=elements.size();
        for(int i=0;i<n;++i){
            String cur=elements.remove();
            if(cur.equals(target)){
                return res;
            }
            //加入观察过的队列
            visited.add(cur);
          for(int j=0;j<4;++j){
                String sub=oneSub(cur,j);
            String plus=onePlus(cur,j);
             if(!visited.contains(sub)&&!deads.contains(sub)){
                 //添加元素
                 elements.offer(sub);
             }
              if(!visited.contains(plus)&&!deads.contains(plus)){
                 //添加元素
                 elements.offer(plus);
             }
          } 
        }
        res++;
        }
        return -1;          
    }
    public String onePlus(String cur,int j){
        char []chars=cur.toCharArray();
        char ch=chars[j];
        if(ch=='9'){
            chars[j]='0';
        }else{
            chars[j]+=1;
        } 
        return new String(chars);  
    }
    public String oneSub(String cur,int j){
        char []chars=cur.toCharArray();
        char ch=chars[j];
        if(ch=='0'){
            chars[j]='9';
        }else{
            chars[j]-=1;
        } 
        return new String(chars);   
    }

}

topic

Leetcode icon-default.png?t=N6B9https://leetcode.cn/problems/minimum-depth-of-binary-tree/

Given a binary tree, find its minimum depth.

The minimum depth is the number of nodes on the shortest path from the root node to the nearest leaf node.

Note: A leaf node refers to a node that has no child nodes.

Example 1:


Input: root = [3,9,20,null,null,15,7]
Output: 2
Example 2:

Input: root = [2,null,3,null,4,null,5,null,6]
Output: 5

 

hint:

The range of the number of nodes in the tree is [0, 105]
- 1000 <= Node.val <= 1000
Passes 574,422 Commits 1,099,570

problem solving ideas

Use the queue to store the elements accessed in the tree, and continuously call the elements in the column until the left and right subtrees of an element are all empty (use a counter to count in the process until the leaf node)

example code

/**
 * 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 {
    //定义计数器
    int count=0;
    //定义数据保存队列
    private LinkedList<TreeNode>data=new LinkedList<>();
    public int minDepth(TreeNode root) {
        if(root==null){
            return 0;
        }
        //将根结点加入队列
        data.add(root);
        bfs();
        return count;
    }
    public void bfs(){
        //while循环遍历深度,for循环遍历同一层
        while(data.size()!=0){
            count++;
            int n=data.size();
            for(int i=0;i<n;++i){
                TreeNode node=data.remove();
                if(node.left==null&&node.right==null){
                    return;
                }
                
                    if(node.left!=null){
                        data.add(node.left);
                    }
                    if(node.right!=null){
                        data.add(node.right);
                    }
                
            }
        }
    }
}

Guess you like

Origin blog.csdn.net/m0_65431718/article/details/131791958