美文网首页
宽度优先搜索

宽度优先搜索

作者: 谢谢水果 | 来源:发表于2018-12-26 06:35 被阅读0次

    Java

    Queue<TreeNode> queue = new LinkedList<>();
    String[] vals = String.split(" ");
    int result = Integer.parseInt(String);
    Collections.reverse(List);
    new int[]{1,0};
    
    1. BFS应用场景
      图的遍历 Traversal in Graph
    • 层级遍历 Level Order Traversal
    • 由点及面 Connected Component
    • 拓扑排序 Topological Sorting

    最短路径 Shortest Path in Simple Graph

    • 仅限简单图求最短路径
    • 即,图中每条边长度都是1,或者边长都相等

    非递归的方式找所有方案 Iteration solution for all possible results
    • 这一点我们将在后面 DFS 的课上提到

    1. 复杂度
      二叉树 时间O(V) 空间:同层节点个数最大值
      图 时间O(V+E) 空间:最大深度
      优化方案 双向BFS Bidirectional BFS
    • 假设单向BFS需要搜索 N 层才能到达终点,每层的判断量为 X,那么总的运算量为 X ^ N 如果换成是双向BFS,前后各自需要搜索 N / 2 层,总运算量为 2 * X ^ (N / 2)
    • 无向图; 所有边的长度都为 1 或者长度都一样; 同时给出了起点和终点
    1. 二叉树上的BFS
      102 Binary Tree Level Order Traversal
      297 Serialize and Deserialize Binary Tree
    • 访问到节点的时候 在结果字符串上添加当前节点信息
    • serialize时候空节点也入队 否则无法表示空节点
    1. 图上的BFS
      注意节点不要重复入队就好
      133 Clone Graph
      *127 Word Ladder
      *261 Graph Valid Tree
      lt431 Connected Component in Undirected Graph
    1. 矩阵上的BFS
      200 Number of Islands 四个
      lt611 Knight Shortest Path 八个
      *lt598 Zombie in Matrix
      lt573 Build Post Office II

    2. 拓扑排序
      算法描述:
      统计每个点的入度
      将每个入度为 0 的点放入队列(Queue)中作为起始节点
      不断从队列中拿出一个点,去掉这个点的所有连边(指向其他点的边),其他点的相应的入度 - 1
      一旦发现新的入度为 0 的点,丢回队列中

    求任意一个拓扑排序
    lt127 Topological Sorting
    210 Course Schedule II
    *269 Alien Dictionary 注意可能会有重复的字符对 这种情况下入度不更新
    求是否存在拓扑排序
    207 Course Schedule
    求是否存在且仅存在一个拓扑序 Queue中最多同时只有1个节点
    *444 Sequence Reconstruction
    注意 重复对不能重复统计入度
    求所有的拓扑序 DFS

    102 Binary Tree Level Order Traversal

    /**
     * Definition of TreeNode:
     * public class TreeNode {
     *     public int val;
     *     public TreeNode left, right;
     *     public TreeNode(int val) {
     *         this.val = val;
     *         this.left = this.right = null;
     *     }
     * }
     */
    
    public class Solution {
        /**
         * @param root: A Tree
         * @return: Level order a list of lists of integer
         */
        public List<List<Integer>> levelOrder(TreeNode root) {
            // write your code here
            List<List<Integer>> results = new ArrayList<>();
            if(root==null)
                return results;
            Queue<TreeNode> queue = new LinkedList<>();
            queue.offer(root);
            while(!queue.isEmpty()){
                int size = queue.size();
                List<Integer> list = new ArrayList<>();
                for(int i=0; i<size; i++){
                    TreeNode node = queue.poll();
                    if(node.left!=null)
                        queue.offer(node.left);
                    if(node.right!=null)
                        queue.offer(node.right);
                    list.add(node.val);
                }
                results.add(list);
            }
            return results;
        }
    }
    

    297 Serialize and Deserialize Binary Tree

    /**
     * Definition of TreeNode:
     * public class TreeNode {
     *     public int val;
     *     public TreeNode left, right;
     *     public TreeNode(int val) {
     *         this.val = val;
     *         this.left = this.right = null;
     *     }
     * }
     */
    
    
    public class Solution {
        /**
         * This method will be invoked first, you should design your own algorithm 
         * to serialize a binary tree which denote by a root node to a string which
         * can be easily deserialized by your own "deserialize" method later.
         */
        public String serialize(TreeNode root) {
            // write your code here
            StringBuilder sb = new StringBuilder();
            if(root==null){
                return sb.toString();
            }
            Queue<TreeNode> queue = new LinkedList<>();
            queue.offer(root);
            while(!queue.isEmpty()){
                TreeNode node = queue.poll();
                if(node==null){
                    sb.append("# ");
                    continue;
                }
                sb.append(node.val);
                sb.append(" ");
                queue.offer(node.left);
                queue.offer(node.right);
            }
            return sb.toString();
        }
    
        /**
         * This method will be invoked second, the argument data is what exactly
         * you serialized at method "serialize", that means the data is not given by
         * system, it's given by your own serialize method. So the format of data is
         * designed by yourself, and deserialize it here as you serialize it in 
         * "serialize" method.
         */
        public TreeNode deserialize(String data) {
            // write your code here
            if(data==null || data.length()==0)
                return null;
            String[] vals = data.split(" ");
            TreeNode root = new TreeNode(Integer.parseInt(vals[0]));
            Queue<TreeNode> queue = new LinkedList<>();
            queue.offer(root);
            int index = 1;
            while(!queue.isEmpty()){
                TreeNode node = queue.poll();
                if(vals[index].equals("#")){
                    node.left = null;
                }else{
                    node.left = new TreeNode(Integer.parseInt(vals[index]));
                    queue.offer(node.left);
                }
                index++;
                if(vals[index].equals("#")){
                    node.right = null;
                }else{
                    node.right = new TreeNode(Integer.parseInt(vals[index]));
                    queue.offer(node.right);
                }
                index++;
            }
            return root;
        }
    }
    

    133 Clone Graph

    /**
     * Definition for undirected graph.
     * class UndirectedGraphNode {
     *     int label;
     *     ArrayList<UndirectedGraphNode> neighbors;
     *     UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
     * };
     */
    
    
    public class Solution {
        /*
         * @param node: A undirected graph node
         * @return: A undirected graph node
         */
        public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
            // write your code here
            if(node==null)
                return null;
            UndirectedGraphNode newroot = new UndirectedGraphNode(node.label);
            Map<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<>();
            map.put(node, newroot);
            Queue<UndirectedGraphNode> queue = new LinkedList<>();
            queue.offer(node);
            while(!queue.isEmpty()){
                UndirectedGraphNode current = queue.poll();
                for(UndirectedGraphNode neighbor: current.neighbors){
                    UndirectedGraphNode newNeighbor;
                    if(!map.containsKey(neighbor)){
                        newNeighbor = new UndirectedGraphNode(neighbor.label);
                        map.put(neighbor, newNeighbor);
                        queue.offer(neighbor);
                    }
                    newNeighbor = map.get(neighbor);
                    UndirectedGraphNode newCurrent = map.get(current);
                    newCurrent.neighbors.add(newNeighbor);
                }
            }
            return newroot;
        }
    }
    

    127 Word Ladder

    class Solution {
        public int ladderLength(String beginWord, String endWord, List<String> wordList) {
            Set<String> set = new HashSet<>();
            for(String str : wordList){
                set.add(str);
            }
            int result = 2;
            if(!set.contains(endWord))
                return 0;
            if(beginWord.equals(endWord))
                return 1;
            Queue<String> queue = new LinkedList<>();
            Set<String> visited = new HashSet<>();
            visited.add(beginWord);
            queue.offer(beginWord);
            while(!queue.isEmpty()){
                
                int size = queue.size();
                for(int i=0; i<size; i++){
                    String current = queue.poll();
                    for(String next : getNextWords(set, current, visited)){
                        if(endWord.equals(next))
                            return result;
                        queue.offer(next);
                    }
                } 
               result++; 
            }
            return 0;
        }
        private List<String> getNextWords(Set<String> set, String str, Set<String> visited){
            List<String> result = new ArrayList<>();
            char[] chars = str.toCharArray();
            for(int i=0; i<chars.length; i++){
                for(char c='a'; c<'z'; c++){
                    char charati = chars[i];
                    if(c==chars[i])
                        continue;
                    chars[i] = c;
                    String temp = new String(chars);
                    if(set.contains(temp) && !visited.contains(temp)){
                        result.add(temp);
                        visited.add(temp);
                    }     
                    chars[i] = charati;
                }
            }
            return result;
        }
    }
    

    261 Graph Valid Tree

    class Solution {
        public boolean validTree(int n, int[][] edges) {
            return bfs(n, edges);
        }
        private boolean bfs(int n, int[][] edges){
            if(edges.length!=n-1)
                return false;
            Map<Integer, Set<Integer>> graph = new HashMap<>();
            for(int[] edge : edges){
                int n0 = edge[0];
                int n1 = edge[1];
                Set<Integer> set0 = graph.getOrDefault(n0, new HashSet<>());
                Set<Integer> set1 = graph.getOrDefault(n1, new HashSet<>());
                set0.add(n1);
                set1.add(n0);
                graph.put(n0, set0);
                graph.put(n1, set1);
            }
            Queue<Integer> queue = new LinkedList<>();
            Set<Integer> visited = new HashSet<>();
            queue.offer(0);
            visited.add(0);
            int count = 0;
            while(!queue.isEmpty()){
                int current = queue.poll();
                count++;
                for(Integer next : graph.getOrDefault(current, new HashSet<>())){
                    if(visited.contains(next))
                        return false;
                    visited.add(next);
                    Set<Integer> set = graph.get(next);
                    set.remove(current);
                    graph.put(next, set);
                    queue.offer(next);
                }
            }
            System.out.println(count);
            return count == n;
        }
    }
    

    lt431 Connected Component in Undirected Graph

    /**
     * Definition for Undirected graph.
     * class UndirectedGraphNode {
     *     int label;
     *     ArrayList<UndirectedGraphNode> neighbors;
     *     UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
     * };
     */
    
    
    public class Solution {
        /*
         * @param nodes: a array of Undirected graph node
         * @return: a connected set of a Undirected graph
         */
        public List<List<Integer>> connectedSet(List<UndirectedGraphNode> nodes) {
            // write your code here
            if(nodes==null)
                return null;
            Set<UndirectedGraphNode> set = new HashSet<>();
            List<List<Integer>> result = new ArrayList<>();
            for(UndirectedGraphNode node: nodes){
                if(!set.contains(node)){
                    set.add(node);
                    List<Integer> temp = getBFS(nodes, node, set);
                    result.add(temp);
                }
            }
            return result;
        }
        private List<Integer> getBFS(List<UndirectedGraphNode> nodes, UndirectedGraphNode node, Set<UndirectedGraphNode> set){
            List<Integer> result = new ArrayList<>();
            Queue<UndirectedGraphNode> queue = new LinkedList<>();
            queue.offer(node);
            while(!queue.isEmpty()){
                UndirectedGraphNode temp = queue.poll();
                result.add(temp.label);
                for(UndirectedGraphNode neighbor: temp.neighbors){
                    if(!set.contains(neighbor)){
                        queue.offer(neighbor);
                        set.add(neighbor);
                    }
                }
            }
            Collections.sort(result);
            return result;
        }
    }
    

    200 Number of Islands

    class Solution {
        public int numIslands(char[][] grid) {
            if(grid==null || grid.length==0 || grid[0]==null || grid[0].length==0)
                return 0;
            int result = 0;
            boolean[][] visited = new boolean[grid.length][grid[0].length];
            for(int i=0; i<grid.length; i++){
                for(int j=0; j<grid[0].length; j++){
                    if(grid[i][j]=='1'){
                        result++;
                        grid[i][j] = '0';
                        visited[i][j] = true;
                        bfs(grid, i, j, visited);
                    }
                }
            }
            return result;
        }
        private void bfs(char[][] grid, int i, int j, boolean[][] visited){
            int[] dirx = {1, -1, 0, 0};
            int[] diry = {0, 0, 1, -1};
            Queue<int[]> queue = new LinkedList<>();
            queue.offer(new int[]{i, j});
            while(!queue.isEmpty()){
                int[] current = queue.poll();
                for(int k=0; k<4; k++){
                    int x = current[0]+dirx[k];
                    int y = current[1]+diry[k];
                    if(isValid(visited, x, y, grid)){
                        queue.offer(new int[]{x, y});
                        grid[x][y] = '0';
                        visited[x][y] = true;
                    }
                }
            }
        }
        private boolean isValid(boolean[][] visited, int x, int y, char[][] grid){
            return x>=0 && x<grid.length && y>=0 && y<grid[0].length && visited[x][y]==false && grid[x][y]=='1';
        }
    }
    

    lt611 Knight Shortest Path

    /**
     * Definition for a point.
     * class Point {
     *     int x;
     *     int y;
     *     Point() { x = 0; y = 0; }
     *     Point(int a, int b) { x = a; y = b; }
     * }
     */
    
    public class Solution {
        /**
         * @param grid: a chessboard included 0 (false) and 1 (true)
         * @param source: a point
         * @param destination: a point
         * @return: the shortest path 
         */
        public int shortestPath(boolean[][] grid, Point source, Point destination) {
            // write your code here
            if(grid==null || grid.length==0 || grid[0]==null || grid[0].length==0)
                return 0;
            if(source.x==destination.x && source.y==destination.y)
                return 0;
            Queue<int[]> queue = new LinkedList<>();
            queue.offer(new int[]{source.x, source.y});
            int[] dirx = {1, -1, 2, 2, 1, -1, -2, -2};
            int[] diry = {2, 2, 1, -1, -2, -2, 1, -1};
            boolean[][] visited = new boolean[grid.length][grid[0].length];
            visited[source.x][source.y] = true;
            int result = 0;
            while(!queue.isEmpty()){
                result++;
                int size = queue.size();
                System.out.println(size);
                for(int i=0; i<size; i++){
                    int[] current = queue.poll();
                    int x = current[0];
                    int y = current[1];
                    System.out.println(x+" "+y);
                    for(int j=0; j<8; j++){
                        int newx = x+dirx[j];
                        int newy = y+diry[j];
                        if(isValid(newx, newy, grid, visited)){
                            if(newx==destination.x && newy==destination.y)
                                return result;
                            queue.offer(new int[]{newx, newy});
                            visited[newx][newy] = true;
                        }
                    }
                }
            }
            return -1;
        }
        
        private boolean isValid(int x, int y, boolean[][] grid, boolean[][] visited){
            return x>=0 && x<grid.length && y>=0 && y<grid[0].length && grid[x][y]==false && visited[x][y]==false;
        }
    }
    

    598 Zombie in Matrix

    public class Solution {
       /**
        * @param grid: a 2D integer grid
        * @return: an integer
        */
       public int zombie(int[][] grid) {
           // write your code here
           Queue<int[]> queue = new LinkedList<>();
           for(int i=0; i<grid.length; i++){
               for(int j=0; j<grid[0].length; j++){
                   if(grid[i][j]==1)
                       queue.offer(new int[]{i,j});
               }
           }
           int days = 0;
           int[] dirx = {1, -1, 0, 0};
           int[] diry = {0, 0, 1, -1};
           while(!queue.isEmpty()){
               int size = queue.size();
               days++;
               for(int i=0; i<size; i++){
                   int[] current = queue.poll();
                   int x = current[0];
                   int y = current[1];
                   for(int k=0; k<4; k++){
                       int newx = x+dirx[k];
                       int newy = y+diry[k];
                       if(isValid(grid, newx, newy)){
                           grid[newx][newy] = 1;
                           queue.offer(new int[]{newx, newy});
                       }
                   }
               }
           }
           for(int i=0; i<grid.length; i++){
               for(int j=0; j<grid[0].length; j++){
                   if(grid[i][j]==0)
                       return -1;
               }
           }
           return days-1;
       }
       private boolean isValid(int[][] grid, int x, int y){
           return x>=0 && x<grid.length && y>=0 && y<grid[0].length && grid[x][y]==0;
       }
    }
    

    127 Topological Sorting

    /**
     * Definition for Directed graph.
     * class DirectedGraphNode {
     *     int label;
     *     ArrayList<DirectedGraphNode> neighbors;
     *     DirectedGraphNode(int x) { label = x; neighbors = new ArrayList<DirectedGraphNode>(); }
     * };
     */
    
    public class Solution {
        /*
         * @param graph: A list of Directed graph node
         * @return: Any topological order for the given graph.
         */
        public ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
            // write your code here
            Map<DirectedGraphNode, Integer> map = new HashMap<>();
            for(DirectedGraphNode node : graph){
                for(DirectedGraphNode neighbor : node.neighbors){
                    map.put(neighbor, map.getOrDefault(neighbor, 0)+1);
                }
            }
            Queue<DirectedGraphNode> queue = new LinkedList<>();
            for(DirectedGraphNode node : graph){
                if(!map.containsKey(node)){
                    queue.offer(node);
                }
            }
            ArrayList<DirectedGraphNode> result = new ArrayList<>();
            while(!queue.isEmpty()){
                DirectedGraphNode node = queue.poll();
                result.add(node);
                for(DirectedGraphNode neighbor : node.neighbors){
                    map.put(neighbor, map.get(neighbor)-1);
                    if(map.get(neighbor)==0)
                        queue.offer(neighbor);
                }
            }
            return result;
        }
    }
    

    210 Course Schedule II

    class Solution {
        public int[] findOrder(int numCourses, int[][] prerequisites) {
            Map<Integer, Integer> map = new HashMap<>();
            Map<Integer, List<Integer>> graph = new HashMap<>();
            for(int[] prerequest : prerequisites){
                int in = prerequest[0];
                int out = prerequest[1];
                map.put(in, map.getOrDefault(in,0)+1);
                List<Integer> neighbors = graph.getOrDefault(out, new ArrayList<>());
                neighbors.add(in);
                graph.put(out, neighbors);
            }
            Queue<Integer> queue = new LinkedList<>();
            for(int i=0; i<numCourses; i++){
                if(!map.containsKey(i)){
                    queue.offer(i);
                }
            }
            int count = 0;
            int[] result = new int[numCourses];
            while(!queue.isEmpty()){
                int out = queue.poll();
                result[count] = out;
                count++;
                for(Integer in : graph.getOrDefault(out, new ArrayList<>())){
                    map.put(in, map.get(in)-1);
                    if(map.get(in)==0)
                        queue.offer(in);
                }
            }
            if(count==numCourses)
                return result;
            return new int[0];
        }
    }
    

    269 Alien Dictionary

    class Solution {
        public String alienOrder(String[] words) {
            Map<Character, Set<Character>> graph = new HashMap<>();
            Map<Character, Integer> indegree = new HashMap<>();
            Set<Character> alphabet = new HashSet<>();
            for(String word : words){
                for(int i=0; i<word.length(); i++){
                    alphabet.add(word.charAt(i));
                }
            }
            for(int i=1; i<words.length; i++){
                String pre = words[i-1];
                String next = words[i];
                int j=0;
                while(j<pre.length() && j<next.length() ){
                    if(pre.charAt(j)==next.charAt(j)){
                        j++;
                    }else{
                        Set<Character> set = graph.getOrDefault(pre.charAt(j), new HashSet<>());
                        if(set.add(next.charAt(j))){
                            graph.put(pre.charAt(j), set);
                            indegree.put(next.charAt(j), indegree.getOrDefault(next.charAt(j), 0)+1);
                        }
                        break;
                    }
                }
            }
            StringBuilder sb = new StringBuilder();
            Queue<Character> queue = new LinkedList<>();
            for(Character c : alphabet){
                if(!indegree.containsKey(c)){
                    queue.offer(c);
                }
            }
            while(!queue.isEmpty()){
                Character c = queue.poll();
                sb.append(c);
                for(Character next : graph.getOrDefault(c, new HashSet<>())){
                    indegree.put(next, indegree.get(next)-1);
                    if(indegree.get(next)==0)
                        queue.offer(next);
                }
            }
            if(sb.length()==alphabet.size()){
                return sb.toString();
            }
            return "";
        }
    }
    

    207 Course Schedule

    class Solution {
        public boolean canFinish(int numCourses, int[][] prerequisites) {
            Map<Integer, Integer> map = new HashMap<>();
            Map<Integer, List<Integer>> graph = new HashMap<>();
            for(int[] prerequest : prerequisites){
                int in = prerequest[0];
                int out = prerequest[1];
                map.put(in, map.getOrDefault(in,0)+1);
                List<Integer> neighbors = graph.getOrDefault(out, new ArrayList<>());
                neighbors.add(in);
                graph.put(out, neighbors);
            }
            Queue<Integer> queue = new LinkedList<>();
            for(int i=0; i<numCourses; i++){
                if(!map.containsKey(i)){
                    queue.offer(i);
                }
            }
            int count = 0;
            while(!queue.isEmpty()){
                int out = queue.poll();
                count++;
                for(Integer in : graph.getOrDefault(out, new ArrayList<>())){
                    map.put(in, map.get(in)-1);
                    if(map.get(in)==0)
                        queue.offer(in);
                }
            }
            return count==numCourses;
        }
    }
    

    444 Sequence Reconstruction

    class Solution {
        public boolean sequenceReconstruction(int[] org, List<List<Integer>> seqs) {
            // write your code here
            Map<Integer, Integer> indegree = new HashMap<>();
            Map<Integer, Set<Integer>> graph = new HashMap<>();
            
            int index = 0;
            for(List<Integer> seq : seqs){
                for(int i=1; i<seq.size(); i++){
                    int in = seq.get(i);
                    int out = seq.get(i-1);
                    if(in>org.length || out>org.length)
                        return false;
                    if(!graph.containsKey(in)){
                        graph.put(in, new HashSet<>());
                    }
                    Set<Integer> set = graph.getOrDefault(out, new HashSet<>());
                    if(set.add(in)){
                        graph.put(out, set);
                        indegree.put(in, indegree.getOrDefault(in, 0)+1);
                    }
                    
                }
            }
            System.out.println(indegree.size());
            System.out.println(graph.size());
            Queue<Integer> queue = new LinkedList<>();
            if(indegree.containsKey(org[0]))
                return false;
            queue.offer(org[0]);
            while(!queue.isEmpty()){
                Integer current = queue.poll();
                if(org[index]!=current)
                    return false;
                index++;
                for(Integer next : graph.getOrDefault(current, new HashSet<>())){
                    indegree.put(next, indegree.get(next)-1);
                    if(indegree.get(next)==0)
                        queue.offer(next);
                }
                if(queue.size()>1)
                    return false;
            }
            return index==org.length;
        }
    }
    

    相关文章

      网友评论

          本文标题:宽度优先搜索

          本文链接:https://www.haomeiwen.com/subject/vcdecqtx.html