宽度优先搜索(BFS)— 20180909 - 20180917

BFS几类题:

1.图的遍历:a.层级遍历 b.由点及面 c.拓扑排序

2.简单图最短路径:

简单图:1.无向图 2.边权重一致

图的时间复杂度:

N个点,M条边,M最大是N^2,时间复杂度O(N+M),最坏是O(N^2);

矩阵是一种特殊图,R行C列矩阵,有R*C个点,R*C*2条边,所以是O(R*C);

69. Binary Tree Level Order Traversal

 1     public List<List<Integer>> levelOrder(TreeNode root) {
 2         // write your code here
 3         if(root == null){
 4             return new ArrayList();
 5         }
 6         List<List<Integer>> result = new ArrayList();
 7         Queue<TreeNode> queue = new LinkedList<TreeNode>();
 8         queue.offer(root);
 9         
10         while(!queue.isEmpty()){
11             List<Integer> level = new ArrayList<>();
12             int size = queue.size();
13             for(int i=0;i<size;i++){
14                 TreeNode head = queue.poll();
15                 level.add(head.val);
16                 if(head.left != null){
17                     queue.offer(head.left);
18                 }
19                 
20                 if(head.right != null){
21                     queue.offer(head.right);
22                 }
23             }
24             result.add(level);
25         }
26         
27         return result;
28     }
View Code

70. Binary Tree Level Order Traversal II

 1     public List<List<Integer>> levelOrderBottom(TreeNode root) {
 2         // write your code here
 3         List<List<Integer>> result = new ArrayList();
 4         if(root == null){
 5             return result;
 6         }
 7         
 8         Queue<TreeNode> queue = new LinkedList<TreeNode>();
 9         queue.offer(root);
10         
11         while(!queue.isEmpty()){
12             List<Integer> level = new ArrayList();
13             int size = queue.size();
14             
15             for(int i=0; i<size; i++){
16                 TreeNode head = queue.poll();
17                 level.add(head.val);
18                 
19                 if(head.left != null){
20                     queue.offer(head.left);
21                 }
22                 
23                 if(head.right != null){
24                     queue.offer(head.right);
25                 }
26             }
27             
28             result.add(level);
29         }
30         
31         Collections.reverse(result);
32         return result;
33     }
View Code

71. Binary Tree Zigzag Level Order Traversal

 1     public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
 2         // write your code here
 3                 List<List<Integer>> result = new ArrayList();
 4         if(root == null){
 5             return result;
 6         }
 7         
 8         Queue<TreeNode> queue = new LinkedList<TreeNode>();
 9         queue.offer(root);
10         int count = 0;
11         while(!queue.isEmpty()){
12             List<Integer> level = new ArrayList();
13             int size = queue.size();
14             
15             for(int i=0; i<size; i++){
16                 TreeNode head = queue.poll();
17                 level.add(head.val);
18                 
19                 if(head.left != null){
20                     queue.offer(head.left);
21                 }
22                 
23                 if(head.right != null){
24                     queue.offer(head.right);
25                 }
26             }
27             
28             if(count%2 == 1){
29                 Collections.reverse(level);
30             }
31             result.add(level);
32             count++;
33         }
34         
35         return result;
36     }
View Code

7. Serialize and Deserialize Binary Tree(未AC)

 178. Graph Valid Tree

valid tree条件:1.n个点n-1条边,2.n个点连通

