一、题目打卡
1.1 复原IP地址
题目链接:. - 力扣(LeetCode)
class Solution {
private:
bool check(string& s){
// if(s[0] && s[0] == '0') return false;
int ind = 0;
int sum = 0;
while(ind < s.size()){
sum = 10 * sum + (s[ind++] - '0');
}
// cout << sum << "------"; // check if the code is correct
return 0 <= sum && sum <= 255;
}
public:
string path;
vector<string> res;
int times = 0;
void backTrack(string &s, int startInd){
if(startInd == s.size() && times == 4){
res.push_back(path);
return;
}
// 提前剪枝
// if(s[startInd] == '0') return;
// if(s[startInd] == '0' && startInd < s.size() && s[startInd + 1] != '0') return;
if(times > 4) return;
string tmp;
for(int i = startInd; i < s.size(); i++){
tmp += s[i];
if(tmp.size() > 4 || (tmp.size() > 1 && tmp[0] == '0')) return;
if(check(tmp)){
times++;
path = path + tmp + '.';
backTrack(s,i+1);
path.pop_back();
// while((!path.empty() && path.back() != '.') || !path.empty()){
// path.pop_back();
// }
times--;
int i_ = tmp.size();
while(i_--) path.pop_back();
}
}
}
vector<string> restoreIpAddresses(string s) {
if(s.size() > 12) return {};
backTrack(s,0);
for(auto& it : res){ // 这里注意要引用
it.pop_back();
}
return res;
}
};
思路其实和分割回文那个题目差不多,但是我了一些评论区的答案,感觉写的更简洁一点,但是我不想再优化了(摆烂.jpg)。
1.2 子集
题目链接:. - 力扣(LeetCode)
class Solution {
public:
vector<int> path;
vector<vector<int>> res;
void backtrack(vector<int>& nums, int startInd){
res.push_back(path);
if(startInd >= nums.size()) return;
for(int i = startInd; i < nums.size();i++){
path.push_back(nums[i]);
backtrack(nums, i + 1);
path.pop_back();
}
}
vector<vector<int>> subsets(vector<int>& nums) {
// res.emplace_back(vector<int>{});
backtrack(nums,0);
return res;
}
};
思想其实和组合差不多,但是这个主要不一样的是终止条件,其实就是用索引大于所给数组的 size ,而且这时候注意的是,res 的插入操作是在每一次回溯都会进行的,因为这里处理的是子集,只要是插入到 path 中的内容,本质上都是子集,而且这样放到回溯结束后第一个执行的语句,正好也处理好了空集的情况。
1.3 子集II
题目链接:. - 力扣(LeetCode)
class Solution {
public:
vector<int> path;
vector<vector<int>> res;
void recur(vector<int> &nums, int startInd){
res.push_back(path);
if(startInd == nums.size()) return;
for(int i = startInd ; i < nums.size() ; i++){
if(i > startInd && nums[i] == nums[i-1]) continue;
path.push_back(nums[i]);
recur(nums, i + 1);
path.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(),nums.end());
recur(nums,0);
return res;
}
};
只需要在上一个题目的基础上添加两行代码就可以解决:首先因为涉及到去重,所以需要对目标的 nums 进行排序,其次就是当同一层(也就是横向)遇到重复元素的时候,需要进行去重的处理。