40.组合总和Ⅱ python

题目

题目描述

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

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

注意:解集不能包含重复的组合。

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]

提示:

1 <= candidates.length <= 100
1 <= candidates[i] <= 50
1 <= target <= 30

题解

解题思路

这个问题与之前的组合总和问题类似,但有一个关键的区别:每个数字在每个组合中只能使用一次,并且解集不能包含重复的组合。这意味着我们需要采取措施来避免产生重复的结果,同时确保我们不会多次使用同一个数字。

为了实现这一点,我们可以先对输入数组candidates进行排序,然后使用回溯算法(Backtracking)来生成所有可能的组合。在递归过程中,我们将跳过那些会导致重复组合的分支。具体来说,当我们选择了一个数字后,在后续的选择中我们应该跳过所有与它相同的数字,以确保每个组合都是唯一的。

python实现

下面是Python代码实现:

def combinationSum2(candidates, target):
    def backtrack(start, target, path):
        if target == 0:
            result.append(list(path))
            return
        if target < 0:
            return
        
        for i in range(start, len(sorted_candidates)):
            # Skip duplicates
            if i > start and sorted_candidates[i] == sorted_candidates[i - 1]:
                continue
            # Choose the number candidates[i]
            path.append(sorted_candidates[i])
            # Explore further with the chosen number
            backtrack(i + 1, target - sorted_candidates[i], path)
            # Backtrack, undo the choice
            path.pop()

    candidates.sort()  # Sort to facilitate duplicate skipping
    sorted_candidates = candidates
    result = []
    backtrack(0, target, [])
    return result

代码解释

在这段代码中,backtrack函数接收当前搜索的起始索引start、剩余的目标值target以及当前路径path作为参数。我们首先检查是否达到了目标值或超过了目标值。如果找到了一个有效的组合(即target == 0),我们就将这个组合添加到结果列表中;如果超出了目标值(即target < 0),我们就停止进一步探索。

为了避免重复的组合,我们在循环中加入了条件判断if i > start and sorted_candidates[i] == sorted_candidates[i - 1]: continue。这行代码的作用是跳过与前一个数字相同的数字,除非这是第一次遇到该数字(即i == start)。通过这种方式,我们可以保证每个组合都是独一无二的。

最后,我们对candidates进行了排序,这样可以更容易地识别和跳过重复的元素。排序后的数组存储在sorted_candidates变量中,以便在回溯过程中使用。

提交结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gxls2024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值