深度优先搜索(DFS) — 20180926
Posted lizzyluvcoding
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度优先搜索(DFS) — 20180926相关的知识,希望对你有一定的参考价值。
用DFS的场景:
找出所有方案:DFS
找出所有方案总数 可能是动态规划
DFS时间复杂度:答案个数*构造每个答案的时间
动态规划时间复杂度:状态个数*计算每个状态时间
二叉树时间复杂度:节点数*处理每个节点时间
135. Combination Sum
1 public class Solution { 2 /** 3 * @param candidates: A list of integers 4 * @param target: An integer 5 * @return: A list of lists of integers 6 */ 7 public List<List<Integer>> combinationSum(int[] candidates, int target) { 8 // write your code here 9 List<List<Integer>> result = new ArrayList<>(); 10 if(candidates == null || candidates.length ==0){ 11 return result; 12 } 13 Arrays.sort(candidates); 14 ArrayList<Integer> combination = new ArrayList<>(); 15 16 Hepler(result,candidates,target,0,combination); 17 return result; 18 19 } 20 21 22 public void Hepler(List<List<Integer>> result,int[] candidates, int target, int startIndex,List<Integer> combination){ 23 if(target == 0){ 24 result.add(new ArrayList(combination)); 25 return; 26 } 27 28 for(int i= startIndex; i<candidates.length; i++){ 29 if(target<candidates[i]){ 30 continue; 31 } 32 if(i>0 && candidates[i]==candidates[i-1]){ 33 continue; 34 } 35 combination.add(candidates[i]); 36 Hepler(result,candidates,target-candidates[i],i,combination); 37 combination.remove(combination.size()-1); 38 } 39 } 40 }
153. Combination Sum II
1 public class Solution { 2 /** 3 * @param num: Given the candidate numbers 4 * @param target: Given the target number 5 * @return: All the combinations that sum to target 6 */ 7 public List<List<Integer>> combinationSum2(int[] num, int target) { 8 // write your code here 9 List<List<Integer>> result = new ArrayList<>(); 10 if(num == null || num.length ==0){ 11 return result; 12 } 13 Arrays.sort(num); 14 List<Integer> combination = new ArrayList<>(); 15 16 Helper(num,target,0,result,combination); 17 18 return result; 19 } 20 21 public void Helper(int[] num, int target, int startIndex, List<List<Integer>> result, List<Integer> combination){ 22 if(target==0){ 23 result.add(new ArrayList<>(combination)); 24 return; 25 } 26 27 for(int i = startIndex; i<num.length; i++){ 28 if(target<num[i]){ 29 break; 30 } 31 if(i>0 && num[i] == num[i-1] && i!=startIndex){ 32 continue; 33 } 34 combination.add(num[i]); 35 Helper(num,target-num[i],i+1,result,combination); 36 combination.remove(combination.size()-1); 37 } 38 } 39 }
136. Palindrome Partitioning
切割问题也就是组合问题
1 public class Solution { 2 /* 3 * @param s: A string 4 * @return: A list of lists of string 5 */ 6 public List<List<String>> partition(String s) { 7 // write your code here 8 List<List<String>> result = new ArrayList<>(); 9 if (s == null || s.length() == 0) { 10 return result; 11 } 12 13 List<String> combination = new ArrayList<>(); 14 Helper(result, combination, 0, s); 15 return result; 16 } 17 18 public void Helper(List<List<String>> result, List<String> combination, int startIndex, String s) { 19 if (startIndex == s.length()) { 20 result.add(new ArrayList<>(combination)); 21 return; 22 } 23 24 for (int i = startIndex; i < s.length(); i++) { 25 String sub = s.substring(startIndex, i + 1); 26 if (!isPalindrome(sub)) { 27 continue; 28 } 29 combination.add(sub); 30 Helper(result, combination, i + 1, s); 31 combination.remove(combination.size() - 1); 32 } 33 } 34 35 public boolean isPalindrome(String s) { 36 int start = 0; 37 int end = s.length() - 1; 38 while (start < end) { 39 if (s.charAt(start) != s.charAt(end)) { 40 return false; 41 } 42 start++; 43 end--; 44 } 45 return true; 46 } 47 }
15. Permutations
1 public class Solution { 2 /* 3 * @param nums: A list of integers. 4 * @return: A list of permutations. 5 */ 6 public List<List<Integer>> permute(int[] nums) { 7 // write your code here 8 List<List<Integer>> result = new ArrayList<>(); 9 if (nums == null) { 10 return result; 11 } 12 13 boolean[] visited = new boolean[nums.length]; 14 List<Integer> permutation = new ArrayList<>(); 15 Helper(result, permutation, nums, visited); 16 return result; 17 } 18 19 public void Helper(List<List<Integer>> result, List<Integer> permutation, int[] nums, boolean[] visited) { 20 if (permutation.size() == nums.length) { 21 result.add(new ArrayList<>(permutation)); 22 return; 23 } 24 25 for (int i = 0; i < nums.length; i++) { 26 if (visited[i]) { 27 continue; 28 } 29 permutation.add(nums[i]); 30 visited[i] = true; 31 Helper(result, permutation, nums, visited); 32 permutation.remove(permutation.size() - 1); 33 visited[i] = false; 34 } 35 } 36 }
16. Permutations II
1 public class Solution { 2 /* 3 * @param : A list of integers 4 * @return: A list of unique permutations 5 */ 6 public List<List<Integer>> permuteUnique(int[] nums) { 7 // write your code here 8 List<List<Integer>> result = new ArrayList<>(); 9 if(nums == null){ 10 return result; 11 } 12 13 List<Integer> permutation = new ArrayList<>(); 14 boolean[] visited =new boolean[nums.length]; 15 Arrays.sort(nums); 16 Helper(result,nums,permutation,visited); 17 return result; 18 } 19 20 public void Helper(List<List<Integer>> result, int[] nums, List<Integer> permutation, boolean[] visited){ 21 if(permutation.size() == nums.length){ 22 result.add(new ArrayList<>(permutation)); 23 return; 24 } 25 26 for(int i =0; i<nums.length;i++){ 27 if(visited[i]){ 28 continue; 29 } 30 if(i>0 && nums[i]==nums[i-1] && visited[i-1] == false){ 31 continue; 32 } 33 permutation.add(nums[i]); 34 visited[i] = true; 35 Helper(result,nums,permutation,visited); 36 permutation.remove(permutation.size()-1); 37 visited[i] = false; 38 } 39 } 40 };
33. N-Queens
1 public class Solution { 2 /* 3 * @param n: The number of queens 4 * @return: All distinct solutions 5 */ 6 public List<List<String>> solveNQueens(int n) { 7 // write your code here 8 List<List<String>> result = new ArrayList<>(); 9 if (n < 0) { 10 return result; 11 } 12 List<Integer> queenSolution = new ArrayList<>(); 13 Helper(result, queenSolution, n); 14 return result; 15 } 16 17 public void Helper(List<List<String>> result, List<Integer> queenSolution, int n) { 18 if (queenSolution.size() == n) { 19 result.add(getQueenStr(queenSolution)); 20 return; 21 } 22 23 for (int i = 0; i < n; i++) { 24 if (!isValid(queenSolution, i)) { 25 continue; 26 } 27 queenSolution.add(i); 28 Helper(result, queenSolution, n); 29 queenSolution.remove(queenSolution.size() - 1); 30 } 31 } 32 33 public boolean isValid(List<Integer> queenSolution, int q) { 34 int nextcol = queenSolution.size(); 35 for (int i = 0; i < queenSolution.size(); i++) { 36 //判断是否同一列 37 if (queenSolution.get(i) == q) { 38 return false; 39 } 40 //判断是否在左斜线 41 if (nextcol + q == i + queenSolution.get(i)) { 42 return false; 43 } 44 //判断是否在右斜线 45 if (nextcol - q == i - queenSolution.get(i)) { 46 return false; 47 } 48 } 49 50 return true; 51 } 52 53 public List<String> getQueenStr(List<Integer> solution) { 54 List<String> res = new ArrayList<>(); 55 int strLen = solution.size(); 56 for (Integer i : solution) { 57 StringBuilder stringBuilder = new StringBuilder(); 58 for (int m = 0; m < strLen; m++) { 59 stringBuilder.append(m == i ? ‘Q‘ : ‘.‘); 60 } 61 res.add(stringBuilder.toString()); 62 } 63 return res; 64 } 65 }
121. Word Ladder II
1 public class Solution { 2 /* 3 * @param start: a string 4 * @param end: a string 5 * @param dict: a set of string 6 * @return: a list of lists of string 7 */ 8 public List<List<String>> findLadders(String start, String end, Set<String> dict) { 9 // write your code here 10 List<List<String>> result = new ArrayList<>(); 11 if (start == null || end == null) { 12 return result; 13 } 14 if (start.equals(end)) { 15 List<String> solution = new ArrayList<>(); 16 solution.add(start); 17 solution.add(end); 18 result.add(solution); 19 return result; 20 } 21 //字典要加入start,end,否则对某些case会fail 22 dict.add(start); 23 dict.add(end); 24 Map<String, Integer> distanceMap = new HashMap<>(); 25 Map<String, List<String>> neighbourMap = new HashMap<>(); 26 getShortestPath(start, end, dict, distanceMap, neighbourMap); 27 List<String> solution = new ArrayList<>(); 28 //基于nextWord进行递归,所以一开始要将初始值加入solution 29 solution.add(start); 30 Helper(result, solution, distanceMap, neighbourMap, start, end); 31 return result; 32 } 33 34 //bfs 重点注意,得到最短路径之后一定要走完最后一层的BFS,否则会少解 35 public void getShortestPath(String start, String end, Set<String> dict, 36 Map<String, Integer> distanceMap, Map<String, List<String>> neighbourMap) { 37 38 Queue<String> queue = new LinkedList<>(); 39 queue.offer(start); 40 distanceMap.put(start, 0); 41 42 int distance = 0; 43 boolean isShortedPath = false; 44 while (!queue.isEmpty()) { 45 int size = queue.size(); 46 distance++; 47 for (int i = 0; i < size; i++) { 48 String word = queue.poll(); 49 if (neighbourMap.containsKey(word)) { 50 continue; 51 } 52 neighbourMap.put(word, new ArrayList<>()); 53 for (String next : getNextWords(word, dict)) { 54 neighbourMap.get(word).add(next); 55 if(!distanceMap.containsKey(next)){ 56 distanceMap.put(next, distance); 57 queue.offer(next); 58 } 59 if (next.equals(end)) { 60 isShortedPath = true; 61 } 62 } 63 } 64 65 if(isShortedPath){ 66 break; 67 } 68 } 69 70 } 71 72 //dfs 73 public void Helper(List<List<String>> result, List<String> solution, 74 Map<String, Integer> distanceMap, Map<String, List<String>> neighbourMap, 75 String word, String end) { 76 if(word.equals(end)){ 77 result.add(new ArrayList<>(solution)); 78 return; 79 } 80 81 if(neighbourMap.get(word)!=null){ 82 for(String str: neighbourMap.get(word)){ 83 if(distanceMap.containsKey(str) && distanceMap.get(str) == distanceMap.get(word) + 1){ 84 solution.add(str); 85 Helper(result,solution,distanceMap,neighbourMap,str,end); 86 solution.remove(solution.size()-1); 87 } 88 } 89 } 90 } 91 92 public List<String> getNextWords(String word, Set<String> dict) { 93 List<String> result = new ArrayList<>(); 94 int len = word.length(); 95 for (int i = 0; i < len; i++) { 96 for (char ch = ‘a‘; ch <= ‘z‘; ch++) { 97 if (ch == word.charAt(i)) { 98 continue; 99 } 100 if (dict.contains(getReplaceWord(word, i, ch))) { 101 result.add(getReplaceWord(word, i, ch)); 102 } 103 } 104 } 105 return result; 106 } 107 108 public String getReplaceWord(String word, int i, char ch) { 109 char[] chars = word.toCharArray(); 110 chars[i] = ch; 111 return new String(chars); 112 } 113 114 }
以上是关于深度优先搜索(DFS) — 20180926的主要内容,如果未能解决你的问题,请参考以下文章
DFS(深度优先搜索遍历有向图)-03-有向图-太平洋大西洋水流问题
深度优先搜索(DFS: Depth First Search)
数据结构与算法图遍历算法 ( 深度优先搜索 DFS | 深度优先搜索和广度优先搜索 | 深度优先搜索基本思想 | 深度优先搜索算法步骤 | 深度优先搜索理论示例 )
深度优先搜索 DFS(Depath First Search, DFS)