https://leetcode.cn/problems/restore-ip-addresses/description/
28.复原ip地址
好难啊这道题,这道题难在不但需要回溯,还要仔细揣摩题目的意思,设置isValid函数判断数字是否是有效的0-9,同时,数字不能用0开头。
回溯的思想还是用到隔板,这里的隔板就是startIndex那个字母后面的一竖画。首先得判断isValid的返回值,true的时候才不断递归下去,然后在pointNum==3的时候就可以收割结果了。
class Solution {
private:
vector<string>result;
bool isValid(const string&s,int begin,int end)
{
if(begin>end)
return false;
if(s[begin]=='0'&&begin!=end)
return false;
int sum=0;
for(int i=begin;i<=end;i++)
{
if(s[i]>'9'||s[i]<'0')
{return false;}
sum=sum*10+(s[i]-'0');
if(sum>255)
return false;
}
return true;
}
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) {
result.clear();
if(s.size()<4||s.size()>12) return result;
backtracking(s,0,0);
return result;
}
};
78.子集
这道题比较简单,之前的回溯的题是在结果(叶子结点收割),而子集求的是过程中的每一个集合,所以只需在进入函数后先将上一个函数的结果path加入到结果集里面就可以。
class Solution {
private:
vector<int>path;
vector<vector<int>>result;
void backtracking(vector<int>&nums,int startIndex)
{
result.push_back(path);
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) {
path.clear();
result.clear();
backtracking(nums,0);
return result;
}
};
90.子集II
这道题是结合之前有一道题也是重复元素的,思路是一模一样,判断条件还是if(i>startIndex&&nums[i]==nums[i-1]),这一步是树层层面的去重,为了避免树枝层面因为nums[i]==nums[i-1]受到干扰,所以加上限制条件i>startIndex,其余的回溯思想跟前几道题一样。
https://leetcode.cn/problems/subsets-ii/
class Solution {
private:
vector<int>path;
vector<vector<int>>result;
void backtracking(vector<int>&nums,int startIndex)
{
result.push_back(path);
for(int i=startIndex;i<nums.size();i++)
{
if(i>startIndex&&nums[i]==nums[i-1])
continue;
path.push_back(nums[i]);
backtracking(nums,i+1);
path.pop_back();
}
}
public:
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
path.clear();
result.clear();
sort(nums.begin(),nums.end());
backtracking(nums,0);
return result;
}
};