### 7.8 93. Restore IP Addresses A valid IP address consists of exactly four integers separated by single dots. Each integer is between 0 and 255 (inclusive) and cannot have leading zeros. For example, "0.1.2.201" and "192.168.1.1" are valid IP addresses, but "0.011.255.245", "192.168.1.312" and "192.168@1.1" are invalid IP addresses. Given a string s containing only digits, return all possible valid IP addresses that can be formed by inserting dots into s. You are not allowed to reorder or remove any digits in s. You may return the valid IP addresses in any order. https://programmercarl.com/0093.%E5%A4%8D%E5%8E%9FIP%E5%9C%B0%E5%9D%80.html 这题卡住的地方:无需建立中间的path,本质上只是在原有字符串上打点。 写的过程中出错的地方:辅助函数isValid中,让0开头的非0数字不合法的语句中,charAt(int)返回的是char,所以应该是`=='0'。 ```java List<String> result = new LinkedList<>(); public List<String> restoreIpAddresses(String s) { StringBuilder sb = new StringBuilder(s); backtracking(sb,0,0); return result; } private void backtracking(StringBuilder sb, int startIndex, int pointSum){ if(pointSum == 3){ if(isValid(sb,startIndex,sb.length()-1)){ result.add(sb.toString()); } return; } for (int i = startIndex; i < sb.length(); i++) { if(isValid(sb,startIndex,i)){ sb.insert(i+1,"."); pointSum++; }else{ break;//后面的不用再看了,直接退出 } backtracking(sb,i+2,pointSum); sb.deleteCharAt(i+1); pointSum--; } } private boolean isValid(StringBuilder sb, int start, int end){ if(end < start){ return false; } //这里的0是char,所以要打上''!!!不然是不会return false的! if(sb.charAt(start) == '0' && start != end){ return false; } int num = 0; for (int i = start; i <= end; i++) { int digit = sb.charAt(i) - '0'; num = num * 10 + digit; if(num > 255) return false; } return true; } ``` ### 7.9 78. Subsets Given an integer array nums of unique elements, return all possible subsets (the power set). The solution set must not contain duplicate subsets. Return the solution in any order. Example 1: Input: nums =` [1,2,3] Output: `[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]] Example 2: Input: nums =` [0] Output:` [[],[0]] 78.子集 子集问题,就是收集树形结构中,每一个节点的结果。 整体代码其实和 回溯模板都是差不多的。 https://programmercarl.com/0078.%E5%AD%90%E9%9B%86.html 终止条件:到达叶子节点。 startIndex > nums.length() 那什么时候把path放入result呢?在终止条件的上方。每次进入递归,就收获结果。 ```java public class subsets78 { List<List<Integer>> result = new LinkedList<>(); LinkedList<Integer> path = new LinkedList<>(); public List<List<Integer>> subsets(int[] nums) { backtracking(nums,0); return result; } private void backtracking(int[] nums, int startIndex){ //收获结果 result.add(new ArrayList<>(path)); //终止条件 if(startIndex > nums.length) return; for (int i = startIndex; i < nums.length; i++) { path.add(nums[i]); backtracking(nums,i+1); path.removeLast(); startIndex--; } } } class subsets78Test { public static void main(String[] args) { subsets78 example = new subsets78(); int[] nums = {1,2,3}; List<List<Integer>> result = example.subsets(nums); for(List<Integer> levels :result){ System.out.print("["); for(int i : levels){ System.out.print(i+" "); } System.out.println("]"); } } } ``` ### 7.10 90. Subsets II Given an integer array nums that may contain duplicates, return all possible subsets (the power set). The solution set must not contain duplicate subsets. Return the solution in any order. Example 1: Input: nums = `[1,2,2] Output: `[[],[1],[1,2],[1,2,2],[2],[2,2]] Example 2: Input: nums =` [0] Output:` [[],[0]]` 90.子集II 大家之前做了 40.组合总和II 和 78.子集 ,本题就是这两道题目的结合,建议自己独立做一做,本题涉及的知识,之前都讲过,没有新内容。 https://programmercarl.com/0090.%E5%AD%90%E9%9B%86II.html 这类题目要记得给数组排序!! ```java public class subsets90 { List<List<Integer>> result = new LinkedList<>(); LinkedList<Integer> path = new LinkedList<>(); public List<List<Integer>> subsetsWithDup(int[] nums) { int[] used = new int[nums.length]; Arrays.sort(nums); backtracking(nums,0,used); return result; } private void backtracking(int[] nums, int startIndex, int[] used){ result.add(new ArrayList<>(path)); if(startIndex > nums.length) return; for (int i = startIndex; i < nums.length; i++) { //used[i-1] == 0意味着前一位重复元素之前没有在同一层遍历上使用过,这种情况需要做去重。直接continue,不处理后面的数据即可。 if(i > 0 && nums[i] == nums[i-1] && used[i-1] == 0) continue; path.add(nums[i]); used[i] = 1; backtracking(nums,i+1,used); path.removeLast(); startIndex--; used[i] = 0; } } } class subsets90Test { public static void main(String[] args) { subsets90 example = new subsets90(); int[] nums = {4,4,4,1,4}; List<List<Integer>> result = example.subsetsWithDup(nums); for(List<Integer> levels :result){ System.out.print("["); for(int i : levels){ System.out.print(i+" "); } System.out.println("]"); } } } ```
day24 回溯算法-ip+subsets*2
于 2024-08-11 15:50:36 首次发布