回溯问题
46. 全排列
全排列问题:
path
递归终止条件:path中是否已存储所有元素;
for循环处理节点集合:used=0未被使用的元素
cpp
class Solution {
public:
vector<int> path;
vector<vector<int>> res;
void backtracking(vector<int>& nums,vector<bool>& used) {
if(path.size() == nums.size()){
res.push_back(path);
return;
}
for(int i=0;i<nums.size();i++) {
if(used[i]==true)
continue;
path.push_back(nums[i]);
used[i]=true;
backtracking(nums,used);
used[i]=false;
path.pop_back();
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<bool> used(nums.size(),false);
backtracking(nums,used);
return res;
}
};
78. 子集
子集问题:
每个集合都需要存储到res中,
递归终止条件:可以省略,startIndex下标到达数组末尾 与for循环的条件判断一致
for循环处理的元素集合,startIndex-数组最后一个元素
cpp
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
void backtracking(vector<int>& nums,int startIndex) {
res.push_back(path);
for(int i=startIndex;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 res;
}
};
17. 电话号码的字母组合
这个题根据digits中给出的数字字符,从而锁定对应的字符串,对字符串中的字母进行组合,前面复习过两遍,对这个题的印象还不是很清晰,故再写一次题解:
cpp
class Solution {
const string strSet[10] = {
"",
"",
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz"
};
public:
string s;
vector<string> res;
void backtracking(const string& digits,int index) {
if(index == digits.size()) {
res.push_back(s);
return;
}
int digit = digits[index]-'0';
string str = strSet[digit];
for(int i=0;i<str.size();i++) {
s.push_back(str[i]);
backtracking(digits,index+1);
s.pop_back();
}
}
vector<string> letterCombinations(string digits) {
if(digits.size()==0)
return res;
backtracking(digits,0);
return res;
}
};
39. 组合总和
元素可以多次使用,下一次元素集合的开始位置可以还是startIndex
cpp
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
void backtracking(vector<int>& candidates,int target,int sum,int startIndex) {
if(sum > target)
return;
if(sum == target) {
res.push_back(path);
return;
}
for(int i=startIndex;i<candidates.size();i++) {
path.push_back(candidates[i]);
sum+=candidates[i];
backtracking(candidates,target,sum,i);
sum-=candidates[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
int sum=0;
backtracking(candidates,target,sum,0);
return res;
}
};
138. 随机链表的复制
cpp
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
unordered_map<Node*,Node*> cachedNode;
Node* copyRandomList(Node* head) {
if(head == nullptr)
return nullptr;
//如果当前节点没有被拷贝
if(!cachedNode.count(head)) {
//新定义节点headNew保存val,
Node* headNew = new Node(head->val);
cachedNode[head] = headNew;
//head->next 和head->random要先存在了才能指过去
//利用递归完成headNew的后继节点next和随机指向节点random的拷贝
headNew->next = copyRandomList(head->next);
headNew->random = copyRandomList(head->random);
}
return cachedNode[head];
}
};