此题重点在于如何通过给定的点和边建立邻接图Map

 1     public boolean validTree(int n, int[][] edges) {
 2         // write your code here
 3         if(n == 0){
 4             return false;
 5         }
 6         
 7         if(edges.length != n-1){
 8             return false;
 9         }
10         
11         Map<Integer,Set<Integer>> neighbourMap = getNeighbourHoods(n,edges);
12         
13         Queue<Integer> queue = new LinkedList<Integer>();
14         Set<Integer> findedNodes = new HashSet<Integer>();
15         queue.offer(0);
16         findedNodes.add(0);
17         while(!queue.isEmpty()){
18             int node = queue.poll();
19             Set<Integer> neighbours = neighbourMap.get(node);
20             for(Integer neighbour:neighbours){
21                 if(!findedNodes.contains(neighbour)){
22                     findedNodes.add(neighbour);
23                     queue.offer(neighbour);
24                 }
25             }
26         }
27         
28         return (findedNodes.size()==n);
29         
30     }
31     
32     Map<Integer,Set<Integer>> getNeighbourHoods(int n, int[][] edges){
33         Map<Integer, Set<Integer>> map = new HashMap<>();
34         for(int i=0; i<n; i++){
35             map.put(i,new HashSet<Integer>());
36         }
37         
38         for(int i=0; i<edges.length; i++){
39             int u = edges[i][0];
40             int v = edges[i][1];
41             map.get(u).add(v);
42             map.get(v).add(u);
43         }
44         
45         return map;
46     }
View Code

137. Clone Graph

由点及面问题:在队列初始化时,需要对记录访问点的set也初始化,非常容易因为忽略而不能AC

queue.offer(node);
nodeSet.add(node);

 1     public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
 2         // write your code here
 3         if(node == null){
 4             return null;
 5         }
 6         
 7         
 8         //get All nodes
 9         List<UndirectedGraphNode> allNodes = new ArrayList<>();
10         Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();
11         Set<UndirectedGraphNode> nodeSet = new HashSet<UndirectedGraphNode>();
12         queue.offer(node);
13         nodeSet.add(node);
14         while(!queue.isEmpty()){
15             UndirectedGraphNode n = queue.poll();
16             for(UndirectedGraphNode neighbor:n.neighbors){
17                 if(!nodeSet.contains(neighbor)){
18                     queue.offer(neighbor);
19                     nodeSet.add(neighbor);
20                 }
21             }
22         }
23         
24         allNodes = new ArrayList<UndirectedGraphNode>(nodeSet);
25         
26         //copy nodes and mark the new/old nodes' corresponding
27         Map<UndirectedGraphNode,UndirectedGraphNode> oldNewMap = new HashMap<>();
28         for(UndirectedGraphNode n:allNodes){
29             oldNewMap.put(n,new UndirectedGraphNode(n.label));
30         }
31         
32         //copy neighbors
33         for(UndirectedGraphNode n:allNodes){
34             UndirectedGraphNode newNode = oldNewMap.get(n);
35             for(UndirectedGraphNode neighbor:n.neighbors){
36                 newNode.neighbors.add(oldNewMap.get(neighbor));
37             }
38         }
39         
40         return oldNewMap.get(node);
41     }
View Code

618. Search Graph Nodes

 1     public UndirectedGraphNode searchNode(ArrayList<UndirectedGraphNode> graph,
 2                                           Map<UndirectedGraphNode, Integer> values,
 3                                           UndirectedGraphNode node,
 4                                           int target) {
 5         // write your code here
 6         if(node == null){
 7             return null;
 8         }
 9         
10         Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();
11         Set<UndirectedGraphNode> set = new HashSet<>();
12         
13         queue.offer(node);
14         set.add(node);
15         
16         while(!queue.isEmpty()){
17             UndirectedGraphNode head = queue.poll();
18             if(values.get(head) == target){
19                 return head;
20             }
21             
22             for(UndirectedGraphNode n: head.neighbors){
23                 if(!set.contains(n)){
24                     if(values.get(n) == target){
25                         return n;
26                     }
27                     queue.offer(n);
28                     set.add(n);
29                 }
30             }
31         }
32         
33         return null;
34     }
View Code

127. Topological Sorting

拓扑排序基础题,一定要掌握思路

 1     public ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
 2         // write your code here
 3         ArrayList<DirectedGraphNode> result = new ArrayList<>();
 4         if(graph == null || graph.size()==0){
 5             return result;
 6         }
 7         
 8         Map<DirectedGraphNode,Integer> map = new HashMap<>();
 9         //统计入度
