3.判断子串是否合法:
-
最后就是在写一个判断段位是否是有效段位了。主要考虑到如下三点:
- 段位以0为开头的数字不合法
- 段位里有非正整数字符不合法
- 段位如果大于255了不合法
import java.util.ArrayList; import java.util.List; public class RestoreIPAddresses { List<String> result = new ArrayList<>(); public List<String> restoreIpAddresses(String s) { if(s.length() > 12)return result;// 算是剪枝了 backTracking(s,0,0); return result; } // startIndex: 搜索的起始位置, pointNum:添加逗点的数量 private void backTracking(String s, int startIndex, int pointNum){ if(pointNum == 3){// 逗点数量为3时,分隔结束 // 判断第四段⼦字符串是否合法,如果合法就放进result中 if(isValid(s, startIndex, s.length()-1)){ result.add(s); } return; } for(int i = startIndex; i < s.length(); i++){ if(isValid(s, startIndex, i)){ /**在str的后面插入一个逗点 * 举例:s="245132" * 1.假设在5后面插入逗点,此时i的位置在5 * 2.s.substring[0, i + 1)取到了245(分割区间为左闭右开) * 3.s.substring[i + 1]取到了132 */ s = s.substring(0,i + 1) + "." + s.substring(i + 1);//在str的后⾯插⼊⼀个逗点 pointNum +=1;//pointNum++; /** * 插入逗点之后下一个子串串的起始位置为i+2 * 举例:s="245.132" i位置在5,i+2位置在1 */ backTracking(s, i + 2, pointNum);// 插⼊逗点之后下⼀个⼦串的起始位置为i+2 /** 回溯删掉逗点 * 举例:s="245.132" ,此时i的位置在5 * 1.s.substring[0, i + 1)取到了245(分割区间为左闭右开) * 2.s.substring[i + 1]取到了132 */ // 回溯 s = s.substring(0, i + 1) + s.substring(i + 2);// 回溯删掉逗点 pointNum -= 1;//pointNum--; }else{ break;// 不合法,直接结束本层循环 } } } // 判断字符串s在左闭⼜闭区间[start, end]所组成的数字是否合法 private boolean isValid(String s, int start, int end){ if(start > end){ return false; } if(s.charAt(start) == '0' && start !=end){// 0开头的数字不合法 return false; } int num = 0; for (int i = start; i <= end; i++){ if(s.charAt(i) > '9' || s.charAt(i) < '0'){ // 遇到⾮数字字符不合法 return false; } /* num*10表示放大10倍,如12变成120,p[i]-'0'表示数字0~9,如'7'-'0'=7 num=num*10+p[i]-'0' ;表示将原来的数num放大10倍再加上当前的数。 */ num = num * 10 + (s.charAt(i) - '0'); if(num > 255){// 如果⼤于255了不合法 return false; } } return true; } }
import java.util.ArrayList; import java.util.LinkedList; import java.util.List; public class Subsets { List<List<Integer>> result = new ArrayList<>(); 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(); } } }
import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; public class SubsetsII { List<List<Integer>> result = new ArrayList<>(); LinkedList<Integer> path = new LinkedList<>(); boolean used; public List<List<Integer>> subsetsWithDup(int[] nums) { Arrays.sort(nums); used = false; backTracking(nums,0,false); return result; } private void backTracking(int[]nums, int startIndex, boolean used){ result.add(new ArrayList<>(path)); if(startIndex >= nums.length)return; for(int i = startIndex; i < nums.length; i++){ if(i > 0 && nums[i] == nums[i - 1] && !used){ continue; } path.add(nums[i]); used = true; backTracking(nums, i + 1, used); path.removeLast(); used = false; } } }