图与搜索

Posted futurehau

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图与搜索相关的知识,希望对你有一定的参考价值。

主要知识点:

克隆图

拓扑排序

DFS BFS

BFS两个使用场景:图的遍历 简单图求最短路径

BFS in Graph 和BFS in Tree的主要区别就是有无环

遇到让找所有方案的题,一定是DFS,90%的DFS要么是排列,要么是组合。

 

Clone Graph --not bug free

方法一:递归

 1 public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
 2         // write your code here
 3         if (node == null) {
 4             return node;
 5         }
 6         HashMap<UndirectedGraphNode, UndirectedGraphNode> hashMap = new HashMap<>();
 7         return help(node, hashMap);
 8     }
 9     
10     public UndirectedGraphNode help(UndirectedGraphNode node, HashMap<UndirectedGraphNode, UndirectedGraphNode> hashMap) {
11         UndirectedGraphNode root = new UndirectedGraphNode(node.label);
12         hashMap.put(node, root);
13         for (UndirectedGraphNode neighbor : node.neighbors) {
14             if (hashMap.containsKey(neighbor)) {
15                 root.neighbors.add(hashMap.get(neighbor));
16             } else {
17                 root.neighbors.add(help(neighbor, hashMap));
18             }
19         }
20         return root;
21     }
View Code

方法二:非递归,分两步:找节点和mapping  neighbors

 1 public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
 2         // write your code here
 3         if (node == null) {
 4             return node;
 5         }
 6         //getNodeAndMapping
 7         List<UndirectedGraphNode> nodes = new ArrayList<UndirectedGraphNode>();
 8         HashMap<UndirectedGraphNode, UndirectedGraphNode> mapping = new HashMap<>();
 9         Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();
10         queue.offer(node);
11         nodes.add(node);
12         mapping.put(node, new UndirectedGraphNode(node.label));
13         while (!queue.isEmpty()) {
14             UndirectedGraphNode cur = queue.poll();
15             for (UndirectedGraphNode neighbor : cur.neighbors) {
16                 if (mapping.containsKey(neighbor)) {
17                     continue;
18                 }
19                 nodes.add(neighbor);
20                 mapping.put(neighbor, new UndirectedGraphNode(neighbor.label));
21                 queue.offer(neighbor);
22             }
23         }
24         
25         //clone neighbor
26         for (UndirectedGraphNode old : nodes) {
27             UndirectedGraphNode newNode = mapping.get(old);
28             for (UndirectedGraphNode neighbor : old.neighbors) {
29                 newNode.neighbors.add(mapping.get(neighbor));
30             }
31         }
32         return mapping.get(node);
33     }
View Code

 

Topological Sorting

 1 public ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
 2         // write your code here
 3         Map<DirectedGraphNode, Integer> indegreeMap = new HashMap<DirectedGraphNode, Integer>();
 4         getInDegree(graph, indegreeMap);
 5         Queue<DirectedGraphNode> queue = new LinkedList<DirectedGraphNode>();
 6         for (DirectedGraphNode node : graph) {
 7             if (!indegreeMap.containsKey(node)) {
 8                 queue.offer(node);
 9             }
10         }
11         ArrayList<DirectedGraphNode> result = new ArrayList<>();
12         while (!queue.isEmpty()) {
13             DirectedGraphNode cur = queue.poll();
14             result.add(cur);
15             for (DirectedGraphNode neighbor : cur.neighbors) {
16                 int indegree = indegreeMap.get(neighbor);
17                 indegreeMap.put(neighbor, indegree - 1);
18                 if (indegree == 1) {
19                     queue.offer(neighbor);
20                 }
21             }
22         }
23         return result;
24     }
25     
26     public void getInDegree(ArrayList<DirectedGraphNode> graph,  
27         Map<DirectedGraphNode, Integer> indegreeMap) {
28             for (DirectedGraphNode node : graph) {
29                 for (DirectedGraphNode neighbor : node.neighbors) {
30                     if (!indegreeMap.containsKey(neighbor)) {
31                         indegreeMap.put(neighbor, 1);
32                     } else {
33                         indegreeMap.put(neighbor, indegreeMap.get(neighbor) + 1);
34                     }
35                 }
36             }   
37     }
View Code

 

Permutations

Given a list of numbers, return all possible permutations.You can assume that there is no duplicate numbers in the list.

public List<List<Integer>> permute(int[] nums) {
        // write your code here
        List<List<Integer>> results = new ArrayList<>();
        if (nums == null || nums.length == 0) {
            results.add(new ArrayList<Integer>());
            return results;
        }
        boolean[] used = new boolean[nums.length];
        DFS(nums, results, new ArrayList<Integer>(), used);
        return results;
    }
    
    public void DFS(int[] nums, List<List<Integer>> results, List<Integer> cur, boolean[] used) {
        if (cur.size() == nums.length) {
            results.add(new ArrayList<>(cur));
            return ;
        }
        for (int i = 0; i < nums.length; i++) {
            if (used[i]) {
                continue;
            }
            used[i] = true;
            cur.add(nums[i]);
            DFS(nums, results, cur, used);
            cur.remove(cur.size() - 1);
            used[i] = false;
        }
    }