10         for(DirectedGraphNode node: graph){
11             for(DirectedGraphNode n: node.neighbors){
12                 Integer exist = map.get(n);
13                 if(exist == null){
14                     map.put(n,1);
15                 }else{
16                     map.put(n,exist+1);
17                 }
18             }
19         }
20         
21         //取出入度为0的点初始化队列和拓扑结果
22         Queue<DirectedGraphNode> queue = new LinkedList<>();
23         for(DirectedGraphNode node : graph){
24             if(!map.containsKey(node)){
25                 queue.offer(node);
26                 result.add(node);
27             }
28         }
29         
30         //BFS 更新入度,按入度为0的顺序进行拓扑排序
31         while(!queue.isEmpty()){
32             DirectedGraphNode head = queue.poll();
33             for(DirectedGraphNode neighbor: head.neighbors){
34                 map.put(neighbor,map.get(neighbor)-1);
35                 if(map.get(neighbor) == 0){
36                     queue.offer(neighbor);
37                     result.add(neighbor);
38                 }
39             }
40         }
41         
42         return result;
43     }
View Code

615. Course Schedule

这题其实不用开Hash去存,由于给定的条件特殊,其实可以通过同长度数组对应位置去存储(可参考标准答案)

 1     public boolean canFinish(int numCourses, int[][] prerequisites) {
 2         // write your code here
 3         
 4         //构建邻接Map,加统计入度
 5         Map<Integer,ArrayList<Integer>> map = new HashMap<>();
 6         Map<Integer,Integer> degreeMap = new HashMap();
 7         
 8         for(int i=0; i<numCourses; i++){
 9             map.put(i,new ArrayList<Integer>());
10         }
11         
12         //注意审题,这题反了对结果没有影响,但如果需要输出序列则不能AC
13         for(int i=0; i<prerequisites.length; i++){
14             map.get(prerequisites[i][1]).add(prerequisites[i][0]);
15             if(!degreeMap.containsKey(prerequisites[i][0])){
16                 degreeMap.put(prerequisites[i][0],1);
17             }else{
18                 degreeMap.put(prerequisites[i][0],degreeMap.get(prerequisites[i][0])+1);
19             }
20         }
21         
22         
23         //拓扑排序
24         int count =0;
25         Queue<Integer> queue = new LinkedList<>();
26         for(int i=0; i<numCourses; i++){
27             if(!degreeMap.containsKey(i)){
28                 queue.offer(i);
29                 count++;
30             }
31         }
32         
33         while(!queue.isEmpty()){
34             Integer course = queue.poll();
35             for(Integer nextCourse: map.get(course)){
36                 degreeMap.put(nextCourse,degreeMap.get(nextCourse)-1);
37                 if(degreeMap.get(nextCourse)==0){
38                     queue.offer(nextCourse);
39                     count++;
40                 }
41             }
42         }
43         
44         return (count==numCourses);
45     }
View Code

616. Course Schedule II

 1     public int[] findOrder(int numCourses, int[][] prerequisites) {
 2         // write your code here
 3         int[] result = new int[numCourses];
 4         //构建邻接Map,加统计入度
 5         Map<Integer,ArrayList<Integer>> map = new HashMap<>();
 6         Map<Integer,Integer> degreeMap = new HashMap();
 7         
 8         for(int i=0; i<numCourses; i++){
 9             map.put(i,new ArrayList<Integer>());
10         }
11         
12         for(int i=0; i<prerequisites.length; i++){
13             map.get(prerequisites[i][1]).add(prerequisites[i][0]);
14             if(!degreeMap.containsKey(prerequisites[i][0])){
15                 degreeMap.put(prerequisites[i][0],1);
16             }else{
17                 degreeMap.put(prerequisites[i][0],degreeMap.get(prerequisites[i][0])+1);
18             }
19         }
20         
21         
22         //拓扑排序
23         int count = 0;
24         Queue<Integer> queue = new LinkedList<>();
25         for(int i=0; i<numCourses; i++){
26             if(!degreeMap.containsKey(i)){
27                 queue.offer(i);
28                 result[count] = i;
29                 count++;
30             }
31         }
32         
33         while(!queue.isEmpty()){
34             Integer course = queue.poll();
35             for(Integer nextCourse: map.get(course)){
36                 degreeMap.put(nextCourse,degreeMap.get(nextCourse)-1);
37                 if(degreeMap.get(nextCourse)==0){
38                     queue.offer(nextCourse);
39                     result[count] = nextCourse;
40                     count++;
41                 }
42             }
43         }
44         
45         if(count == numCourses){
46             return result;
47         }
48         
49         return new int[0];
50     }
View Code

