for循是遍历层,而baktracking遍历树枝
class Solution {
private:
vector<string> result;
bool isValid(const string& s,int start,int end){
if(start>end) return false;
if(s[start]=='0'&&start!=end) return false;
int num=0;
for(int i=start;i<=end;i++){
//这里是比较字符串的’9‘,而不能写成9;
if(s[i]>'9'||s[i]<'0'){
return false;
}
num=num*10+(s[i]-'0');
if(num>255) {
return false;
}
}
return true;
}
//pointNum记录.的个数
void backtracking(string& s,int startIndex,int pointNum){
//终止条件是已经有三个.此时需要判断最后一段字符串是否合法
if(pointNum==3){
if(isValid(s,startIndex,s.size()-1)){
result.push_back(s);
}
return;
}
for(int i=startIndex;i<s.size();i++){
if(isValid(s,startIndex,i)){
//如果合法添加一个.
s.insert(s.begin()+i+1,'.');
pointNum++;
backtracking(s,i+2,pointNum);
pointNum--;
s.erase(s.begin()+i+1);
}
else break;// 不合法,直接结束本层循环
}
}
public:
vector<string> restoreIpAddresses(string s) {
if (s.size() < 4 || s.size() > 12) return result;
backtracking(s,0,0);
return result;
}
};
78. 子集这道题就是搜集所有节点,包括了空节点,思路很简单,但是要注意在回溯时要先收集结果,以防漏掉自身,代码中这点也标注了。代码随想录解析
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums,int startIndex){
result.push_back(path);// 收集子集,要放在终止添加的上面,否则会漏掉自己
//这个终止条件可以不写,因为for循环结束,也就结束了
if(startIndex>=nums.size()){
//result.push_back(path);
return;
}
for(int i=startIndex;i<nums.size();i++){
path.push_back(nums[i]);
backtracking(nums,i+1);
path.pop_back();
}
}
public:
vector<vector<int>> subsets(vector<int>& nums) {
result.clear();
path.clear();
backtracking(nums,0);
return result;
}
};
90. 子集 II 本题数组有重复,但要求结果不重复,和之前做的40.组合总和II一样,需要一个used数组来判断相同的是层还是树枝,层的used[i-1]为(false)->coninue,树枝的used[i-1]为(true)->backtracing,第一次写反了没通过,现在狠狠记住了。这次代码是自己写的,棒。代码随想录解析
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums,int startIndex,vector<bool>& used){
result.push_back(path);
for(int i=startIndex;i<nums.size();i++){
//这里的判断层和树枝的条件不要写反了
if(i>0&&nums[i]==nums[i-1]&&used[i-1]==false){
continue;
}
path.push_back(nums[i]);
used[i]=true;
backtracking(nums,i+1,used);
used[i]=false;
path.pop_back();
}
}
public:
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
vector<bool> used(nums.size(),false);
backtracking(nums,0,used);
return result;
}
};