View Code

 

Permutations II

注意不要忘了排序。

Given a list of numbers with duplicate number in it. Find all unique permutations.

 1 public List<List<Integer>> permuteUnique(int[] nums) {
 2         // write your code here
 3         List<List<Integer>> results = new ArrayList<>();
 4         if (nums == null || nums.length == 0) {
 5             results.add(new ArrayList<Integer>());
 6             return results;
 7         }
 8         Arrays.sort(nums);
 9         boolean[] used = new boolean[nums.length];
10         DFS(nums, results, new ArrayList<Integer>(), used);
11         return results;
12     }
13     
14     public void DFS(int[] nums, List<List<Integer>> results, List<Integer> cur, boolean[] used) {
15         if (cur.size() == nums.length) {
16             results.add(new ArrayList<>(cur));
17             return ;
18         }
19         for (int i = 0; i < nums.length; i++) {
20             if (used[i]) {
21                 continue;
22             }
23             if (i > 0 && !used[i - 1] && nums[i] == nums[i - 1]) {
24                 continue;
25             }
26             used[i] = true;
27             cur.add(nums[i]);
28             DFS(nums, results, cur, used);
29             cur.remove(cur.size() - 1);
30             used[i] = false;
31         }
32     }
View Code

 

String Permutation II

Given a list of numbers with duplicate number in it. Find all uniquepermutations.

 1 public List<String> stringPermutation2(String str) {
 2         // Write your code here
 3         List<String> result = new ArrayList<String>();
 4         if (str == null || str.length() == 0) {
 5             result.add("");
 6             return result;
 7         }
 8         char[] chars = str.toCharArray();
 9         Arrays.sort(chars);
10         boolean[] used = new boolean[chars.length];
11         StringBuilder sb = new StringBuilder();
12         DFS(chars, result, sb, used);
13         return result;
14     }
15     
16     private void DFS(char[] chars, List<String> result, StringBuilder sb, boolean[] used) {
17         if (sb.length() == chars.length) {
18             result.add(sb.toString());
19         }
20         for (int i = 0; i < chars.length; i++) {
21             if (used[i]) {
22                 continue;
23             }
24             if (i != 0 && !used[i - 1] && chars[i] == chars[i - 1]) {
25                 continue;
26             }
27             used[i] = true;
28             sb.append(chars[i]);
29             DFS(chars, result, sb, used);
30             used[i] = false;
31             sb.deleteCharAt(sb.length() - 1);
32         }
33     }
View Code

 

Subsets

Given a set of distinct integers, return all possible subsets

 1 public ArrayList<ArrayList<Integer>> subsets(int[] nums) {
 2         // write your code here
 3         ArrayList<ArrayList<Integer>> results = new ArrayList<ArrayList<Integer>>();
 4         if (nums == null || nums.length == 0) {
 5             return results;
 6         }
 7         Arrays.sort(nums);
 8         DFS(nums, results, new ArrayList<Integer>(), 0);
 9         return results;
10     }
11     
12     private void DFS(int[] nums, ArrayList<ArrayList<Integer>> results, ArrayList<Integer> cur, int start) {
13         results.add(new ArrayList<Integer>(cur));
14         for (int i = start; i < nums.length; i++) {
15             cur.add(nums[i]);
16             DFS(nums, results, cur, i + 1);
17             cur.remove(cur.size() - 1);
18         }
19     }
View Code

 

Subsets II

Given a list of numbers that may has duplicate numbers, return all possible subsets

 1 public ArrayList<ArrayList<Integer>> subsetsWithDup(int[] nums) {
 2         // write your code here
 3         ArrayList<ArrayList<Integer>> results = new ArrayList<ArrayList<Integer>>();
 4         if (nums == null || nums.length == 0) {
 5             return results;
 6         }
 7         Arrays.sort(nums);
 8         DFS(nums, results, new ArrayList<Integer>(), 0);
 9         return results;
10     }
11     
12     private void DFS(int[] nums, ArrayList<ArrayList<Integer>> results, ArrayList<Integer> cur, int start) {
13         results.add(new ArrayList<Integer>(cur));
14         for (int i = start; i < nums.length; i++) {
15             if (i != start && nums[i] == nums[i - 1]) {
16                 continue;
17             }
18             cur.add(nums[i]);
19             DFS(nums, results, cur, i + 1);
20             cur.remove(cur.size() - 1);
21         }
22     }
View Code

 

k Sum II

Given n unique integers, number k (1<=k<=n) and target.