605. Sequence Reconstruction

这题要注意细节判断,思路简单,但不容易AC

 1     public boolean sequenceReconstruction(int[] org, int[][] seqs) {
 2         // write your code here
 3         //判断seqs是否有超过org范围的数字
 4         //构建入度和邻接表
 5         //BFS,判断是否只能又一个拓扑排序,且数字是否一一对应
 6         
 7         Map<Integer, Integer> degreeMap = new HashMap<>();
 8         Map<Integer, List<Integer>> adjacentMap = new HashMap<>();
 9         
10         int min = Integer.MAX_VALUE;
11         int max = Integer.MIN_VALUE;        
12         for(int num : org){
13         //    adjacentMap.put(num, new ArrayList<>());
14             min = num<min? num:min;
15             max = num>max? num:max;
16         }
17 
18 
19         for(int[] seq: seqs){
20             if(seq.length>0 && (seq[0]>max || seq[0]<min)){
21                 return false;
22             }
23             if(seq.length>0 && !adjacentMap.containsKey(seq[0])){
24                 adjacentMap.put(seq[0],new ArrayList());
25             }
26             for(int i =1; i<seq.length; i++){
27                 if(seq[i]>max || seq[i]<min){
28                     return false;
29                 }
30                 if(degreeMap.containsKey(seq[i])){
31                     degreeMap.put(seq[i],degreeMap.get(seq[i])+1);                 
32                 }else{
33                     degreeMap.put(seq[i],1);
34                 }
35                 if(!adjacentMap.containsKey(seq[i-1])){
36                     adjacentMap.put(seq[i-1],new ArrayList());
37                 }
38                 if(!adjacentMap.containsKey(seq[i])){
39                     adjacentMap.put(seq[i],new ArrayList());
40                 }
41                 adjacentMap.get(seq[i-1]).add(seq[i]);
42             }
43         }
44         
45         
46         Queue<Integer> queue = new LinkedList<>();
47         for(int num: org){
48             if(!adjacentMap.containsKey(num)){
49                 return false;
50             }
51             if(!degreeMap.containsKey(num)){
52                 queue.offer(num);
53             }
54         }
55         
56         int index =0;
57         while(queue.size()==1){
58             Integer head = queue.poll();
59             if(head != org[index]){
60                 return false;
61             }
62             index++;
63             for(int neighbor: adjacentMap.get(head)){
64                 degreeMap.put(neighbor,degreeMap.get(neighbor)-1);
65                 if(degreeMap.get(neighbor)==0){
66                     queue.offer(neighbor);
67                 }
68             }
69         }
70         
71         return (index == org.length);
72     }
View Code

433. Number of Islands

 1 class Coordinate{
 2     int x;
 3     int y;
 4     public Coordinate(int x,int y){
 5         this.x = x;
 6         this.y = y;
 7     }
 8 }
 9 
10 public class Solution {
11     /**
12      * @param grid: a boolean 2D matrix
13      * @return: an integer
14      */
15      
16     int[] directX = {0,1,0,-1};
17     int[] directY = {1,0,-1,0};
18     public int numIslands(boolean[][] grid) {
19         // write your code here
20         if(grid == null ||grid.length==0){
21             return 0;
22         }
23         
24         int r = grid.length;
25         int c = grid[0].length;
26         
27         if(r==0 || c==0){
28             return 0;
29         }
30         
31         int count =0;
32         for(int i =0; i<r; i++){
33             for(int j =0; j<c; j++){
34                 if(grid[i][j]){
35                     BFS(grid,new Coordinate(i,j));
36                     count++;
37                 }
38             }
39         }
40         
41         return count;
42     }
43     
44     public void BFS(boolean[][] grid,Coordinate center){
45         Queue<Coordinate> queue = new LinkedList<>();
46         queue.offer(center);
47         grid[center.x][center.y]=false;
48         
49         while(!queue.isEmpty()){
50             Coordinate head = queue.poll();
51             for(int i =0;i<4; i++){
52                 Coordinate point = new Coordinate(head.x+directX[i],head.y+directY[i]);
53                 if(!isInMatrix(point,grid)){
54                     continue;
55                 }
56                 if(grid[point.x][point.y]){
57                     queue.offer(point);
58                     grid[point.x][point.y] = false;
59                 }
60             }
61         }
62     }
63     
64     public boolean isInMatrix(Coordinate point, boolean[][] grid){
65         int r = grid.length;
66         int c = grid[0].length;
67         return(point.x>=0 && point.x<r && point.y>=0 && point.y<c);
68     }
69     
70 }
View Code

