复原IP地址
题目链接: 力扣
这题和昨天的分割回文串很相似
返回条件:
当记录在path中的点数超过4时,直接return
当字符串处理到结尾 index = s.size() 且path中的点数等于4时,收集结果
在单层遍历for循环中,注意判断当前字符是否合法(是否超过三位数,是否大于255或小于0,是否是两位数却第一位是0),不合法时,直接continue;
其余的套模板即可。
class Solution {
public:
vector<string> restoreIpAddresses(string s) {
if(s.size()<4 || s.size() > 12) //剪枝
return result;
backtracking(s, 0);
return result;
}
string path="";
vector<string> result;
void backtracking(string s, int index)
{
if(count(path.begin(), path.end(),'.') > 4)
return;
if(index == s.size() && count(path.begin(), path.end(),'.') == 4)
{
result.push_back(path.substr(0,path.size()-1));
return;
}
for(int i = index ;i<s.size();i++)
{
if((i-index+1)>3) //超过三位数 不玩了
continue;
string tempstr = s.substr(index,i-index+1);
int temp = stoi(tempstr);
if(tempstr.size() > 1 && tempstr.front()=='0') //字符串位数大于1,第一位却是0,也不玩了
continue;
if(temp<=255 && temp>=0)
{
path+= tempstr;
path+=".";
}
else
continue; //数不在0~255范围内 也不玩了
backtracking(s, i+1);
int subsize = tempstr.size();
while(subsize) //去除数字
{
path.pop_back();
subsize--;
}
path.pop_back(); //去除点
}
}
};
子集
题目链接: 力扣
这题属于模板题 ,子集也是一种组合问题,它的集合是无序的
也就是说,遍历这个树的时候,把所有节点记录下来,就是子集集合。即每次遍历,都把Path的值赋给result:
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
backtracking(nums, 0);
return result;
}
vector<int> Path;
vector<vector<int>> result;
void backtracking(vector<int>& nums, int index)
{
result.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();
}
}
};
子集II
题目链接:力扣
这一题和上一题的区别在于,nums中可能会包含重复元素,但是解集中不可以包含重复子集。
所以要做到树层去重,这里去重的逻辑和组合中去重的逻辑是一样的,采用一个used数组来记录元素是否被访问。
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {
continue;
}
这里used[i-1]=false 说明以上一个结点为根进行的遍历已经遍历完了。
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);
sort(nums.begin(), nums.end()); // 去重需要排序
backtracking(nums, 0, used);
return result;
}
};
也可以直接用index来进行去重,去重逻辑为:
if(i>index && nums[i]==nums[i-1]) //!!!去重逻辑
continue;