Find all possible k integers where their sum is target.

 1 public ArrayList<ArrayList<Integer>> kSumII(int[] A, int k, int target) {
 2         // write your code here
 3         ArrayList<ArrayList<Integer>> results = new ArrayList<ArrayList<Integer>>();
 4         if (A == null || A.length == 0) {
 5             results.add(new ArrayList<Integer>());
 6             return results;
 7         }
 8         Arrays.sort(A);
 9         DFS(A, k, target, 0, results, new ArrayList<Integer>());
10         return results;
11     }
12     
13     private void DFS(int[] A, int k, int target, int start, 
14         ArrayList<ArrayList<Integer>> results, ArrayList<Integer> cur) {
15         if (cur.size() > k) {
16             return ;
17         }
18         if (cur.size() == k && target == 0) {
19             results.add(new ArrayList<Integer>(cur));
20             return ;
21         }
22         for (int i = start; i < A.length; i++) {
23             cur.add(A[i]);
24             DFS(A, k, target - A[i], i + 1, results, cur);
25             cur.remove(cur.size() - 1);
26         }
27     }
View Code

 

N-Queens --not bug free

 1 ArrayList<ArrayList<String>> solveNQueens(int n) {
 2         // write your code here
 3         ArrayList<ArrayList<String>> results = new ArrayList<ArrayList<String>>();
 4         if (n <= 0) {
 5             results.add(new ArrayList<String>());
 6             return results;
 7         }
 8         char[] helpChar = new char[n];
 9         Arrays.fill(helpChar,\'.\');
10         boolean[] col_used = new boolean[n];
11         boolean[] diag_pos_used = new boolean[2 * n - 1];
12         boolean[] diag_neg_used = new boolean[2 * n - 1];
13         help(n, results, new ArrayList<String>(), helpChar,
14             0, col_used, diag_pos_used, diag_neg_used);
15         return results;
16     }
17     
18     public void help(int n, ArrayList<ArrayList<String>> results, ArrayList<String> cur,
19         char[] helpChar, int row_cur, boolean[] col_used, 
20         boolean[] diag_pos_used, boolean[] diag_neg_used) {
21         if (row_cur == n) {
22             results.add(new ArrayList<String>(cur));
23             return;
24         }
25         for (int j = 0; j < n; j++) {
26             int d1 = row_cur + j;
27             int d2 = j - row_cur + n - 1;
28             if (col_used[j] || diag_pos_used[d2] || diag_neg_used[d1]) {
29                     continue;
30             } else {
31                 col_used[j] = true;
32                 diag_pos_used[d2] = true;
33                 diag_neg_used[d1] = true;
34                 helpChar[j] = \'Q\';
35                 cur.add(new String(helpChar));
36                 helpChar[j] = \'.\';//Attention
37                     
38                 help(n, results, cur, helpChar,
39                     row_cur + 1, col_used, diag_pos_used, diag_neg_used);
40                     
41                 col_used[j] = false;
42                 diag_pos_used[d2] = false;
43                 diag_neg_used[d1] = false;
44                 cur.remove(cur.size() - 1);
45             }
46         }
47     }
View Code

 

N-Queens II

Follow up for N-Queens problem.

Now, instead outputting board configurations, return the total number of distinct solutions.

 1 public static int sum;
 2     public int totalNQueens(int n) {
 3         //write your code here
 4         if (n <= 0) {
 5             return 0;
 6         }
 7         boolean[] col_used = new boolean[n];
 8         boolean[] diag_pos_used = new boolean[2 * n];
 9         boolean[] diag_neg_used = new boolean[2 * n];
10         sum = 0;
11         DFS(n, 0, col_used, diag_pos_used, diag_neg_used);
12         return sum;
13     }
14     
15     public void DFS(int n, int row, boolean[] col_used, boolean[] diag_pos_used, boolean[] diag_neg_used) {
16         if (row == n) {
17             sum++;
18             return;
19         }
20         for (int j = 0; j < n; j++) {
21             int d1 = j - row + n - 1;
22             int d2 = j + row;
23             if (col_used[j] || diag_pos_used[d1] || diag_neg_used[d2]) {
24                 continue;
25             }
26             col_used[j] = true;
27             diag_pos_used[d1] = true;
28             diag_neg_used[d2] = true;
29             DFS(n, row + 1, col_used, diag_pos_used, diag_neg_used);
30             col_used[j] = false;
31             diag_pos_used[d1] = false;
32             diag_neg_used[d2] = false;
33         }
34     }
View Code

 

Palindrome Partitioning

复杂度2^n,切或者不切。

Given a string s, partition s such that every substring of the partition is a palindrome.Return all possible palindrome partitioning of s.

 1 List<List<String>> results = new ArrayList<List<String>>();
 2         if (s == null || s.length() == 0) {
 3             results.add(new ArrayList<String>());
 4             return results;
 5         }
 6         int n = s.length();
以上是关于图与搜索的主要内容,如果未能解决你的问题,请参考以下文章

图与搜索

图与深度优先广度优先搜索

片段从一开始就没有显示 |安卓工作室

如何在 BottomNavigationView 的片段上打开搜索界面?

26个jQuery代码片段使用技巧

插入排序动态图与代码(二分插入与普通插入)