回溯
组合问题
77. 组合
class Solution {
private:
vector<int> path;
vector<vector<int>> result;
void backtracking(int n, int k, int startIndex)
{
if(path.size() == k) { result.push_back(path); return; }
for(int i=startIndex; i<=n-(k-path.size())+1; ++i)
{
path.push_back(i);
backtracking(n, k, i + 1);
path.pop_back();
}
}
public:
vector<vector<int>> combine(int n, int k) {
path.clear(); result.clear();
backtracking(n, k, 1);
return result;
}
};
216. 组合总和 III
class Solution {
private:
vector<int> path;
vector<vector<int>> result;
void backtracking(int targetSum, int k, int sum, int startIndex)
{
if(sum > targetSum) { return; }
if(path.size() == k) { if(sum == targetSum) result.push_back(path); return; }
for(int i=startIndex; i<=9-(k-path.size())+1; ++i)
{
sum += i;
path.push_back(i);
backtracking(targetSum, k, sum, i + 1);
sum -= i;
path.pop_back();
}
}
public:
vector<vector<int>> combinationSum3(int k, int n) {
path.clear(); result.clear();
backtracking(n, k, 0, 1);
return result;
}
};
17. 电话号码的字母组合
class Solution {
private:
const string letterMap[10] = {
"",
"",
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz",
};
vector<string> result;
string s;
void backtracking(const string& digits, int index)
{
if(digits.size() == index) { result.push_back(s); return; }
int digit = digits[index] - '0';
string letters = letterMap[digit];
for(int i=0; i<letters.size(); ++i)
{
s.push_back(letters[i]);
backtracking(digits, index + 1);
s.pop_back();
}
}
public:
vector<string> letterCombinations(string digits) {
s.clear(); result.clear();
if(digits.size() == 0) { return result; }
backtracking(digits, 0);
return result;
}
};
39. 组合总和
class Solution {
private:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& candidates, int target, int sum, int startIndex)
{
if(sum == target) { result.push_back(path); return; }
for(int i=startIndex; i<candidates.size(); ++i)
{
sum += candidates[i];
path.push_back(candidates[i]);
backtracking(candidates, target, sum, i);
sum -= candidates[i];
path.pop_back();
}
}
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
path.clear(); result.clear();
sort(candidates.begin(), candidates.end());
backtracking(candidates, target, 0, 0);
return result;
}
};
40.组合总和II(很重要)
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& candidates, int target, int sum, int startIndex, vector<bool>& used) {
if (sum == target) {
result.push_back(path);
return;
}
for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) {
if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) {
continue;
}
sum += candidates[i];
path.push_back(candidates[i]);
used[i] = true;
backtracking(candidates, target, sum, i + 1, used);
used[i] = false;
sum -= candidates[i];
path.pop_back();
}
}
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
vector<bool> used(candidates.size(), false);
path.clear();
result.clear();
sort(candidates.begin(), candidates.end());
backtracking(candidates, target, 0, 0, used);
return result;
}
};
切割问题
131. 分割回文串
class Solution {
private:
vector<string> path;
vector<vector<string>> result;
bool isPalindrome(const string& s, int start, int end)
{
while(start < end)
{
if(s[start] != s[end]) { return false; }
start++;
end--;
}
return true;
}
void backtracking(const string& s, int startIndex)
{
if(startIndex >= s.size()) { result.push_back(path); return; }
for(int i=startIndex; i<s.size(); ++i)
{
if(isPalindrome(s, startIndex, i))
{
string str = s.substr(startIndex, i-startIndex+1);
path.push_back(str);
}
else
{
continue;
}
backtracking(s, i+1);
path.pop_back();
}
}
public:
vector<vector<string>> partition(string s) {
path.clear(); result.clear();
backtracking(s, 0);
return result;
}
};
93. 复原 IP 地址
class Solution {
private:
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; }
int num = 0;
for (int i = start; i <= end; i++)
{
if (s[i] > '9' || s[i] < '0') { return false; }
num = num * 10 + (s[i] - '0');
if (num > 255) { return false; }
}
return true;
}
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++;
backtracking(s, i+2, pointNum);
pointNum--;
s.erase(s.begin()+i+1);
}
else
{
break;
}
}
}
public:
vector<string> restoreIpAddresses(string s) {
result.clear();
backtracking(s, 0, 0);
return result;
}
};
子集问题
78. 子集
class Solution {
private:
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();
}
}
public:
vector<vector<int>> subsets(vector<int>& nums) {
path.clear(); result.clear();
backtracking(nums, 0);
return result;
}
};
90. 子集 II
class Solution {
private:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums, int startIndex, vector<bool>& used)
{
result.push_back(path);
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();
}
}
public:
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
vector<bool> used(nums.size(), false);
path.clear(); result.clear();
sort(nums.begin(), nums.end());
backtracking(nums, 0, used);
return result;
}
};
排列问题
491. 递增子序列
class Solution {
private:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums, int startIndex)
{
if(path.size() > 1) { result.push_back(path); }
unordered_set<int> uset;
for(int i=startIndex; i<nums.size(); ++i)
{
if((!path.empty() && nums[i] < path.back()) || uset.find(nums[i]) != uset.end()) { continue; }
uset.insert(nums[i]);
path.push_back(nums[i]);
backtracking(nums, i+1);
path.pop_back();
}
}
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
path.clear(); result. clear();
backtracking(nums, 0);
return result;
}
};
class Solution {
private:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums, int startIndex)
{
if(path.size() > 1) { result.push_back(path); }
int used[201] = {0};
for(int i=startIndex; i<nums.size(); ++i)
{
if((!path.empty() && nums[i] < path.back()) || used[nums[i] + 100] == 1) { continue; }
used[nums[i] + 100] = 1;
path.push_back(nums[i]);
backtracking(nums, i+1);
path.pop_back();
}
}
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
path.clear(); result. clear();
backtracking(nums, 0);
return result;
}
};
46. 全排列
class Solution {
private:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums, vector<bool>& used)
{
if(path.size() == nums.size()) { result.push_back(path); return; }
for(int i=0; i<nums.size(); ++i)
{
if(used[i] == true) { continue; }
used[i] = true;
path.push_back(nums[i]);
backtracking(nums, used);
used[i] = false;
path.pop_back();
}
}
public:
vector<vector<int>> permute(vector<int>& nums) {
path.clear(); result.clear();
vector<bool> used(nums.size(), false);
backtracking(nums, used);
return result;
}
};
47. 全排列 II
class Solution {
private:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums, vector<bool>& used)
{
if(path.size() == nums.size()) { result.push_back(path); return; }
for(int i=0; i<nums.size(); ++i)
{
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) { continue; }
if(used[i] == false)
{
used[i] = true;
path.push_back(nums[i]);
backtracking(nums, used);
used[i] = false;
path.pop_back();
}
}
}
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
path.clear(); result.clear();
vector<bool> used(nums.size(), false);
sort(nums.begin(), nums.end());
backtracking(nums, used);
return result;
}
};