LeetCode - 조합 합계

문제 설명



개별 정수 후보의 배열과 대상 정수 대상이 주어지면 선택한 숫자가 대상으로 합산되는 모든 고유한 후보 조합 목록을 반환합니다. 순서에 상관없이 조합을 반환할 수 있습니다.

후보자 중에서 동일한 번호를 무제한으로 선택할 수 있습니다. 선택한 숫자 중 적어도 하나의 빈도가 다른 경우 두 조합은 고유합니다.

목표에 합산되는 고유한 조합의 수가 주어진 입력에 대해 150개 미만의 조합임을 보장합니다.

다음에서 가져온 문제 설명: https://leetcode.com/problems/combination-sum/ .

예 1:

Input: candidates = [2, 3, 6, 7], target = 7
Output: [[2, 2, 3], [7]]
Explanation:
2 and 3 are candidates, and 2 + 2 + 3 = 7. Note that 2 can be used multiple times.
7 is a candidate, and 7 = 7.
These are the only two combinations.


예 2:

Input: candidates = [2, 3, 5], target = 8
Output: [[2, 2, 2, 2], [2, 3, 3], [3, 5]]


예 3:

Input: candidates = [2], target = 1
Output: []


제약:

- 1 <= candidates.length <= 30
- 1 <= candidates[i] <= 200
- All elements of candidates are distinct.
- 1 <= target <= 500


설명



무차별 대입 방식



무차별 대입 접근 방식은 모든 조합을 생성하고 배열의 요소가 대상에 합산되는지 확인하는 것입니다.

그러나 위 프로그램의 시간 복잡도는 O(N^2)가 됩니다.

역추적



