首页 > 其他分享 >Day 26| 39. 组合总和 、 40.组合总和II 、 131.分割回文串

Day 26| 39. 组合总和 、 40.组合总和II 、 131.分割回文串

时间:2024-06-18 23:54:19浏览次数:13  
标签:index 39 target 组合 res self candidates sum 总和

  1. 组合总和

本题是 集合里元素可以用无数次,那么和组合问题的差别 其实仅在于 startIndex上的控制

题目链接/文章讲解:https://programmercarl.com/0039.组合总和.html
视频讲解:https://www.bilibili.com/video/BV1KT4y1M7HJ
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。

思考

这道题的特点是可以重复选取。
因此for循环内遍历的时候,start_index = i

class Solution:
    def __init__(self):
        self.path = []
        self.res_list_all = []
        self.sum = 0
    def backtracking(self,candidates,target,start_index):
        if self.sum == target:
            self.res_list_all.append(self.path[:])
            return 
        elif self.sum > target:
            return 
        else:
            for i in range(start_index,len(candidates)):
                self.path.append(candidates[i])
                self.sum+=candidates[i]
                self.backtracking(candidates,target,i)
                self.path.pop()
                self.sum-=candidates[i]
                
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        self.backtracking(candidates,target,0)
        return self.res_list_all

排序后,回溯的过程可以剪枝,同一层,前面的数和已经超了的话,后面的就不用再试了,因为后面的数更大。

class Solution:
    def __init__(self):
        self.path = []
        self.res_list_all = []
        self.sum = 0
    def backtracking(self,candidates,target,start_index):
        if self.sum == target:
            self.res_list_all.append(self.path[:])
            return 
        elif self.sum > target:
            return 
        else:
            for i in range(start_index,len(candidates)):
                if self.sum+candidates[i] > target:
                    break
                self.path.append(candidates[i])
                self.sum+=candidates[i]
                self.backtracking(candidates,target,i)
                self.path.pop()
                self.sum-=candidates[i]
                
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        candidates.sort()
        self.backtracking(candidates,target,0)
        return self.res_list_all

40.组合总和II

本题开始涉及到一个问题了:去重。

注意题目中给我们 集合是有重复元素的,那么求出来的 组合有可能重复,但题目要求不能有重复组合。

题目链接/文章讲解:https://programmercarl.com/0040.组合总和II.html
视频讲解:https://www.bilibili.com/video/BV12V4y1V73A

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

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

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

思考

这道题的难点是要在回溯中去重,即去除重复的组合。
两种方法:

  1. 需要定义一个used数组。
    used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
    used[i - 1] == false,说明同一树层candidates[i - 1]使用过

    2. 判断条件增加i>start_index
    两种方案都需要先排序才能去重。

方案二的方法

class Solution:
    def __init__(self):
        self.res = []
        self.res_all = []
        self.sum = 0
    def backtracking(self,candidates,target,start_index):
        if self.sum > target:
            return
        if self.sum == target:
            self.res_all.append(self.res[:])
            return
        for i in range(start_index,len(candidates)):
            if i > start_index and (candidates[i-1] == candidates[i]):
                continue
            self.sum+=candidates[i]
            self.res.append(candidates[i])
            self.backtracking(candidates,target,i+1)
            self.res.pop()
            self.sum-=candidates[i]
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        candidates.sort()
        self.backtracking(candidates,target,0)
        return self.res_all

131.分割回文串

本题较难,大家先看视频来理解 分割问题,明天还会有一道分割问题,先打打基础。

https://programmercarl.com/0131.分割回文串.html
视频讲解:https://www.bilibili.com/video/BV1c54y1e7k6
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

返回 s 所有可能的分割方案。

示例: 输入: "aab" 输出: [ ["aa","b"], ["a","a","b"] ]

思考

分割问题本质上也是求组合问题。start_index表示分割线。

def is_huiwen(s):
    i = 0
    j = len(s)-1
    while i<j:
        if s[i]==s[j]:
            i+=1
            j-=1
        else:
            return False
    return True
class Solution:
    def partition(self, s: str) -> List[List[str]]:
        def backtracking(s,star_index):
            if star_index == len(s):
                res.append(path[:])
                return
            for i in range(star_index,len(s)):
                if is_huiwen(s[star_index:i+1]):
                    path.append(s[star_index:i+1])
                    backtracking(s,i+1)
                    path.pop()
        path = []
        res = []
        backtracking(s,0)
        return res   

标签:index,39,target,组合,res,self,candidates,sum,总和
From: https://www.cnblogs.com/forrestr/p/18255433

相关文章