93.复原IP地址
细节:
1.判断ip是否有效时的条件很重要。s[left]=='0'&&left!=right 保证第一个为o的同时,后面还有其他数,因此不合法。011等。
2.递归时的参数。
class Solution {
public:
vector<string> res;
void backtracking(string s,int count,int index){
if(count==3){
if(judge(s,index,s.size()-1)){
res.push_back(s);
}
return; //'.'数超过三,直接判断并且结束这层递归
}
for(int i=index;i<s.size();i++){
if(judge(s,index,i)){
count++;
s.insert(s.begin()+i+1,'.');
backtracking(s,count,i+2);
//i+2由于中间+'.',下层递归中间空一个值
s.erase(s.begin()+i+1);
count--;
}
else{
break;
}
}
}
bool judge(const string& s,int left,int right){
int val=0;
if( left>right||s[left]=='0'&&left!=right) return false;
for(int i=left;i<=right;i++){
if(s[i]<'0'||s[i]>'9')
{
return false;
}
val=val * 10 + (s[i]-'0');
if(val>255){
return false;
}
}
return true;
}
vector<string> restoreIpAddresses(string s) {
if(s.size()>12||s.size()<4) return res;
backtracking(s,0,0);
return res;
}
};
78.子集
由于不能包含重复的子集,所以我们不能每次从0开始。
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
void backtracking(vector<int> &nums,int index){
res.push_back(path);
//下面条件可有可无
if(index>nums.size()){
return;
}
for(int i=index;i<nums.size();i++){
path.push_back(nums[i]);
backtracking(nums,i+1);
path.pop_back();
}
}
vector<vector<int>> subsets(vector<int>& nums) {
backtracking(nums,0);
return res;
}
};
90.子集II
这题包含重复元素,所以和上面的区别是我们需要去重,将元素先排序。
去重时,条件很重要。i>0后,才能进行前后项的比较。
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
void backtracking(vector<int> &nums,int index,vector<bool>& used){
res.push_back(path);
for(int i=index;i<nums.size();i++){
if(i>0 && nums[i]==nums[i-1] &&used[i-1]==false)
{
continue;
}
used[i]=true;
path.push_back(nums[i]);
backtracking(nums,i+1,used);
path.pop_back();
used[i]=false;
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<bool> used(nums.size(),false);
backtracking(nums,0,used);
return res;
}
};