93.复原IP地址
思路:这个题和131.分割回文串一样都是对字符串进行分割,只不过这个子字符串判断时是看是不是0-225之间的数字。
回溯三部曲:
1、递归函数参数:全局变量:String数组result存放结果集。 递归函数参数:原字符串;startIndex,因为切割过的地方不能重复切割,和组合问题是一样的;变量pointNum,记录添加逗点的数量。
2、终止条件:终止条件和131.分割回文串 (opens new window)不同,本题明确要求只会分成4段,所以不能用切割线切到最后作为终止条件,而是分割的段数作为终止条件。pointNum表示逗点数量,pointNum为3说明字符串分成了4段了。
3、单层搜索的逻辑:在for (int i = startIndex; i < s.size(); i++)循环中,我们定义了起始位置startIndex,那么 [startIndex, i] 就是要截取的子串。首先判断这个子串是不是在0-225之间且首位不为0,如果是,就加入path中,path用来记录切割过的回文子串。
代码如下:
class Solution {
List<String> result=new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
StringBuilder sb=new StringBuilder(s);
backTracking(sb,0,0);
return result;
}
public void backTracking(StringBuilder sb,int startIndex,int pointNum){
if(pointNum==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,'.');
backTracking(sb,i+2,pointNum+1);
sb.deleteCharAt(i+1);
}else break;
}
}
public boolean isValid(StringBuilder sb,int start,int end){
if(start>end) 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;
}
}
78.子集
思路:感觉和组合问题差不多,关键问题在于如何确定递归的深度。一个很清晰的思路:组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点,所以在遍历树时将所有节点进行记录即可。
回溯三部曲:
1、递归函数参数:全局变量:数组result存放结果集,path存放遍历到的每个节点。 递归函数参数:原数组;startIndex,和组合问题一样无序不能重复。
2、终止条件:startIndex遍历完数组,大于等于数组的长度;可以不需要加终止条件,因为startIndex >= nums.length,本层for循环本来也结束了。
3、单层搜索的逻辑:在for (int i = startIndex; i < s.size(); i++)循环中,我们定义了起始位置startIndex,那么 [startIndex, i] 就是要截取的子串。首先判断这个子串是不是在0-225之间且首位不为0,如果是,就加入path中,path用来记录切割过的回文子串。
代码如下:
class Solution {
List<List<Integer>> result=new ArrayList<>();
List<Integer> path=new LinkedList<>();
public List<List<Integer>> subsets(int[] nums) {
backTracking(nums,0);
return result;
}
public void backTracking(int[] nums, int startIndex){
result.add(new ArrayList(path));
for(int i=startIndex;i<nums.length;i++){
path.add(nums[i]);
backTracking(nums,i+1);
path.removeLast();
}
}
}
90.子集II
思路:这个题和40.组合总和II思路类似,即原始数组中存在重复元素,这个时候为了保证最终结果不重复,即同一层内不能有重复的元素。
对数组排序,在循环中加一个条件,如果该元素与前一个元素相同,则continue。
代码如下:
class Solution {
List<List<Integer>> result=new ArrayList<>();
List<Integer> path=new LinkedList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
backTracking(nums,0);
return result;
}
public void backTracking(int[] nums,int startIndex){
result.add(new ArrayList(path));
for(int i=startIndex;i<nums.length;i++){
if(i>startIndex && nums[i]==nums[i-1]) continue;
path.add(nums[i]);
backTracking(nums,i+1);
path.removeLast();
}
}
}
标签:nums,int,day24,Part03,startIndex,子集,result,sb,path
From: https://blog.csdn.net/m0_51007517/article/details/142388005