一、LeetCode 93. 复原IP地址
状态:已解决
1.思路
分割字符串做出来了,那么这道题也就很容易想出来,二者本质差不多,都是在进行分割。只是,对分割出的子串的有效性判断不一致了。93题判断一个子串是否有效是根据该字符串转成的int数据是否介于[0,255],以及是否有前缀0来判断的;39题则是判断是否是回文串。另外,这道题对分割出的子串数量有限制,必须为4。因此,直接根据以上变动在39题的代码上得到93题的代码。
2.完整代码
class Solution {
public:
vector<string> path;
vector<string> result;
bool isValid(string& s,int startIndex,int i){
string substrs = s.substr(startIndex,i-startIndex+1);
if(substrs[0]=='0' && substrs.size()>1) return false;
int value = atoi(substrs.c_str());
if(!(0<=value && value<=255)){
return false;
}
return true;
}
void backtracking(string& s,int startIndex,int k){
if(startIndex >= s.size()){
if(k==4){
string temp="";
for(int i=0;i<path.size();i++){
temp += path[i];
temp += ".";
}
temp.pop_back();
result.push_back(temp);
}
return ;
}
for(int i=startIndex;i<s.size();i++){
if(isValid(s,startIndex,i)){
string substrs = s.substr(startIndex,i-startIndex+1);
path.push_back(substrs);
backtracking(s,i+1,k+1);
path.pop_back();
}
else{
continue;
}
}
return;
}
vector<string> restoreIpAddresses(string s) {
backtracking(s,0,0);
return result;
}
};
二、78.子集
题目链接/文章讲解/视频讲解: https://programmercarl.com/0078.%E5%AD%90%E9%9B%86.html状态:已解决
1.思路
这题也就是回溯法的模板题的简单升级,只比模板题多了一点变动。模板题是每次在叶子节点处存数据,而此题在树层处就要存数据,即每条枝干上的每个节点都要存。也就是说,result.push_back(path)要放到终止条件的外部。
2.完整代码
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) {
backtracking(nums,0);
return result;
}
};
三、90.子集II
题目链接/文章讲解/视频讲解: https://programmercarl.com/0090.%E5%AD%90%E9%9B%86II.html状态:已解决
1.思路
这和40题差不多,由于有重复元素,故此题与40题一样都需要去重。区别在于40题存路径的条件是要满足路径各节点值之和等于target,此题没有这个限制,故每个中间路径都要存,这又与78题类似,因此这题实则是78题和40题的结合:40题的去重思路(树枝去重used数组、树层去重nums[i]==nums[i-1])、78题的存路径思路(每条中间路径都要存)。
2.代码实现
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums,int startIndex,vector<int> used){
result.push_back(path);//78题找子集,在于每个中间路径都要存
if(startIndex>=nums.size()){
return ;
}
for(int i=startIndex;i<nums.size();i++){
if(i>0 && nums[i]==nums[i-1] && used[i-1]==0){
continue;
}//40题去重做法,双重去重。
path.push_back(nums[i]);
used[i]=1;
backtracking(nums,i+1,used);
used[i]=0;
path.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(),nums.end());
path.clear();
result.clear();
vector<int> used(nums.size(),0);
backtracking(nums,0,used);
return result;
}
};