メインコンテンツへスキップ

NeetCode 150 [Backtracking]medium:Combination Sum2

· loading · loading ·
kiitosu
著者
kiitosu
画像処理やデバイスドライバ、データ基盤構築からWebバックエンドまで、多様な領域に携わってきました。地図解析や地図アプリケーションの仕組みにも経験があり、幅広い技術を活かした開発に取り組んでいます。休日は草野球とランニングを楽しんでいます。
目次

NeetCodeのSolutionを書いていく
#

Combination Sum2
#

問題
#

正数の配列candidatesが与えられます。対象となる正数targetもあるし、重複した値も含んでいます。 合計値がtargetになるcandidatesのユニークな組み合わせをすべて返しなさい。

candidatesの要素は多くても一度しか使えません。回答のsetは重複した組み合わせを含んではいけません。 組み合わせ自体の順番も、組み合わせ内の要素の順番も問われません。

#

Input: candidates = [9,2,2,4,6,1,5], target = 8 Output: [ [1,2,5], [2,2,4], [2,6] ]

Input: candidates = [1,2,3,4,5], target = 7 Output: [ [1,2,4], [2,5], [3,4] ]

制約
#

  • 1 <= candidates.length <= 100
  • 1 <= candidates[i] <= 50
  • 1 <= target <= 30
  • 計算量:O(n*(2^n)) tはtarget、mはnumsの最小値とします。
  • メモリ:O(n)

メモ
#

前回と何が違うんだろう。

  • 入力配列に重複する要素がある。
  • 入力配列の要素は何度も使ってはいけない。使ったら消える

candidatesでループしてcandidate毎に使うか使わないか判定する。 合計値がtargetになったらOutputにappendする。 組み合わせの重複チェックが力技になってしまった。 candidatesをソートしておいて、同じ値の場合は次の枝の候補にしなければいいらしい。 (絶対うまく言えていない・・・)

from collections import Counter
from typing import List


class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        max_index = len(candidates) - 1
        res: List[List[int]] = []

        def backtrack(work: List[int], index):
            if index > max_index:
                return

            #########################
            # 新しい要素を使わないパターン
            #########################
            backtrack(work.copy(), index + 1)

            #########################
            # 新しい要素を使うパターン
            #########################
            e = candidates[index]
            work.append(e)

            # 回答が出た場合は使うバターンの解析は終了
            if sum(work) == target:
                # パターンの重複をチェック
                if Counter(work) not in [Counter(r) for r in res]:
                    res.append(work.copy())
            # 数を超えた場合も次の調査は不要
            elif sum(work) > target:
                pass
            # それ以外だけ調査を続ける
            else:
                backtrack(work.copy(), index + 1)

        backtrack([], 0)

        return res
Reply by Email

関連記事

NeetCode 150 [Backtracking]medium:Combination Sum
· loading · loading
NeetCode 150 [Backtracking]medium:Subsets
· loading · loading
NeetCode 150 [Heap / Priority Queue]medium:Design Twitter
· loading · loading