美文网首页算法学习
算法题--给定和,挑选可行的数字列表,同一个位置的元素最多只能使

算法题--给定和,挑选可行的数字列表,同一个位置的元素最多只能使

作者: 岁月如歌2020 | 来源:发表于2020-03-19 02:27 被阅读0次
image.png

0. 链接

题目链接

1. 题目

Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

Each number in candidates may only be used once in the combination.

Note:

All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
Example 1:

Input: candidates = [10,1,2,7,6,1,5], target = 8,
A solution set is:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]

Example 2:

Input: candidates = [2,5,2,1,2], target = 5,
A solution set is:
[
  [1,2,2],
  [5]
]

2. 思路:先升序+去重+深度优先搜索

  • 先升序排列排列
  • 去重,并记录每个元素的重复次数
  • 遍历处理每个待选值
  • 对于每个值a,假设其进入假设集,然后
  1. 如果在本回合中,a的已使用次数小于前面记录过的a的重复次数,则继续从大于等于a的数里深度搜索后续值(优先重复选取,条件是a小于目标值),
  2. 否则,就要继续从大于a的数里深度搜索了

终止条件:直到这些值的和等于目标值,则找到了一个组合,将其添加到结果二维列表中

  • 返回结果二维列表

3. 代码

# coding:utf8
from typing import List


class Solution:
    def find(self, nums: List[int], nums_len: int, begin_idx: int, target: int, results: List[List[int]],
             temp_result: List[int], temp_used_times, nums_times_to_use):
        if begin_idx >= nums_len:
            return

        for i in range(begin_idx, nums_len):
            num = nums[i]

            if num < target:
                temp_result.append(num)
                temp_used_times[num] += 1

                if temp_used_times[num] < nums_times_to_use[num]:
                    next_num_index = i
                else:
                    next_num_index = i + 1
                self.find(nums, nums_len, next_num_index, target - num, results, temp_result, temp_used_times, nums_times_to_use)
                temp_result.pop(-1)
                temp_used_times[num] -= 1
            elif num == target:
                result = temp_result + [num]
                results.append(result)
            elif num > target:
                break

    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        candidates.sort()

        candidates_no_repeat = list()
        nums_times_to_use = dict()
        temp_used_times = dict()
        for candidate in candidates:
            if candidate not in nums_times_to_use:
                nums_times_to_use[candidate] = 1
                temp_used_times[candidate] = 0
                candidates_no_repeat.append(candidate)
            else:
                nums_times_to_use[candidate] += 1

        results, temp_result = list(), list()
        self.find(candidates_no_repeat, len(candidates_no_repeat), 0, target, results, temp_result, temp_used_times, nums_times_to_use)
        return results


solution = Solution()
print(solution.combinationSum2([10, 1, 2, 7, 6, 1, 5], 8))
print(solution.combinationSum2([2, 5, 2, 1, 2], 5))

输出结果

[[1, 1, 6], [1, 2, 5], [1, 7], [2, 6]]
[[1, 2, 2], [5]]

4. 结果

image.png

相关文章

网友评论

    本文标题:算法题--给定和,挑选可行的数字列表,同一个位置的元素最多只能使

    本文链接:https://www.haomeiwen.com/subject/rmzhyhtx.html