598. Zombie in Matrix

 1 class Coordinate{
 2     int x;
 3     int y;
 4     public Coordinate(int x, int y){
 5         this.x = x;
 6         this.y = y;
 7     }
 8 }
 9 
10 public class Solution {
11     /**
12      * @param grid: a 2D integer grid
13      * @return: an integer
14      */
15      
16     private static final int ZOMBIE = 1;
17     private static final int PEOPLE = 0;
18     private static final int WALL = 2;
19     
20     int[] directX = {0,1,0,-1};
21     int[] directY = {1,0,-1,0};
22     public int zombie(int[][] grid) {
23         // write your code here
24         
25         if(grid == null || grid.length ==0 || grid[0].length ==0){
26             return 0;
27         }
28         
29         int r = grid.length;
30         int c = grid[0].length;
31         Queue<Coordinate> queue = new LinkedList<>();
32         
33         int people = 0;
34         for(int i=0; i<r; i++)
35             for(int j=0; j<c; j++){
36                 if(grid[i][j] == ZOMBIE){
37                     queue.offer(new Coordinate(i,j));
38                 }
39                 if(grid[i][j] == PEOPLE){
40                     people++;
41                 }
42             }
43         
44         if(people == 0){
45             return 0;
46         }
47         //BFS
48         int day = 0;
49         while(!queue.isEmpty()){
50             day++;
51             int size = queue.size();
52             for(int i = 0; i<size; i++){
53                 Coordinate center = queue.poll();
54                 for(int j=0; j<4; j++){
55                     Coordinate next = new Coordinate(center.x+directX[j],center.y+directY[j]);
56                     if(!isInMatrix(next,grid)){
57                         continue;
58                     }
59                     
60                     if(grid[next.x][next.y] == PEOPLE){
61                         grid[next.x][next.y] = ZOMBIE;
62                         queue.offer(next);
63                         people--;
64                         if(people ==0){
65                             return day;
66                         }
67                     }
68                 }
69             }
70         }
71         
72         
73         return -1;
74         
75         
76     }
77     
78     public boolean isInMatrix(Coordinate point, int[][]grid){
79         int r = grid.length;
80         int c = grid[0].length;
81         
82         return(point.x>=0 && point.x<r && point.y>=0 && point.y<c);
83     }
84 }
View Code

611. Knight Shortest Path

 1 /**
 2  * Definition for a point.
 3  * class Point {
 4  *     int x;
 5  *     int y;
 6  *     Point() { x = 0; y = 0; }
 7  *     Point(int a, int b) { x = a; y = b; }
 8  * }
 9  */
