LeetCode93.复原IP地址
题目链接:93. 复原 IP 地址 - 力扣(LeetCode)
思路:
class Solution {
public:
vector<string> result;
//判断合法
bool isIP(string s,int start,int end) {
if(start > end) return false;
if(s[start] == '0' && start != end) return false;//0开头的数字不合法
int num = 0;
for(int i = start;i <= end;i++) {
if(s[i] < '0' || s[i] > '9') return false;
num = num * 10 + (s[i] - '0');
if(num > 255) return false;//大于255不合法
}
return true;
}
void backtracking(string s,int start,int nums) {
if(nums == 3) {//逗点为3时,分割结束
if(isIP(s,start,s.size() - 1)) result.push_back(s);//判断第4个子串合不合法
return ;
}
for(int i = start;i < s.size();i++) {
if(isIP(s,start,i)) {//判断[start,i]区间子串合不合法
s.insert(s.begin() + i + 1,'.');//在i后面插入.
nums++;
backtracking(s,i + 2,nums); //插入.后下一个子串起始位置为i+2
nums--;//回溯
s.erase(s.begin() + 1 + i);//删掉逗点
}
else break;
}
return ;
}
vector<string> restoreIpAddresses(string s) {
backtracking(s,0,0);
return result;
}
};
LeetCode78.子集
思路:
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums, int start) {
result.push_back(path);
if(start >= nums.size()) {
return ;
}
for(int i = start;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;
}
};
子集是收集树形结构中树的所有节点的结果。
而组合问题、分割问题是收集树形结构中叶子节点的结果。
LeetCode90.子集II
思路:
去重先排序,再看相同元素用过没有
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums,int start,vector<bool>& used) {
result.push_back(path);
if(start >= nums.size()) return ;
for(int i = start;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) {
vector<bool> used(nums.size(),false);
sort(nums.begin(),nums.end());
backtracking(nums,0,used);
return result;
}
};