LeetCode39 && LeetCode40 && LeetCode216 LeetCode377:组合总和

目录

一、LeetCode39:组合总和(1)

1、题目

2、示例

3、思路

4、代码

二、LeetCode40:组合总和(2)

1、题目

2、示例

3、思路

4、代码

三、LeetCode216:组合总和(3)

1、题目

2、示例

3、思路

4、代码

四、LeetCode377:组合总和(4)

1、题目

2、示例

3、思路

4、代码


一、LeetCode39:组合总和(1)

1、题目

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

candidates 中的数字可以无限制重复被选取。

说明:

  • 所有数字(包括 target)都是正整数
  • 解集不能包含重复的组合

2、示例

示例 1:

输入candidates =[2,3,6,7], target =7
所求解集为:

[
  [7],
  [2,2,3]
]

示例 2:

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

提示:

  • 1 <= candidates.length <= 30
  • 1 <= candidates[i] <= 200
  • candidate 中的每个元素都是独一无二的。
  • 1 <= target <= 500

3、思路

递归+贪心,每次传入的数组均为当前数字之后的数组,包括当前数字。

4、代码

class Solution:
    def combinationSum(self, candidates, target):
        res = []

        def DFS(candidates, target, tmp):
            if len(candidates) == 0 or target == 0:
               res.append(tmp)
               return

               if target < 0:
                  return

               for i in range(len(candidates)):
                   DFS(candidates[i:], target - candidates[i], tmp + [candidates[i]])

        DFS(candidates, target, [])
        return res

if __name__ == '__main__':
    candidates = [2, 3, 6, 7]
    target = 7
    s = Solution()
    ans = s.combinationSum(candidates, target)
    print(ans)

二、LeetCode40:组合总和(2)

1、题目

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

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

说明:

  • 所有数字(包括目标数)都是正整数
  • 解集不能包含重复的组合

2、示例

示例 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]
]

3、思路

(1)递归+贪心+去重,每次传入的list均为当前数字之后的list,不包括当前数字。

(2)tmp用来存储符合条件的组合,当target为0时,即当前组合符合条件,再对其进行排序,并判断其是否已经在res中,若不在,则append,否则,return。

(3)如果传入的数组candidates为空,若target也为0,则append,否则,直接return。

4、代码

class Solution:
    def combinationSum2(self, candidates: list, target: int) -> list:
       
        def DFS(candidates, target, tmp):
            if len(candidates) == 0:
                if target == 0:
                    res.append(tmp)
                    return
                else:
                    return

            if target == 0:
                tmp.sort()
                if tmp not in res:
                    res.append(tmp)
                    return

            if target < 0:
                return

            for i in range(len(candidates)):
                if i > 0 and candidates[i - 1] == candidates[i]:
                    continue

                if target - candidates[i] >= 0:
                    DFS(candidates[i + 1:], target - candidates[i], tmp + [candidates[i]])

        DFS(candidates, target, [])
        return res

if __name__ == '__main__':
    candidates = [10,1,2,7,6,1,5]
    target = 8
    s = Solution()
    ans = s.combinationSum2(candidates, target)
    print(ans)

三、LeetCode216:组合总和(3)

1、题目

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

说明:

  • 所有数字都是正整数
  • 解集不能包含重复的组合

2、示例

示例 1:

输入: k = 3, n = 7
输出: [[1,2,4]]

示例  2:

输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]

3、思路

递归

4、代码

class Solution:
    def combinationSum3(self, k: int, n: int):

        res = []
        candidates = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

        def DFS(i, sums, tmp):
            if sums > n:
                return
            if len(tmp) > k:
                return
            if i == len(candidates):
                return
            if len(tmp) == k and sums < n:
                return
            if len(tmp) == k and sums == n:
                res.append(tmp)
                return

            DFS(i + 1, sums + candidates[i], tmp + [candidates[i]])
            DFS(i + 1, sums, tmp)

        DFS(0, 0, [])
        return res

if __name__ == '__main__':
    k = 3
    n = 15
    s = Solution()
    ans = s.combinationSum3(k , n)
    print(ans)

四、LeetCode377:组合总和(4)

1、题目

给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。

2、示例

nums = [1, 2, 3]
target = 4

所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)

请注意,顺序不同的序列被视作不同的组合。

因此输出为 7。

3、思路

1、自底向上,使用dp数组。

dp[i] = dp[i - nums[0]] + dp[i - nums[1]] + dp[i - nums[2]]+...

例如,

nums = [1, 3, 4], target = 7
dp[7] = dp[6] + dp[4] + dp[3]
其实就是说7的组合数可以由三部分组成,1和dp[6],3和dp[4], 4和dp[3]

2、自顶向下,使用functools模块的lur_cache装饰器,可以缓存最多 maxsize 个此函数的调用结果,从而提高程序执行的效率,特别适合于耗时的函数。否则,将显示超时。

4、代码

1、

from collections import defaultdict

class Solution:
    def combinationSum4(self, nums, target):

        dp = defaultdict(int)
        dp[0] = 1
        for i in range(1, target + 1):
            for num in nums:
                dp[i] += dp[i - num]
        return dp[target]

if __name__ == '__main__':
    # nums = [1, 2, 3]
    # target = 4
    nums = [4, 2, 1]
    target = 32
    s = Solution()
    ans = s.combinationSum4(nums, target)
    print(ans)

2、

from functools import lru_cache

class Solution:
    def combinationSum4(self, nums, target):
        @lru_cache(None)

        res = []
               
        def DFS(target):
            count = 0
            if target == 0:
                return 1
            if target < 0:
                return 0
       
            for i in nums:
                count = count + DFS(target - i)
            return count
       
        return DFS(target)


if __name__ == '__main__':
    # nums = [1, 2, 3]
    # target = 4
    nums = [4, 2, 1]
    target = 32
    s = Solution()
    ans = s.combinationSum4(nums, target)
    print(ans)

猜你喜欢

转载自blog.csdn.net/weixin_45666660/article/details/108684054