10 
11 public class Solution {
12     /**
13      * @param grid: a chessboard included 0 (false) and 1 (true)
14      * @param source: a point
15      * @param destination: a point
16      * @return: the shortest path 
17      */
18      
19     int[] directX = {1,1,-1,-1,2,2,-2,-2};
20     int[] directY = {2,-2,2,-2,1,-1,1,-1};
21     public int shortestPath(boolean[][] grid, Point source, Point destination) {
22         // write your code here
23         if(grid == null || grid.length==0 || grid[0].length==0){
24             return -1;
25         }
26         
27         if(source.x == destination.x && source.y==destination.y){
28             return 0;
29         }
30         
31         Queue<Point> queue = new LinkedList<>();
32         queue.offer(source);
33         
34         int step = 0;
35         while(!queue.isEmpty()){
36             step++;
37             int size = queue.size();
38             for(int i =0; i<size; i++){
39                 Point center = queue.poll();
40                 for(int j=0; j<8; j++){
41                     Point next = new Point(center.x+directX[j],center.y+directY[j]);
42                     if(!isInMatrix(next,grid)){
43                         continue;
44                     }
45                     
46                     if(next.x == destination.x && next.y == destination.y){
47                         return step;
48                     }
49                     
50                     if(!grid[next.x][next.y]){
51                         queue.offer(next);
52                         grid[next.x][next.y] = true;
53                     }
54                 }
55             }
56         }
57         
58         return -1;
59     }
60     
61     public boolean isInMatrix(Point point, boolean[][]grid){
62         int r = grid.length;
63         int c = grid[0].length;
64         
65         return(point.x>=0 && point.x<r && point.y>=0 && point.y<c);
66     }
67 }
View Code

431. Connected Component in Undirected Graph

 1     public List<List<Integer>> connectedSet(List<UndirectedGraphNode> nodes) {
 2         // write your code here
 3         if(nodes == null || nodes.size() ==0){
 4             return new ArrayList<>();
 5         }
 6         
 7         List<List<Integer>> result = new ArrayList<>();
 8         Queue<UndirectedGraphNode> queue = new LinkedList<>();
 9         Set<UndirectedGraphNode> visit = new HashSet<>();
10         
11         
12         for(UndirectedGraphNode node: nodes){
13             if(!visit.contains(node)){
14                 List<Integer> list = new ArrayList<>();
15                 list.add(node.label);
16                 queue.offer(node);
17                 visit.add(node);
18         
19                 while(!queue.isEmpty()){
20                     UndirectedGraphNode head = queue.poll();
21                     for(UndirectedGraphNode neighbor: head.neighbors){
22                         if(!visit.contains(neighbor)){
23                             list.add(neighbor.label);
24                             queue.offer(neighbor);
25                             visit.add(neighbor);
26                         }
27                     }
28                 }
29                 
30                 Collections.sort(list);
31                 result.add(list);
32             
33             }
34         }
35         
36         return result;
37         
38     }
View Code

120. Word Ladder

 1     public int ladderLength(String start, String end, Set<String> dict) {
 2         // write your code here
 3         if(start == null || end ==null || dict == null){
 4             return 0; 
 5         }
 6         
 7         if(start.equals(end)){
 8             return 1;
 9         }
10         
11         dict.add(end);
12         dict.add(start);
13         
14         int steps = 1;
15         Queue<String> queue = new LinkedList<>();
16         Set<String> visited = new HashSet<>();
17         queue.offer(start);
18         visited.add(start);
19         
20         while(!queue.isEmpty()){
21             steps++;
22             int size = queue.size();
23             for(int i =0; i<size; i++){
24                 String word = queue.poll();
25                 for(String next: getNextWords(word,dict)){
26                     if(next.equals(end)){
27                         return steps;
28                     }
29                     
30                     if(!visited.contains(next)){
31                         visited.add(next);
32                         queue.offer(next);
33                     }
34                 }
35             }
36         }
37         
38         return 0;
39     }
40     public ArrayList<String> getNextWords(String word, Set<String> dict){
41         ArrayList<String> result = new ArrayList<>();
42         for(int i=0; i< word.length(); i++){
43             for(char c = 'a'; c<='z'; c++){
44                 if(word.charAt(i) == c){
45                     continue;
46                 }
47                 
48                 String replacedWord = getReplacedWorld(word,i,c);
49                 if(dict.contains(replacedWord)){
50                     result.add(replacedWord);
51                 }
52             }
53         }
54         
55         return result;
56     }
57     
58     public String getReplacedWorld(String word,int index, char c){
59         char[] chars = word.toCharArray();
60         chars[index] = c;
61         return new String(chars);
62     }
View Code

猜你喜欢

转载自www.cnblogs.com/lizzyluvcoding/p/9653326.html
今日推荐