leetcode

40. 组合总和 II

2020-02-24  本文已影响0人  十月里的男艺术家

题目

40. 组合总和 II

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
  [1,2,2],
  [5]
]

思路:

背包问题,深度优先搜索(dfs)

代码

class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        self.ans = []
        candidates = sorted(candidates)

        def dfs(remain, t, path):
            if t == 0:
                self.ans.append(path)
                return

            if not remain or remain[0] > t:
                return
            head = remain[0]
            dfs(remain[1:], t-head, path+[head])
            i = 1
            while i < len(remain) and remain[i] == remain[i-1]:
                i += 1
            dfs(remain[i:], t, path)

        dfs(candidates, target, [])
        return self.ans

import "sort"

func combinationSum2(candidates []int, target int) [][]int {
    sort.Ints(candidates)
    res := [][]int{}
    sol := []int{}
    backtrack(candidates, sol, target, &res)
    return res
}

func backtrack(cand []int, sol []int, target int, res *[][]int) {
    if target == 0 {
        copySol := make([]int, len(sol))
        copy(copySol, sol)
        *res = append(*res, sol)
    }
    if len(cand) == 0 || cand[0] > target {
        return
    }
    // sol = sol[:len(sol):len(sol)]
    backtrack(cand[1:], append(sol, cand[0]), target-cand[0], res)
    i := 1
    for i < len(cand) && cand[i] == cand[i-1] {
        i++
    }

    backtrack(cand[i:], sol, target, res)
}

上一篇 下一篇

猜你喜欢

热点阅读