[leetcode-078] 求子集 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums)
{
if(nums.empty())
return {};
vector<vector<int>> res;
vector<int> item;
subsetsCore(res, nums, item, 0);
return res;
}
void subsetsCore(vector<vector<int>>& res, vector<int>& nums, vector<int>& item, int index)
{
res.push_back(item);
for(int i = index; i < nums.size(); ++i)
{
item.push_back(nums[i]);
subsetsCore(res, nums, item, i + 1);
item.pop_back();
}
}
};
[leetcode-077] 组合 给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。
class Solution {
public:
vector<vector<int>> combine(int n, int k)
{
vector<vector<int>> res;
vector<int> item;
combineCore(n, k, res, item, 1);
return res;
}
void combineCore(int n, int k, vector<vector<int>>& res, vector<int>& item, int index)
{
if(item.size() == k)
{
res.push_back(item);
return;
}
for(int i = index; i <= n; ++i)
{
item.push_back(i);
combineCore(n, k, res, item, i + 1);
item.pop_back();
}
}
};
[leetcode-046] 全排列 给定一个 没有重复 数字的序列,返回其所有可能的全排列。
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums)
{
vector<vector<int>> res;
vector<int> item;
permuteCore(nums, res, item);
return res;
}
void permuteCore(vector<int>& nums, vector<vector<int>>& res, vector<int>& item)
{
if(item.size() == nums.size())
{
res.push_back(item);
return;
}
for(int i = 0; i < nums.size(); ++i)
{
if(find(item.begin(), item.end(), nums[i]) != item.end())
continue;
item.push_back(nums[i]);
permuteCore(nums, res, item);
item.pop_back();
}
}
};
[leetcode-047] 全排列II 给定一个 有重复 数字的序列,返回其所有可能的全排列。
class Solution {
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>> res;
vector<int> item;
vector<bool> used(nums.size(), false);
sort(nums.begin(), nums.end());
DFS(nums, res, item, used);
return res;
}
private:
void DFS(vector<int>& nums, vector<vector<int>>& res, vector<int> item, vector<bool> used) {
if(item.size() == nums.size()) {
res.push_back(item);
return;
}
for(int i = 0; i < nums.size(); ++i) {
if(used[i]) {
continue;
}
if(i > 0 && used[i - 1] && nums[i] == nums[i - 1]) { //是否在访问多个重复的字符
continue;
}
used[i] = true;
item.push_back(nums[i]);
DFS(nums, res, item, used);
used[i] = false;
item.pop_back();
}
}
};
[剑指offer-38] 字符串排列--有重复字符
class Solution {
public:
vector<string> permutation(string s) {
vector<bool> used(s.size(), false);
vector<string> res;
string path;
sort(s.begin(), s.end());
DFS(s, res, used, path);
return res;
}
void DFS(string s, vector<string>& res, vector<bool>& used, string& path) {
if(path.size() == s.size()) {
res.push_back(path);
return;
}
for(int i = 0; i < s.size(); ++i) {
if(used[i]) {
continue;
}
if(i > 0 && used[i - 1] && s[i] == s[i - 1]) {
continue;
}
used[i] = true;
path += s[i];
DFS(s, res, used, path);
used[i] = false;
path = path.substr(0, path.size() - 1);
}
}
};
[leetcode-39]数组总和
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
**此处在递归中加入的index可以保证得到的路径不重复。类比[78],此处的index在递归的时候并未加1,因为数字可以重复选取。
class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target)
{
vector<vector<int>> res;
vector<int> item;
combSumCore(candidates, target, res, item, 0);
return res;
}
void combSumCore(vector<int>& candidates, int target, vector<vector<int>>& res, vector<int>& item, int index)
{
if(accumulate(item.begin(), item.end(), 0) > target)
return;
if(accumulate(item.begin(), item.end(), 0) == target)
res.push_back(item);
for(int i = index; i < candidates.size(); ++i)
{
item.push_back(candidates[i]);
combSumCore(candidates, target, res, item, i);
item.pop_back();
}
}
};
![[1, 2, 4] target = 4](https://i-blog.csdnimg.cn/blog_migrate/a2b708fa2b44df5877e437d4ed78b5a3.png)
[leetcode-40]数组总和
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> combinationSum2(vector<int>& candidates, int target)
{
vector<int> item;
sort(candidates.begin(), candidates.end());
combinationSumCore(candidates, target, item, 0);
return res;
}
void combinationSumCore(vector<int>& candidates, int target, vector<int>& item, int index)
{
if(accumulate(item.begin(), item.end(), 0) > target)
return;
if(accumulate(item.begin(), item.end(), 0) == target)
res.push_back(item);
for(int i = index; i < candidates.size(); ++i)
{
if(i > index && candidates[i] == candidates[i - 1])
continue;
item.push_back(candidates[i]);
combinationSumCore(candidates, target, item, i + 1);
item.pop_back();
}
}
};
[leetcode-797] 所有可能的路径
class Solution {
public:
vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
vector<vector<int>> res;
vector<int> item{0};
DFS(graph, res, item, 0);
return res;
}
void DFS(vector<vector<int>>& graph, vector<vector<int>>& res, vector<int>& item, int node) {
if(item.size() > 0 && graph.size() - 1 == item[item.size() - 1]) {
res.push_back(item);
return;
}
for(int i = 0; i < graph[node].size(); ++i) {
item.push_back(graph[node][i]);
DFS(graph, res, item, graph[node][i]); //此处的node参数为获取到的下一个节点的值
item.pop_back();
}
}
};
[leetcode-17] 电话号码字母组合
class Solution {
public:
vector<string> letterCombinations(string digits) {
if(digits.empty()) {
return {};
}
map<char, string> mp;
mp['2'] = "abc";
mp['3'] = "def";
mp['4'] = "ghi";
mp['5'] = "jkl";
mp['6'] = "mno";
mp['7'] = "pqrs";
mp['8'] = "tuv";
mp['9'] = "wxyz";
vector<string> res;
string path;
DFS(digits, res, path, 0, mp);
return res;
}
void DFS(string digits, vector<string>& res, string& path, int index, map<char, string> mp) {
if(path.size() == digits.size()) {
res.push_back(path);
return;
}
for(int i = 0; i < mp[digits[index]].size(); ++i) {
path += mp[digits[index]][i];
DFS(digits, res, path, index + 1, mp);
path = path.substr(0, path.size() - 1);
}
}
};
[剑指offer - 034] 二叉树中和为某值的路径
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int target) {
if(!root) {
return {};
}
vector<vector<int>> res;
vector<int> item;
DFS(root, target, res, item);
return res;
}
void DFS(TreeNode* root, int target, vector<vector<int>>& res, vector<int>& item) {
if(root) {
item.push_back(root->val);
}
if(accumulate(item.begin(), item.end(), 0) == target && root->left == nullptr && root->right == nullptr) {
res.push_back(item);
}
if(root->left) {
DFS(root->left, target, res, item);
}
if(root->right) {
DFS(root->right, target, res, item);
}
item.pop_back();
}
};