1. 程式人生 > 實用技巧 >[LeetCode] 39. Combination Sum(組合的和)

[LeetCode] 39. Combination Sum(組合的和)

Description

Given an array of distinct integer candicates and a target integer target, return a list of all unique combination of candidates where chosen numbers sum to target. You may return the combinations in any order

.
給一個由互不相同的整陣列成的陣列 candidates 和一個整數 target返回一個列表,列表裡包含所有互異組合,組合裡的元素來自於 candidates,且這些元素的和等於 target。你可以以任何順序返回答案。

The same number may be chosen from candidates an unlimited number of times. Two combinations are unique if the frequency of at least one of the chosen numbers is different.
相同的數可以使用若干次。對於兩個組合,如果至少一個數出現的頻率不同,則認定其為不同的組合

It is guaranteed that the number of unique combinations that sum up to target is less than 150 combinations of the given input.
輸入保證滿足條件的組合元素小於 150 個。

Examples

Example 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.

Example 2

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

Example 3

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

Example 4

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

Example 5

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

Constraints

  • 1 <= candidates.length <= 30

  • 1 <= candidates[i] <= 200

  • All elements of candidates are distinct

  • 1 <= target <= 500

Solution

這題暴力搜尋是比較簡單的,不過在暴力搜尋前可以把 candidates 排下序,方便剪枝。程式碼如下:

class Solution {
    private val result = hashSetOf<List<Int>>()

    fun combinationSum(candidates: IntArray, target: Int): List<List<Int>> {
        candidates.sort()
        backtrack(candidates, 0, target, arrayListOf())
        return result.toList()
    }

    private fun backtrack(candidates: IntArray, curIndex: Int, target: Int, combination: MutableList<Int>) {
        if (target < 0) {
            return
        }
        if (target == 0) {
            result.add(combination.sorted())
        }
        for (i in curIndex..candidates.lastIndex) {
            if (target >= candidates[i]) {
                combination.add(candidates[i])
                backtrack(candidates, curIndex, target - candidates[i], combination)
                combination.removeAt(combination.lastIndex)
            }
        }
    }
}