93.复原IP地址
题目链接:93.复原IP地址
文章讲解:代码随想录|93.复原IP地址
思路
和131.分割回文串类似
左半部分满足条件,就添加’.',然后继续递归右半部分
不满足条件就直接跳过这个for循环遍历
递归结束条件:用pointSum记录加了几个点,加了三个后判断一下剩下的是否满足条件,满足就加入result
代码
class Solution {
public:
vector<string> result;
bool isValid(string& s, int start, int end){
if(end < start) return false;
if(s[start] == '0' && start != end) return false;
int num = 0;
for(int i = start; i <= end; i++){
if(s[i] > '9' || s[i] < '0'){
return false;
}
num = num * 10 + s[i] - '0';
if(num > 255) return false;
}
return true;
}
void backtracking(string& s, int startIndex, int pointSum){
if(pointSum == 3){
if(isValid(s, startIndex, s.size() - 1)){
result.push_back(s);
}
}
for(int i = startIndex; i < s.size(); i++){
if(isValid(s, startIndex, i)){
s.insert(s.begin() + i + 1, '.');
pointSum += 1;
backtracking(s, i + 2, pointSum);
pointSum -= 1;
s.erase(s.begin() + i + 1);
}else break;
}
}
vector<string> restoreIpAddresses(string s) {
backtracking(s, 0, 0);
return result;
}
};
78.子集
题目链接:78.子集
文章讲解:代码随想录|78.子集
思路
如果把 子集问题、组合问题、分割问题都抽象为一棵树的话,那么组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点
终止条件:剩余集合为空,也就是startIndex大于数组的长度(其实也可以不加终止条件,因为for循环中本来就是startIndex >= nums.size()停止的,每次递归的下一层就是从i+1开始的)
代码
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums, int startIndex) {
result.push_back(path); // 收集子集,要放在终止添加的上面,否则会漏掉自己
if (startIndex >= nums.size()) { // 终止条件可以不加
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;
}
};
0.子集II
题目链接:90.子集II
文章讲解:代码随想录|90.子集II
思路
40.组合总和II + 78.子集
代码
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums, int startIndex, vector<bool>& used){
result.push_back(path);
if(startIndex >= nums.size()){
return;
}
for(int i = startIndex; 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);
used[i] = false;
path.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
vector<bool> used(nums.size(), false);
sort(nums.begin(), nums.end());
backtracking(nums, 0 , used);
return result;
}
};