1.复原IP地址
思路:
1.切割问题可以使用回溯搜索法把所有可能性搜索出来。
2.切割字串:[startIndex,i]。
class Solution {
public:
vector<string> result;
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 += 1;
backtracking(s,i + 2,pointNum);
pointNum -= 1;
s.erase(s.begin() + i + 1);
}
else continue;
}
return ;
}
bool isValid(const string& s,int start,int end){
if(start > end) 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;
//因为s是string,所以比较时候需要加‘’,表示数值比较。或者s[i]-'0'>9
num = num * 10 + (s[i] - '0');
if(num > 255) return false;
}
return true;
}
vector<string> restoreIpAddresses(string s) {
result.clear();
backtracking(s,0,0);
return result;
}
};
2.子集
思路:
1.子集问题是找树的所有结点。
2.收获结果时候,每个结点都有我们需要的结果,都要去把这个结果放入结果集中。
每一层递归中都有我们需要的结果。
3.子集是收集树形结构中树的所有结点的结果,而组合问题、分割问题是收集树形结构中的叶子结点的结果。
4.数组中的元素互不相同,不存在去重操作。
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
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();
}
}
vector<vector<int>> subsets(vector<int>& nums) {
path.clear();
result.clear();
backtracking(nums,0);
return result;
}
};
3.子集2
思路:
1.数组中的元素存在相同的元素,但是解集中不能包含重复的子集,所以,关键在于去重操作。
2.去重操作前,一定要对数组排序!
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] == 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();
}
return ;
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
path.clear();
result.clear();
vector<bool> used(nums.size(),false);
sort(nums.begin(),nums.end());//一定要排序。
backtracking(nums,0,used);
return result;
}
};