39. Combination Sum 40. Combination Sum II 131. Palindrome Partitioning

39. Combination Sum

Given an array of distinct不同的 integers candidates and a target integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target. You may return the combinations in any order.

The same number may be chosen from candidates an unlimited number of times. Two combinations are unique if the 

frequency

 of at least one of the chosen numbers is different.

The test cases are generated such that the number of unique combinations that sum up to target is less than 150 combinations for the given input.

 backtracking:

class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        self.backtracking(candidates, target, 0, 0)
        return self.result
    
    def __init__(self):
        self.result = []
        self.path = []

    def backtracking(self, candidates, target, total, startindex):
        if total == target:
            self.result.append(self.path[:]) # 忘记加[ : ]
            return
        if total > target:
            return
        
        for i in range(startindex, len(candidates)): 
            total += candidates[i]
            self.path.append(candidates[i])
            self.backtracking(candidates, target, total, i)
            total -= candidates[i]
            self.path.pop()

+ pruning branches:

1. candidates.sort()

2. if total + candidates[i] > target: #pruning (need sorting)
                continue

class Solution:

    def backtracking(self, candidates, target, total, startIndex, path, result):
        if total == target:
            result.append(path[:])
            return

        for i in range(startIndex, len(candidates)):
            if total + candidates[i] > target: #pruning (need sorting)
                continue
            total += candidates[i]
            path.append(candidates[i])
            self.backtracking(candidates, target, total, i, path, result)
            total -= candidates[i]
            path.pop()

    def combinationSum(self, candidates, target):
        result = []
        candidates.sort()  # 需要排序
        self.backtracking(candidates, target, 0, 0, [], result)
        return result

40. Combination Sum II

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

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

Note: The solution set must not contain duplicate combinations.

backtracking + pruning + duplicates condition:

class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        candidates.sort() #不是 sorted
        result = []
        self.backtracking(candidates, target, [], result, 0, 0)
        return result
    
    def backtracking(self, candidates, target, path, result, startindex, total):
        if total == target:
            result.append(path[:])
            return
        
        if total > target:
            return
        
        for i in range(startindex, len(candidates)):
            if total + candidates[i] > target: #不能直接>= ,if so, the equivalent situations are all skipped
                continue
            if i > startindex and candidates[i] == candidates[i - 1]: #so we add this step 
                continue
            total += candidates[i]
            path.append(candidates[i])
            self.backtracking(candidates, target, path, result, i+1, total)
            total -= candidates[i]
            path.pop()

using used:

class Solution:


    def backtracking(self, candidates, target, total, startIndex, used, path, result):
        if total == target:
            result.append(path[:])
            return

        for i in range(startIndex, len(candidates)):
            # 对于相同的数字,只选择第一个未被使用的数字,跳过其他相同数字
            if i > startIndex and candidates[i] == candidates[i - 1] and not used[i - 1]:
                continue

            if total + candidates[i] > target:
                break

            total += candidates[i]
            path.append(candidates[i])
            used[i] = True
            self.backtracking(candidates, target, total, i + 1, used, path, result)
            used[i] = False
            total -= candidates[i]
            path.pop()

    def combinationSum2(self, candidates, target):
        used = [False] * len(candidates)
        result = []
        candidates.sort()
        self.backtracking(candidates, target, 0, 0, used, [], result)
        return result

to optimise with target - candidates[i]:

class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        candidates.sort()
        results = []
        self.combinationSumHelper(candidates, target, 0, [], results)
        return results

    def combinationSumHelper(self, candidates, target, index, path, results):
        if target == 0:
            results.append(path[:])
            return
        for i in range(index, len(candidates)):
            if i > index and candidates[i] == candidates[i - 1]:
                continue  
            if candidates[i] > target:
                break  
            path.append(candidates[i])
            self.combinationSumHelper(candidates, target - candidates[i], i + 1, path, results)
            path.pop()

131. Palindrome Partitioning 分割回文串 

Given a string s, partition s such that every substringof the partition is a palindrome. Return all possible palindrome  /ˈpælɪnˌdroʊm/ partitioning /ˈpɑːrˌtɪʃənɪŋ/ of s.

 what does startindex mean?       This startIndex is the cut line.

difficult !!!

how  to find the end conditon!!!!!!!!!!

start_index == len(s) : cut already at the end  . (total or sum(): all the numbers are used)

class Solution:
    def partition(self, s: str) -> List[List[str]]:
        result = []
        self.backtracking(s, [], result, 0)
        return result
    
    def backtracking(self, s, path, result, startindex):
        if startindex == len(s): # It's already cut to the end.
            result.append(path[:])
            return
        
        for i in range(startindex, len(s)):
            if s[startindex: i+1] == s[startindex: i+1][::-1]:  #Determine if it is a palindrome
                path.append(s[startindex: i+1])
                self.backtracking(s, path, result, i+1)
                path.pop() #最左边,截取第二个ab中的a的时候之后,回溯重新截取ab

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值