Backtracking issues include:
- Combinatorial problem
- Subset problem
- Subsequence problem
- Permutation problem
Backtracking is much the same as solving problems
The first is the code template and solution tree (this step is best imagined in your mind)
(refer to from) https://programmercarl.com/ )
https://programmercarl.com/%E5%9B%9E%E6%BA%AF%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html#%E5%85%B6%E4%BB%96%E8%AF%AD%E8%A8%80%E7%89%88%E6%9C%AC
void backtracking(parameter) { if (Termination conditions) { Storage results; return; } for (Selection: Elements in the collection of this layer (the number of node children in the tree is the size of the collection)) { Processing node; backtracking(Path, selection list); // recursion Backtracking, undo processing results } }
Step 2: implementation details (consider the operation of each layer and branch on elements in the tree structure)
A. If the topic requires that the same element cannot be traversed repeatedly, we need to record the position of each traversal in the backtracking function as start, and each traversal starts from the last traversal + 1
B. If the title contains repeated elements and is not a subsequence problem, sort the array first, and then establish a used array in the loop of the backtracking function to record the use of the elements of this layer (because used is established independently in each layer, i.e. each recursion, there is no effect on used between recursions of each layer), After sorting using the used array and the original array, the problem of duplicate elements can be solved
(why must the array {2,6,7,6,7} be sorted first? That is, if the array {2,6,7} is not sorted, consider that the first layer, that is, the element in the subset is 0. When traversing the first 6, a subset starting with 6 will be generated, such as {6,7}. When traversing the first 7, because the used record of element 7 has not been used, such as {7,6} will be generated If we first sort {2, 6, 6, 7, 7}, then {6, 7} will be generated when we encounter the first 6. If there is no 6 in the following element when we traverse to 7, there will be no repetition.)
C. If the topic requires a subsequence problem containing repeated elements, it cannot be sorted in advance (because the original sorting nature will be changed after sorting). At this time, the method to solve duplicate elements is the same as above. Each layer recursively maintains its own used array for the elements used by the layer
(why can the subsequence problem solve the problem of repeating elements without sorting? Because the subsequence problem is to find the increasing or decreasing subsequence without repetition. Assuming that the increasing subsequence, {2, 6, 7, 6, 7}, will not appear. The reason why {6, 7} {7, 6} appears repeatedly above is that we will add nums [i] > temp. Back () to get the increasing sequence.) In other words, the newly added element must be larger than the last element in the result array. In other words, such a condition is equivalent to sorting the array in advance, so there will be no repeated subsequences)
D. If the problem requires the arrangement of repeated elements (the problem of full arrangement is encountered temporarily), because the full arrangement problem needs to include all the elements in the original array, the elements before and after it need to be traversed after traversing which element, so it is necessary to solve the problem of traversing the same element again to traverse the repeated elements, At this time, you must maintain an array used in the recursive process to record the access to elements, that is, used is passed as a parameter of the recursive function. The used array takes effect in each branch, from the initial element to the last element, and is not reset until the next element
6. Combined sum II Given an array candidates And a target number target ,find candidates All numbers in the can make the sum target A combination of. candidates Each number in can only be used once in each combination. Note: the solution set cannot contain duplicate combinations. Example 1: input: candidates = [10,1,2,7,6,1,5], target = 8, output: [ [1,1,6], [1,2,5], [1,7], [2,6] ] Example 2: input: candidates = [2,5,2,1,2], target = 5, output: [ [1,2,2], [5] ] Tips: 1 <= candidates.length <= 100 1 <= candidates[i] <= 50 1 <= target <= 30
class Solution { public: vector<vector<int> > res; vector<int> temp; void getcombinationSum2(vector<int>& candidates,int target,int ans,int start){ if(ans == target){ res.push_back(temp); return; } if(ans > target){ return; } vector<int> flag(51,0); for(int i = start;i < candidates.size();++i){ if(flag[candidates[i]] == 1){ continue; } temp.push_back(candidates[i]); ans += candidates[i]; flag[candidates[i]] = 1; getcombinationSum2(candidates,target,ans,i + 1); temp.pop_back(); ans -= candidates[i]; } return; } vector<vector<int>> combinationSum2(vector<int>& candidates, int target) { sort(candidates.begin(),candidates.end()); getcombinationSum2(candidates,target,0,0); return res; } };
216. Combined sum III Find the sum of all the additions n of k A combination of numbers. Only 1 is allowed in the combination - 9 And there are no duplicate numbers in each combination. explain: All numbers are positive integers. The solution set cannot contain duplicate combinations. Example 1: input: k = 3, n = 7 output: [[1,2,4]] Example 2: input: k = 3, n = 9 output: [[1,2,6], [1,3,5], [2,3,4]]
class Solution { public: vector<vector<int> > res; vector<int> temp; void getcombinationsum(int k,int n,int start,int ans){ if(ans > n){ return; } if(temp.size() == k){ if(ans == n){ res.push_back(temp); } return; } else{ for(int i = start;i <= 9;++i){ temp.push_back(i); ans += i; getcombinationsum(k,n,i + 1,ans); ans -= i; temp.pop_back(); } return; } } vector<vector<int>> combinationSum3(int k, int n) { getcombinationsum(k,n,1,0); return res; } };
90. subset II Give you an array of integers nums ,It may contain duplicate elements. Please return all possible subsets (power sets) of the array. The solution set cannot contain duplicate subsets. Subsets of the returned solution set can be arranged in any order. Example 1: Input: nums = [1,2,2] Output:[[],[1],[1,2],[1,2,2],[2],[2,2]] Example 2: Input: nums = [0] Output:[[],[0]] Tips: 1 <= nums.length <= 10 -10 <= nums[i] <= 10
class Solution { public: vector<vector<int> > res; vector<int> tmp; void getsubsetsWithDup(vector<int>& nums,int start){ if(!tmp.empty()){ res.push_back(tmp); } vector<int> used(21,0); for(int i = start;i < nums.size();++i){ if(used[nums[i] + 10] == 1){ continue; } tmp.push_back(nums[i]); used[nums[i] + 10] = 1; getsubsetsWithDup(nums,i + 1); tmp.pop_back(); } return; } vector<vector<int>> subsetsWithDup(vector<int>& nums) { vector<int> emptyV = {}; res.push_back(emptyV); vector<bool> used(nums.size(),false); sort(nums.begin(),nums.end()); getsubsetsWithDup(nums,0); return res; } };
491. Longest increasing subsequence Give you an array of integers nums ,Find and return all different incremental subsequences in the array, and there are at least two elements in the incremental subsequence. You can return answers in any order. The array may contain duplicate elements. If two integers are equal, it can also be regarded as a special case of increasing sequence. Example 1: Input: nums = [4,6,7,7] Output:[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]] Example 2: Input: nums = [4,4,3,2,1] Output:[[4,4]] Tips: 1 <= nums.length <= 15 -100 <= nums[i] <= 100
class Solution { public: vector<vector<int> > res; vector<int> temp; void getSubsequences(vector<int>& nums,int start){ if(temp.size() > 1){ res.push_back(temp); } int used[201] = {0}; for(int i = start;i < nums.size();++i){ if((!temp.empty()&&nums[i] < temp.back())||used[nums[i] + 100] != 0){ continue; } temp.push_back(nums[i]); used[nums[i] + 100] = 1; getSubsequences(nums,i + 1); temp.pop_back(); } return; } vector<vector<int>> findSubsequences(vector<int>& nums) { res.clear(); temp.clear(); getSubsequences(nums,0); return res; } };
47. Full arrangement II Give a sequence that can contain repeated numbers nums ,Returns all non repeating permutations in any order. Example 1: Input: nums = [1,1,2] Output: [[1,1,2], [1,2,1], [2,1,1]] Example 2: Input: nums = [1,2,3] Output:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] Tips: 1 <= nums.length <= 8 -10 <= nums[i] <= 10
class Solution { public: vector<vector<int> > res; vector<int> temp; void getpermuteUnique(vector<int>& nums,vector<int>& used){ if(temp.size() == nums.size()){ res.push_back(temp); return; } for(int i = 0;i < nums.size();++i){ if(i > 0&&nums[i] == nums[i - 1]&&used[i - 1] == 0){ continue; } if(used[i] == 1){ continue; } temp.push_back(nums[i]); used[i] = 1; getpermuteUnique(nums,used); temp.pop_back(); used[i] = 0; } return; } vector<vector<int>> permuteUnique(vector<int>& nums) { res.clear(); temp.clear(); vector<int> used(nums.size() + 1,0); sort(nums.begin(),nums.end()); getpermuteUnique(nums,used); return res; } };
Unfinished to be continued