93.复原IP地址
- 如何进行树的搭建?
- 不需要path了,用原字符串承接就可以,每找到一个合法段,就在后边添加“.”下次回溯的起始点i+2就可以了。
- 如何验证该位置有效?
- 对于0占首位的数字:if(s[begin]==‘0’ && begin!=end)
- 对于大于255的:不要所有的数加完再判断,这样比如‘99999999999999’,最后num=99999999999,int和long都放不下。加一次就判断一次,用Int num就放下了。
- 如何分割字符串?begin:start index;end:i。左闭右闭
- 回溯法步骤
- 终止条件,前三个占位都合法,到叶子结点了,即pointNum=3的时候,看是否合法
- 确定参数:需要startIndex指针,和pointNum
- 回溯逻辑:当前合法,放入,回溯,弹出。当前不合法continue。
class Solution {
public:
vector<string> result;
bool isValid(string& s,int begin, int end){//左闭右闭
if(begin>end){
return false;
}
if(s[begin]=='0' && begin!=end){
return false;
}
int num=0;
for(int i=begin;i<=end;i++){
if(s[i]>='0' && s[i]<='9'){
num=num*10+(s[i]-'0');
if(num>255) return false;
}
else{
return false;
}
}
return true;
//if(num<=255){
//return true;
//}
//else
//return false;
}
void backtracking(string& s,int indexStart,int pointNum){
if(pointNum==3){
if(isValid(s,indexStart,s.size()-1))
result.push_back(s);
}
for(int i=indexStart;i<s.size();i++){
if(isValid(s,indexStart,i)){
s.insert(s.begin()+i+1,'.');
pointNum++;
backtracking(s,i+2,pointNum);//keyouhua
s.erase(s.begin()+i+1);
pointNum--;
}
else
continue;
}
}
vector<string> restoreIpAddresses(string s) {
result.clear();
backtracking(s,0,0);
return result;
}
};
78.子集
- 子集:搜集所有结点
- 所以回溯方法中终止条件可以不写了,for循环完了就return了。
- 分割组合:搜索符合条件的树枝
- 把result.push_back()放到迭代开头。这样会放入[ ]。
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums, int indexStart){
result.push_back(path);
//if(indexStart>=nums.size())
//return;
for(int i=indexStart;i<nums.size();i++){
path.push_back(nums[i]);
backtracking(nums,i+1);
path.pop_back();
}
}
vector<vector<int>> subsets(vector<int>& nums) {
result.clear();
backtracking(nums,0);
return result;
}
};
90.子集II
跟之前多种组合问题一样,这道题变成了集合中有重复元素,所以需要used数组,在树层上去重。
如果nums[i-1]=nums[i]且nums[i-1]为true,那这是树枝上的【1,2,2】情况
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums, int indexStart, vector<bool>& used){
result.push_back(path);
for(int i=indexStart;i<nums.size();i++){
if(i>0 && nums[i-1]==nums[i] && used[i-1]==false){
continue;
}
path.push_back(nums[i]);
used[i]=true;
backtracking(nums,i+1,used);
path.pop_back();
used[i]=false;
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
result.clear();
vector<bool> used(nums.size(),false);
sort(nums.begin(),nums.end());
backtracking(nums,0,used);
return result;
}
};