https://leetcode.cn/problems/restore-ip-addresses/
和前面那个回文串差不多,就是找各种方法来切割,然后判断是否合法就行。
class Solution {
public:
bool isValid(string s) {
if(s.length() > 1 && s[0] == '0') return false;
int x = stoi(s);
if (x < 0 || x > 255) return false;
return true;
}
vector result;
vector path;
void backTracking(string s) {
if (s.empty() && path.size() == 4) {
result.push_back(path[0] + '.' + path[1] + '.' + path[2] + '.' + path[3]);
return;
}
if (s.empty()) return;
if (path.size() == 4) return;
for (int i = 0; i < (s.length() < 3 ? s.length() : 3); i++) {
string left(s.begin(), s.begin() + i + 1);
if (!isValid(left)) continue;
path.push_back(left);
string right(s.begin() + i + 1, s.end());
backTracking(right);
path.pop_back();
}
}
vector restoreIpAddresses(string s) {
backTracking(s);
return result;
}
};
https://leetcode.cn/problems/subsets/
这道题我一开始想的很复杂
思路是这样的,先限定一个path大小的值k,回溯得到大小为k的所有子集添加到result中,然后依次从k=0到k=nums.size()全部回溯一遍
class Solution {
public:
vector> result;
vector path;
void backTracking(vector nums, int k) {
//k : 还需要再path中添加的元素数量
if (k == 0) {
result.push_back(path);
return;
}
if (nums.empty()) {
return;
}
for (int i = 0; i < nums.size(); i++) {
//i : 添加到path中的元素位置
path.push_back(nums[i]);
vector nums2(nums.begin() + i + 1, nums.end());
backTracking(nums2, k - 1);
path.pop_back();
}
}
vector> subsets(vector& nums) {
for (int i = 0; i <= nums.size(); i++) {
backTracking(nums, i);
}
return result;
}
};
后面发现其实就正常的回溯,只不过收集的条件从path大小达到要求改为每一步都收集……
class Solution {
public:
vector> result;
vector path;
void backTracking(vector nums, int cur) {
result.push_back(path);
for(int i = cur; i < nums.size(); i++){
path.push_back(nums[i]);
backTracking(nums, i + 1);
path.pop_back();
}
}
vector> subsets(vector& nums) {
backTracking(nums, 0);
return result;
}
};
直接操作数组:
class Solution {
public:
vector> result;
vector path;
void backTracking(vector& nums) {
result.push_back(path);
if (nums.empty()) return;
for(int i = 0; i < nums.size(); i++){
path.push_back(nums[i]);
vector nums2(nums.begin() + i + 1, nums.end());
backTracking(nums2);
path.pop_back();
}
}
vector> subsets(vector& nums) {
backTracking(nums);
return result;
}
};
https://leetcode.cn/problems/subsets-ii/
和上面的子集问题差不多,但是多了一个去重的需求
class Solution {
public:
vector> result;
vector path;
void backTracking(vector nums, int cur) {
result.push_back(path);
if (cur >= nums.size()) return;
for(int i = cur; i < nums.size(); i++) {
if (i > cur && nums[i] == nums[i - 1]) continue;
path.push_back(nums[i]);
backTracking(nums, i + 1);
path.pop_back();
}
}
vector> subsetsWithDup(vector& nums) {
sort(nums.begin(), nums.end());
backTracking(nums, 0);
return result;
}
};
直接操作数组:
class Solution {
public:
vector> result;
vector path;
void backTracking(vector nums) {
result.push_back(path);
if (nums.empty()) return;
for(int i = 0; i < nums.size(); i++){
if (i > 0 && nums[i] == nums[i - 1]) continue;
path.push_back(nums[i]);
vector nums2(nums.begin() + i + 1, nums.end());
backTracking(nums2);
path.pop_back();
}
}
vector> subsetsWithDup(vector& nums) {
sort(nums.begin(), nums.end());
backTracking(nums);
return result;
}
};
使用set去重:
class Solution {
public:
vector> result;
vector path;
void backTracking(vector nums, int cur) {
result.push_back(path);
if (cur >= nums.size()) return;
unordered_set set;
for(int i = cur; i < nums.size(); i++) {
if (!set.empty() && set.find(nums[i]) != set.end()) continue;
set.insert(nums[i]);
path.push_back(nums[i]);
backTracking(nums, i + 1);
path.pop_back();
}
}
vector> subsetsWithDup(vector& nums) {
vector used(nums.size(), false);
sort(nums.begin(), nums.end());
backTracking(nums, 0);
return result;
}
};
使用used去重:
class Solution {
public:
vector> result;
vector path;
vector used = {false};
void backTracking(vector nums, int cur) {
result.push_back(path);
if (cur >= nums.size()) return;
for(int i = cur; i < nums.size(); i++) {
if (i >= 1 && nums[i] == nums[i-1] && used[i-1] == false) continue;
path.push_back(nums[i]);
used[i] = true;
backTracking(nums, i + 1);
path.pop_back();
used[i] = false;
}
}
vector> subsetsWithDup(vector& nums) {
sort(nums.begin(), nums.end());
backTracking(nums, 0);
return result;
}
};