zoukankan      html  css  js  c++  java
  • 图与搜索

    主要知识点:

    克隆图

    拓扑排序

    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();
     7         char[] chars = s.toCharArray();
     8         boolean[][] isPalindrome = new boolean[n][n];
     9         for (int i = 0; i < n; i++) {
    10             isPalindrome[i][i] = true;
    11         }
    12         for (int k = 1; k < n; k++) {
    13             for (int i = 0; i < n - k; i++) {
    14                 int j = i + k;
    15                 if (chars[i] == chars[j] && (k == 1 || isPalindrome[i + 1][j - 1])) {
    16                     isPalindrome[i][j] = true;
    17                 }
    18             }
    19         }
    20         dfs(s, results, new ArrayList<String>(), isPalindrome, 0);
    21         return results;
    22     }
    23     
    24     private void dfs(String s, List<List<String>> results, List<String> cur, boolean[][] isPalindrome, int start ) {
    25         if (start == s.length()) {
    26             results.add(new ArrayList<String>(cur));
    27             return;
    28         }
    29         for (int i = start; i < s.length(); i++) {
    30             if (isPalindrome[start][i]) {
    31                 cur.add(s.substring(start, i + 1));
    32                 dfs(s, results, cur, isPalindrome, i + 1);
    33                 cur.remove(cur.size() - 1);
    34             }
    35         }
    36     }
    View Code

     Combination Sum

    Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

    The same repeated number may be chosen from C unlimited number of times.

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

    Combination Sum II

    Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

    Each number in C may only be used once in the combination.

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

    Word Ladder --not bug free

    几点容易错的地方:

    求adjMap的时候list list更新只要一个update即可

    prevMap首先应该放入(start, null)

    最后结果是有几个几点就返回几。

    方法一:获得previousMap之后DFS

     1 public int ladderLength(String start, String end, Set<String> dict) {
     2         // write your code here
     3         if (dict == null || dict.size() == 0 || start == null || end == null) {
     4             return 0;
     5         }
     6         dict.add(start);
     7         dict.add(end);
     8         Map<String, List<String>> adjMap = getAdjacentMap(dict, start.length());
     9         Map<String, String> previousMap = new HashMap<String, String>();
    10         // for (String str1 : adjMap.keySet()) {
    11         //     System.out.print(str1 + " ");
    12         //     System.out.println(adjMap.get(str1));
    13         // }
    14         previousMap.put(start, null);//Attention
    15         Queue<String> queue = new LinkedList<String>();
    16         queue.offer(start);
    17         
    18         while (!queue.isEmpty()) {
    19             String cur = queue.poll();
    20             List<String> adj = adjMap.get(cur);
    21             if (adj != null) {//Attention
    22                  for (String str : adj) {
    23                     if (!previousMap.containsKey(str)) {
    24                         previousMap.put(str, cur);
    25                         queue.offer(str);
    26                     }
    27                     if (str.equals(end)) {
    28                         return getNodeNum(previousMap, end);
    29                     }
    30                 }
    31             }
    32         }
    33         return 0;
    34     }
    35     
    36     private int getNodeNum(Map<String, String> previousMap, String end) {
    37         int n = 0;
    38         while (end != null) {
    39             end = previousMap.get(end);
    40             n++;
    41         }
    42         return n;
    43     }
    44 
    45     private Map<String, List<String>> getAdjacentMap(Set<String> dict, int n) {
    46         Map<String, List<String>> adjMap = new HashMap<String, List<String>>();
    47         for (int i = 0; i < n; i++) {
    48             Map<String, List<String>> repToWord = new HashMap<String, List<String>>();
    49             for (String str : dict) {
    50                 String rep = str.substring(0, i) + str.substring(i + 1, n);
    51                 update(repToWord, rep, str);
    52             }
    53             
    54             for (List<String> list : repToWord.values()) {
    55                 if (list.size() < 2) {
    56                     continue;
    57                 }
    58                 for (String str1 : list) {
    59                     for (String str2 : list) {
    60                         if (str1 != str2) {
    61                             update(adjMap, str1, str2);
    62                         }
    63                     }
    64                 }
    65             }
    66         }
    67         return adjMap;
    68     }
    69     
    70     private void update(Map<String, List<String>> map, String key, String value) {
    71         if (!map.containsKey(key)) {
    72             map.put(key, new ArrayList<String>());
    73         }
    74         map.get(key).add(value);
    75     }
    View Code

     方法二:获得previousMap之后BFS

     1  public int ladderLength(String start, String end, Set<String> dict) {
     2         // write your code here
     3         if (dict == null || dict.size() == 0 || start == null || end == null) {
     4             return 0;
     5         }
     6         if (start.equals(end)) {
     7             return 1;
     8         }
     9         dict.add(start);
    10         dict.add(end);
    11         Map<String, List<String>> adjMap = getAdjacentMap(dict, start.length());
    12         HashSet<String> hashSet = new HashSet<String>();
    13         hashSet.add(start);
    14         Queue<String> queue = new LinkedList<String>();
    15         queue.offer(start);
    16         int length = 0;
    17         while (!queue.isEmpty()) {
    18             length++;
    19             int size = queue.size();
    20             for (int i = 0; i < size; i++) {
    21                 String cur = queue.poll();
    22                 List<String> adj = adjMap.get(cur);
    23                 if (adj != null) {
    24                     for (String str : adj) {
    25                         if (!hashSet.contains(str)) {
    26                             hashSet.add(str);
    27                             queue.offer(str);
    28                         }
    29                         if (str.equals(end)) {
    30                             return length + 1;
    31                         }
    32                     }
    33                 }   
    34             }
    35         }
    36         return 0;
    37     }
    38     
    39 
    40     //"hit", "cog", ["hot","dot","dog","lot","log"]
    41     private Map<String, List<String>> getAdjacentMap(Set<String> dict, int n) {
    42         Map<String, List<String>> adjMap = new HashMap<String, List<String>>();
    43         for (int i = 0; i < n; i++) {
    44             Map<String, List<String>> repToWord = new HashMap<String, List<String>>();
    45             for (String str : dict) {
    46                 String rep = str.substring(0, i) + str.substring(i + 1, n);
    47                 update(repToWord, rep, str);
    48             }
    49             
    50             for (List<String> list : repToWord.values()) {
    51                 if (list.size() < 2) {
    52                     continue;
    53                 }
    54                 for (String str1 : list) {
    55                     for (String str2 : list) {
    56                         if (str1 != str2) {
    57                             update(adjMap, str1, str2);
    58                         }
    59                     }
    60                 }
    61             }
    62         }
    63         return adjMap;
    64     }
    65     
    66     private void update(Map<String, List<String>> map, String key, String value) {
    67         if (!map.containsKey(key)) {
    68             map.put(key, new ArrayList<String>());
    69         }
    70         map.get(key).add(value);
    71     }
    View Code

    Word Ladder II--not bug free

     1  public List<List<String>> findLadders(String start, String end, Set<String> dict) {
     2         // write your code here  
     3         List<List<String>> results = new ArrayList<List<String>>();
     4         if (dict == null) {
     5             results.add(new ArrayList<String>());
     6             return results;
     7         }
     8         dict.add(start);
     9         dict.add(end);
    10         Map<String, List<String>> adjMap = getAdjacentMap(dict, start.length());
    11         Map<String, List<String>> previousMap = getLatestPreviousMap(start, end, adjMap);
    12         LinkedList<String> cur = new LinkedList<String>();
    13         cur.add(end);
    14         DFS(start, previousMap, results, cur, end);
    15         return results;
    16     }
    17     
    18     private void DFS(String start, Map<String, List<String>> previousMap, List<List<String>> results,
    19         LinkedList<String> cur, String tail) {
    20             if (tail.equals(start)) {
    21                 results.add(new LinkedList<String>(cur));
    22                 return ;
    23             }
    24             if (previousMap.get(tail) != null) {//Attention
    25                 for (String str : previousMap.get(tail)) {
    26                     cur.addFirst(str);
    27                     DFS(start, previousMap, results, cur, str);
    28                     cur.removeFirst();
    29                 } 
    30             }
    31         }
    32     
    33     
    34     private Map<String, List<String>> getLatestPreviousMap(String start, String end, 
    35         Map<String, List<String>> adjMap) {
    36         Map<String, List<String>> previousMap = new HashMap<String, List<String>>();
    37         Map<String, Integer> distMap = new HashMap<String, Integer>();
    38         Queue<String> queue = new LinkedList<String>();
    39         
    40         previousMap.put(start, null);
    41         distMap.put(start, 0);
    42         queue.offer(start);
    43         
    44         while (!queue.isEmpty()) {
    45             String cur = queue.poll();
    46             List<String> adj = adjMap.get(cur);
    47             if (adj != null) {
    48                 for (String str : adj) {
    49                     if (!previousMap.containsKey(str)) {
    50                         List<String> previousList = new ArrayList<String>();
    51                         previousList.add(cur);
    52                         previousMap.put(str, previousList);
    53                         distMap.put(str, distMap.get(cur) + 1);
    54                         queue.offer(str);//Attention
    55                     } else if (distMap.get(cur) < distMap.get(str)) {
    56                         previousMap.get(str).add(cur);
    57                     }
    58                 }
    59             }
    60         }
    61         return previousMap;
    62     }
    63     
    64      private Map<String, List<String>> getAdjacentMap(Set<String> dict, int n) {
    65         Map<String, List<String>> adjMap = new HashMap<String, List<String>>();
    66         for (int i = 0; i < n; i++) {
    67             Map<String, List<String>> repToWord = new HashMap<String, List<String>>();
    68             for (String str : dict) {
    69                 String rep = str.substring(0, i) + str.substring(i + 1, n);
    70                 update(repToWord, rep, str);
    71             }
    72             
    73             for (List<String> list : repToWord.values()) {
    74                 if (list.size() < 2) {
    75                     continue;
    76                 }
    77                 for (String str1 : list) {
    78                     for (String str2 : list) {
    79                         if (str1 != str2) {
    80                             update(adjMap, str1, str2);
    81                         }
    82                     }
    83                 }
    84             }
    85         }
    86         return adjMap;
    87     }
    88     
    89     private void update(Map<String, List<String>> map, String key, String value) {
    90         if (!map.containsKey(key)) {
    91             map.put(key, new ArrayList<String>());
    92         }
    93         map.get(key).add(value);
    94     }
    View Code

    Six Degrees

    Six degrees of separation is the theory that everyone and everything is six or fewer steps away, by way of introduction, from any other person in the world, so that a chain of "a friend of a friend" statements can be made to connect any two people in a maximum of six steps.

    Given a friendship relations, find the degrees of two people, return -1 if they can not been connected by friends of friends.

     1 public int sixDegrees(List<UndirectedGraphNode> graph,
     2                           UndirectedGraphNode s,
     3                           UndirectedGraphNode t) {
     4         // Write your code here
     5         Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();
     6         HashMap<UndirectedGraphNode, UndirectedGraphNode> preMap 
     7             = new HashMap<UndirectedGraphNode, UndirectedGraphNode>();
     8         queue.offer(s);
     9         preMap.put(s, null);
    10         while (!queue.isEmpty()) {
    11             UndirectedGraphNode cur = queue.poll();
    12             for (UndirectedGraphNode node : cur.neighbors) {
    13                 if (!preMap.containsKey(node)) {
    14                     queue.offer(node);
    15                     preMap.put(node, cur);
    16                 }
    17                 if (node == t) {
    18                     break;
    19                 }
    20             }
    21         }
    22         int dist = 0;
    23         UndirectedGraphNode tail = t;
    24         while (tail != s) {
    25             dist++;
    26             tail = preMap.get(tail);
    27             if (tail == null) {
    28                 return -1;
    29             }
    30         }
    31         return dist;
    32     }
    View Code

     Find the Connected Component in the Undirected Graph

    Find the number connected component in the undirected graph. Each node in the graph contains a label and a list of its neighbors. (a connected component (or just component) of an undirected graph is a subgraph in which any two vertices are connected to each other by paths, and which is connected to no additional vertices in the supergraph.)

    Each connected component should sort by label.

     1 public List<List<Integer>> connectedSet(ArrayList<UndirectedGraphNode> nodes) {
     2         // Write your code here
     3         HashSet<UndirectedGraphNode> hashSet = new HashSet<UndirectedGraphNode>();
     4         List<List<Integer>> results = new ArrayList<List<Integer>>();
     5         for (UndirectedGraphNode node : nodes) {
     6             if (!hashSet.contains(node)) {
     7                 hashSet.add(node);
     8                 List<Integer> tempList = new ArrayList<Integer>();
     9                 Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();
    10                 tempList.add(node.label);
    11                 queue.offer(node);
    12                 while (!queue.isEmpty()) {
    13                     UndirectedGraphNode cur = queue.poll();
    14                     for (UndirectedGraphNode tempNode : cur.neighbors){
    15                          if (!hashSet.contains(tempNode)) {
    16                              hashSet.add(tempNode);
    17                              queue.offer(tempNode);
    18                              tempList.add(tempNode.label);
    19                          }
    20                     }
    21                 }
    22                 Collections.sort(tempList);
    23                 results.add(tempList);
    24             }
    25         }
    26         return results;
    27     }
    View Code

    Find the Missing Number II --not bug free

    Giving a string with number from 1-n in random order, but miss 1 number.Find that number.

     Notice

    n <= 30

     1 public int findMissing2(int n, String str) {
     2         // Write your code here
     3         if (n <= 0 || str == null) {
     4             return 0;
     5         }
     6         char[] chars = str.toCharArray();
     7         boolean[] appeared = new boolean[n + 1];
     8         int[] curIndex = {0};
     9         help(n, chars, appeared, curIndex);
    10         for (int i = 1; i <= n; i++) {
    11             if (!appeared[i]) {
    12                 return i;
    13             }
    14         }
    15         return 0;
    16     }
    17     
    18     public void help(int n, char[] chars, boolean[] appeared, int[] curIndex) {
    19         if (curIndex[0] >= chars.length) {
    20             return ;
    21         }
    22         if (chars[curIndex[0]] == '0') {
    23             return ;
    24         }
    25         if (!appeared[chars[curIndex[0]] - '0']) {
    26             appeared[chars[curIndex[0]] - '0'] = true;
    27             curIndex[0]++;
    28             help(n, chars, appeared, curIndex);
    29             if (curIndex[0] >= chars.length) {
    30                 return ;
    31             }
    32             curIndex[0]--;
    33             appeared[chars[curIndex[0]] - '0'] = false;
    34         }
    35         if (curIndex[0] < chars.length - 1) {
    36             int a1 = chars[curIndex[0]] - '0';
    37             int a2 = chars[curIndex[0] + 1] - '0';
    38             int num = a1 * 10 + a2;
    39             if (num > n || appeared[num]) {
    40                 return ;
    41             }
    42             appeared[num] = true;
    43             curIndex[0] += 2;
    44             help(n, chars, appeared, curIndex);
    45             if (curIndex[0] >= chars.length) {
    46                 return ;
    47             }
    48             curIndex[0] -= 2;
    49             appeared[num] = false;
    50         }
    51     }
    View Code
  • 相关阅读:
    MySQL与Redis结合方案
    Linux系统如何监控服务器硬件、操作系统、应用服务和业务
    【MySQL】MySQL复制之防崩溃从节点
    Linux系统vim编辑器换行至文件的行首及行尾操作
    Xtrabackup远程备份
    innodb_force_recovery参数分析
    Oracle异构平台迁移利器之XTTS(使用rman方式)
    ES6基础语法
    读郭老师推荐书籍--《原则》
    PhpStorm 的基本应用
  • 原文地址:https://www.cnblogs.com/futurehau/p/5989835.html
Copyright © 2011-2022 走看看