이러한 종류의 문제는 역추적을 사용하여 해결할 수 있습니다. 배열 요소를 임시 배열(현재라고 함)에 계속 추가하고 이 임시 배열의 요소 합계를 계속 추적하는 재귀 함수를 작성합니다. 재귀 함수 내에서 두 가지 기본 사례를 유지합니다.
  • 첫 번째 기본 사례는 임시 배열의 요소 합계가 대상과 같은지 확인하는 것입니다. 그렇다면 최종 결과에 임시 배열을 반환하고 추가합니다.
  • 두 번째 기본 사례는 합계가 방금 반환한 대상 요소를 초과하는지 확인하는 것입니다.

  • 위의 접근 방식을 명확하게 이해하기 위해 알고리즘을 확인합시다.

    - initialize the result as a 2D array
      initialize current as an array
    
      // n = index, at start it will be 0.
      // sumTillNow = sum of the current elements in the array, at the start it will be 0
      // current = current list of elements in the array, at the start it will be an empty array []
    - call combinationSumUtil(result, candidates, n, target, sumTillNow, current)
    
    - return result
    
    // combinationSumUtil function
    - if sumTillNow == target
      // append current to result
      - result.push_back(current)
    
    - if sumTillNow > target
      - return
    
    - loop for i = n; i <= candidates.size() - 1; i++
      // append candidates array ith element to the current array
      - current.push_back(candidates[i])
    
      - sumTillNow += candidates[i]
    
      // call the function recursively
      - combinationSumUtil(result, candidates, i, target, sumTillNow, current)
    
      - sumTillNow -= current[current.size() - 1]
    
      // remove the last element from the array
      - current.pop_back()
    


    C++, Golang 및 Javascript의 솔루션을 확인해 봅시다.

    C++ 솔루션




    class Solution {
    public:
        void combinationSumUtil(vector<vector<int>>& result, vector<int>& candidates, int n, int target, int sumTillNow, vector<int>& current) {
            if(sumTillNow == target) {
                result.push_back(current);
            }
    
            if(sumTillNow > target) {
                return;
            }
    
            for(int i = n; i <= candidates.size() - 1; i++) {
                current.push_back(candidates[i]);
                sumTillNow += candidates[i];
    
                combinationSumUtil(result, candidates, i, target, sumTillNow, current);
    
                sumTillNow -= current[current.size() - 1];
                current.pop_back();
            }
        }
    
        vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
            vector<vector<int>> result;
            vector<int> current;
    
            combinationSumUtil(result, candidates, 0, target, 0, current);
            return result;
        }
    };
    


    골랑 솔루션




    func combinationSumUtil(result *[][]int, candidates []int, n, target, sumTillNow int, current []int) {
        if sumTillNow == target {
            *result = append(*result, append([]int{}, current...))
            return
        }
    
        if sumTillNow > target {
            return
        }
    
        for i := n; i <= len(candidates) - 1; i++ {
            current = append(current, candidates[i])
            sumTillNow = sumTillNow + candidates[i]
    
            combinationSumUtil(result, candidates, i, target, sumTillNow, current)
    
            sumTillNow = sumTillNow - current[len(current) - 1]
            current = current[:len(current) - 1]
        }
    }
    
    func combinationSum(candidates []int, target int) [][]int {
        result := make([][]int, 0)
    
        combinationSumUtil(&result, candidates, 0, target, 0, []int{})
    
        return result
    }
    


    자바스크립트 솔루션




    var combinationSum = function(candidates, target) {
        let result = [];
    
        const combinationSumUtil = (candidates, n, target, sumTillNow, current) => {
            if(sumTillNow === target) {
                result.push([...current]);
            }
    
            if(sumTillNow > target) {
                return;
            }
    
            for(let i = n; i <= candidates.length - 1; i++){
                current.push(candidates[i]);
                sumTillNow += candidates[i];
    
                combinationSumUtil(candidates, i, target, sumTillNow, current);
    
                sumTillNow -= current[current.length - 1];
                current.pop();
            }
        }
    
        combinationSumUtil(candidates, 0, target, 0, []);
    
        return result;
    };
    


    알고리즘을 시험 실행해 봅시다.

    Input: candidates = [2, 3, 6, 7]
           target = 7
    
    // combinationSum function
    Step 1: vector<vector<int>> result
            vector<int> current
    
    Step 2: combinationSumUtil(result, candidates, 0, target, 0, current)
    
    // combinationSumUtil function
    Step 3: if sumTillNow == target
               0 == 7
               false
    
            if sumTillNow > target
               0 > 7
               false
    
            loop for int i = n; i <= candidates.size() - 1
                 i = 0
                 i <= 4 - 1
                 0 <= 3
                 true
    
                 current.push_back(candidates[i])
                 current.push_back(candidates[0])
                 current.push_back(2)
                 current = [2]
    
                 sumTillNow += candidates[i]
                             = sumTillNow + candidates[0]
                             = 0 + 2
                             = 2
    
                 combinationSumUtil(result, candidates, i, target, sumTillNow, current)
                 combinationSumUtil([][], [2, 3, 6, 7], 0, 7, 2, [2])
    
    Step 4: if sumTillNow == target
               2 == 7
               false
    
            if sumTillNow > target
               2 > 7
               false
    
            loop for int i = n; i <= candidates.size() - 1
                 i = 0
                 i <= 4 - 1
                 0 <= 3
                 true
    
                 current.push_back(candidates[i])
                 current.push_back(candidates[0])
                 current.push_back(2)
                 current = [2, 2]
    
                 sumTillNow += candidates[i]
                             = sumTillNow + candidates[0]
                             = 2 + 2
                             = 4
    
                 combinationSumUtil(result, candidates, i, target, sumTillNow, current)
                 combinationSumUtil([][], [2, 3, 6, 7], 0, 7, 4, [2, 2])
    
    Step 5: if sumTillNow == target
               4 == 7
               false
    
            if sumTillNow > target
               4 > 7
               false
    
            loop for int i = n; i <= candidates.size() - 1
                 i = 0
                 i <= 4 - 1
                 0 <= 3
                 true
    
                 current.push_back(candidates[i])
                 current.push_back(candidates[0])
                 current.push_back(2)
                 current = [2, 2, 2]
    
                 sumTillNow += candidates[i]
                             = sumTillNow + candidates[0]
                             = 4 + 2
                             = 6
    
                 combinationSumUtil(result, candidates, i, target, sumTillNow, current)
                 combinationSumUtil([][], [2, 3, 6, 7], 0, 7, 6, [2, 2, 2])
    
    Step 6: if sumTillNow == target
               6 == 7
               false
    
            if sumTillNow > target
               6 > 7
               false
    
            loop for int i = n; i <= candidates.size() - 1
                 i = 0
                 i <= 4 - 1
                 0 <= 3
                 true
    
                 current.push_back(candidates[i])
                 current.push_back(candidates[0])
                 current.push_back(2)
                 current = [2, 2, 2, 2]
    
                 sumTillNow += candidates[i]
                             = sumTillNow + candidates[0]
                             = 6 + 2
                             = 8
    
                 combinationSumUtil(result, candidates, i, target, sumTillNow, current)
                 combinationSumUtil([][], [2, 3, 6, 7], 0, 7, 8, [2, 2, 2, 2])
    
    Step 7: if sumTillNow == target
               8 == 7
               false
    
            if sumTillNow > target
               8 > 7
               true
               return
    
               we backtrack to step 6 and continue
    
    Step 8: combinationSumUtil([][], [2, 3, 6, 7], 0, 7, 8, [2, 2, 2, 2])
            sumTillNow = sumTillNow - current[len(current) - 1]
                       = 8 - current[4 - 1]
                       = 8 - current[3]
                       = 8 - 2
                       = 6
    
            current.pop_back()
            current = [2, 2, 2]
    
            i++
            i = 1
    
            i = 1
            i <= 4 - 1
            1 <= 3
            true
    
            current.push_back(candidates[i])
            current.push_back(candidates[1])
            current.push_back(3)
            current = [2, 2, 2, 3]
    
            sumTillNow += candidates[i]
                        = 6 + candidates[1]
                        = 6 + 3
                        = 9
    
            combinationSumUtil(result, candidates, i, target, sumTillNow, current)
            combinationSumUtil([][], [2, 3, 6, 7], 0, 7, 9, [2, 2, 2, 3])
    
    Step 9: if sumTillNow == target
               9 == 7
               false
    
            if sumTillNow > target
               9 > 7
               true
               return
    
               we backtrack to step 8 and continue
    
    Step 10:combinationSumUtil([][], [2, 3, 6, 7], 0, 7, 9, [2, 2, 2, 3])
            sumTillNow = sumTillNow - current[len(current) - 1]
                       = 9 - current[4 - 1]
                       = 9 - current[3]
                       = 9 - 3
                       = 6
    
            current.pop_back()
            current = [2, 2, 2]
    
            i++
            i = 2
    
            i = 2
            i <= 4 - 1
            2 <= 3
            true
    
            current.push_back(candidates[i])
            current.push_back(candidates[2])
            current.push_back(6)
            current = [2, 2, 2, 6]
    
            sumTillNow += candidates[i]
                        = 6 + candidates[2]
                        = 6 + 6
                        = 12
    
            combinationSumUtil(result, candidates, i, target, sumTillNow, current)
            combinationSumUtil([][], [2, 3, 6, 7], 0, 7, 12, [2, 2, 2, 6])
    
    Step 11: if sumTillNow == target
               12 == 7
               false
    
             if sumTillNow > target
               12 > 7
               true
               return
    
               we backtrack to step 10 and continue
    
    Step 12:combinationSumUtil([][], [2, 3, 6, 7], 0, 7, 9, [2, 2, 2, 3])
            sumTillNow = sumTillNow - current[len(current) - 1]
                       = 12 - current[4 - 1]
                       = 12 - current[3]
                       = 12 - 6
                       = 6
    
            current.pop_back()
            current = [2, 2, 2]
    
            i++
            i = 3
    
            i = 3
            i <= 4 - 1
            3 <= 3
            true
    
            current.push_back(candidates[i])
            current.push_back(candidates[3])
            current.push_back(7)
            current = [2, 2, 2, 7]
    
            sumTillNow += candidates[i]
                        = 6 + candidates[3]
                        = 6 + 7
                        = 13
    
            combinationSumUtil(result, candidates, i, target, sumTillNow, current)
            combinationSumUtil([][], [2, 3, 6, 7], 0, 7, 13, [2, 2, 2, 7])
    
    Step 13: if sumTillNow == target
               13 == 7
               false
    
             if sumTillNow > target
               13 > 7
               true
               return
    
               we backtrack to step 12 and continue
    
    Step 14:combinationSumUtil([][], [2, 3, 6, 7], 0, 7, 9, [2, 2, 2, 3])
            sumTillNow = sumTillNow - current[len(current) - 1]
                       = 13 - current[4 - 1]
                       = 13 - current[3]
                       = 13 - 7
                       = 6
    
            current.pop_back()
            current = [2, 2, 2]
    
            i++
            i = 4
    
            i = 3
            i <= 4 - 1
            4 <= 3
            false
    
            We return to Step 5 directly
    
    Step 15:combinationSumUtil([][], [2, 3, 6, 7], 0, 7, 6, [2, 2, 2])
            sumTillNow = sumTillNow - current[len(current) - 1]
                       = 6 - current[3 - 1]
                       = 6 - current[2]
                       = 6 - 2
                       = 4
    
            current.pop_back()
            current = [2, 2]
    
            i++
            i = 1
    
            i = 1
            i <= 4 - 1
            1 <= 3
            true
    
            current.push_back(candidates[i])
            current.push_back(candidates[1])
            current.push_back(3)
            current = [2, 2, 3]
    
            sumTillNow += candidates[i]
                        = 4 + candidates[1]
                        = 4 + 3
                        = 7
    
            combinationSumUtil(result, candidates, i, target, sumTillNow, current)
            combinationSumUtil([][], [2, 3, 6, 7], 0, 7, 7, [2, 2, 3])
    
    Step 16:if sumTillNow == target
               7 == 7
               true
    
               result.push_back(current)
               result.push_back([2, 2, 3])
    
               result = [[2, 2, 3]]
    
    Similarly, we iterate over all other elements and get the result as
    [[2, 2, 3], [7]]
    

    좋은 웹페이지 즐겨찾기