4. Combined sums lll (LeetCode 216)
Title Narrative:
Find the sum of all sums ofn
(used form a nominal expression)k
combinations of numbers, and the following conditions are satisfied:
- Use only numbers 1 through 9
- each figureMaximum of one use
come (or go) backList of all possible valid combinations . The list cannot contain the same combination twice, and combinations can be returned in any order.
Example 1.
Input: k = 3, n = 7
Output: [[1,2,4]]
Explanation.
1 + 2 + 4 = 7
There are no other combinations that match.
Example 2.
Input: k = 3, n = 9
Output: [[1,2,6], [1,3,5], [2,3,4]]
Explanation.
1 + 2 + 6 = 9
1 + 3 + 5 = 9
2 + 3 + 4 = 9
There are no other combinations that match.
Example 3.
Input: k = 4, n = 1
Output: []
Explanation: No valid combination exists.
Using 4 different numbers in the range [1,9], the smallest sum we can get is 1+2+3+4 = 10, since 10 > 1, there is no valid combination.
Tip.
2 <= k <= 9
1 <= n <= 60
Thoughts:
1. Backtracking function parameters and return values
-
No return value
-
We need the startindex variable to mark the position of our traversal
-
And you need a one-dimensional array path to store the current result and a two-dimensional array result to store the final result set.
-
targetSum (int) The target sum, or n in the title.
-
k(int) is the set of k numbers required in the question.
-
sum(int) is the sum of the elements that have been collected, that is, the sum of the elements in the path.
-
startIndex (int) is the start position of the next level of the for loop search.
The code is as follows:
vector<vector<int>> result;
vector<int> path;
void backtracking(int targetSum, int k, int sum, int startIndex)
2. The end condition of the backtracking function
- When the number of elements in our array is equal to k, we have collected k elements, i.e., we have satisfied the conditions of the question, at which point it should be returned
- And, if targetSum=sum at this point, it's an answer that fulfills the requirements of our question, and we should collect that answer.
The code is as follows:
if(()==k){
if(sum==targetSum) result.push_back(path);
return;
}
3. Logic of single-level recursion
- Here we are choosing nine numbers from 1-9, so a single level recursive for loop should be ≤ 9
for(int i=startindex;i<=9;i++)
-
The process is that path collects the elements of each selection, which is equivalent to edges in a tree structure, and sum counts the total number of elements in path.
-
And, we also need to have the backtracking process, whenever we have to go back to the previous level and re-select if we have added, at that point we should subtract it back
The code is as follows:
for(int i=startindex;i<=9;i++){
path.push_back(i);
sum+=i.
//This is i+1, because elements cannot be fetched repeatedly.
backtracking(targetSum,k,sum,i+1); //Here is the logic of backtracking.
//Here is the logic of backtracking, in the previous added elements, if we want to backtrack to the previous level and then operate, we have to subtract back
sum-=i;
path.pop_back();
}
- In fact, we do not need to add or subtract sum, directly to the incoming parameters, which is equivalent to the logic of backtracking hidden in the recursive function, do not recommend this approach.
for(int i=startindex;i<=9;i++){
path.push_back(i);
//This is i+1, because the element cannot be fetched repeatedly.
backtracking(targetSum,k,sum+i,i+1); path.pop_back(); //Here it is i+1 because the element cannot be taken repeatedly.
path.pop_back();
}
Code:
- It is not difficult to arrive at the code based on our analysis of the three steps above:
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
void backtracking(int targetSum, int k, int startindex, int sum) {
if (() == k) {
if (sum == targetSum)
result.push_back(path);
return;
}
for (int i = startindex; i <= 9; i++) {
sum += i;
path.push_back(i);
backtracking(targetSum, k, i + 1, sum);
//process of backtracking
path.pop_back();
sum -= i;
}
}
vector<vector<int>> combinationSum3(int k, int n) {
//through (a gap)1commencement of election
backtracking(n, k, 1, 0);
return result;
}
};
Pruning:
- In this code, we can have two pruning processes.
- The first is that if we find that the current sum is already greater than the targetSum, then there's no point in just traversing further down the list, there must be no k numbers that add up to n that match the condition.
void backtracking(int targetSum, int k, int startindex, int sum) {
//discoveriessumgreater thantargetSum(modal particle intensifying preceding clause),Directly end this level of recursion
if(sum>targetSum) return;
if (() == k) {
if (sum == targetSum)
result.push_back(path);
return;
}
for (int i = startindex; i <= 9; i++) {
sum += i;
path.push_back(i);
backtracking(targetSum, k, i + 1, sum);
//process of backtracking
path.pop_back();
sum -= i;
}
}
- The second is the condition for single-level recursion; we don't have to traverse from startindex to 9, only to9-(())+1can immediately (do sth)
- Why is it only necessary to iterate up to 9 - (()) + 1? The logic of this question is actually similar to the LeetCode 77 combinatorial sums we explained earlier; the number of elements in our array is (), and we still need to select () elements
- And because we start at i, the bottom of the tree, the depth of the recursion, is traversed to the end of 9, thenThe number of elements in this interval must be ≥()classifier for individual things or people, general, catch-all classifier
- The number of elements in this interval is:9-i+1, then 9-i+1>=(), it can be introduced that i<=9-(())+1, that is to say that i is traversed from at most this position
The pruning process is illustrated below:
-
This article borrows the original image from Code Randomizer, and those who want a more in-depth look can go watch the article posted by the original author!
[Code Randomizer ()]()