LeetCode 93 复原IP地址
题目链接:93
思路:本题也是分割问题。题目确定了分割段数为4段,而割3次就能确定4段。因此,终止条件为分割3次时,判断第4段是否合法,若合法则加入result
。具体的分割操作为在原字符串中加入.
。判断每段地址的合法性:长度不为0,不出现除数字外的其他字符,不含前导0
,小于255。
代码:
class Solution {
public:
vector<string> result;
bool isValid(const string& s, int start, int end) {
if (start > end) return false;
if (s[start] == '0' && start != end) return false;
for (int i=start; i<=end; ++i) {
if (s[i] < '0' || s[i] > '9') return false;
}
if (stol(s.substr(start, end-start+1)) > 255) return false;
return true;
}
void backtracking(string& s, int start, int cnt) {
if (cnt == 3) {
if (isValid(s, start, s.size()-1)) result.push_back(s);
return;
}
for (int i=start; i<s.size(); ++i) {
if (!isValid(s, start, i)) break;
s.insert(s.begin()+i+1, '.');
backtracking(s, i+2, cnt+1);
s.erase(s.begin()+i+1);
}
}
vector<string> restoreIpAddresses(string s) {
result.clear();
if (s.size() < 4 || s.size() > 12) return result;
backtracking(s, 0, 0);
return result;
}
};
LeetCode 78 子集
题目链接:78
思路:相较于组合问题求的是到叶子节点的路径,子集问题就是收集每一个节点的路径。
代码:
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
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) {
path.clear();
result.clear();
backtracking(nums, 0);
return result;
}
};
LeetCode 90 子集 II
题目链接:90
思路:即在有重复求组合的基础上,收集每个节点路径。
代码:
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums, int start) {
result.push_back(path);
if (start == nums.size()) return;
for (int i=start; i<nums.size(); ++i) {
if (i>start && nums[i] == nums[i-1]) continue;
path.push_back(nums[i]);
backtracking(nums, i+1);
path.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
path.clear();
result.clear();
sort(nums.begin(), nums.end());
backtracking(nums, 0);
return result;
}
};