代码随想录训练营Day 23|Python|Leetcode|39. 组合总和,40.组合总和II,131.分割回文串

39. 组合总和

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

解题思路:

注意本题同一个 数字可以 **无限制重复被选取,**但是要明确的是进入下一层for循环时,可选的option是从自身开始,不是从第一个数开始否则会有重复,如下

python 复制代码
class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        result= []
        path = []
        start = 0
        def backtracking(candidates, target, start, total, result, path):
            if total == target:
                result.append(path[:])
                print(result)
                return
            if total > target:
                return 
            for i in range(len(candidates)):
#注意此处应该从range(start, len(candidates))开始选取,从自身index开始不包含前面
                total += candidates[i]
                path.append(candidates[i])
                backtracking(candidates, target, i, total, result, path)#从i index开始
                total -= candidates[i]
                path.pop()
        backtracking(candidates, target, start, 0, result, path)
        return result
python 复制代码
[[2, 2, 3]]
[[2, 2, 3], [2, 3, 2]]
[[2, 2, 3], [2, 3, 2], [3, 2, 2]]
[[2, 2, 3], [2, 3, 2], [3, 2, 2], [7]]

正确代码应如下

python 复制代码
class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        result= []
        path = []
        start = 0
        def backtracking(candidates, target, start, total, result, path):
            if total == target:
                result.append(path[:])
                print(result)
                return
            if total > target:
                return 
            for i in range(start, len(candidates)):
                total += candidates[i]
                path.append(candidates[i])
                backtracking(candidates, target, i, total, result, path)
                total -= candidates[i]
                path.pop()
        backtracking(candidates, target, start, 0, result, path)
        return result

40.组合总和II

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

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

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

解题思路:

本体要注意去重,在数层方面除去重复的数字,比如[1,1,2], 第一个数和第二个数是一样的,如果不排除第二个一样的数字会导致出现重复组合,并且遍历逻辑可得是在for loop进行到下一个数字的时候进行判断。

输入参数:def backtracing(candidates, start, result, path, targetsum, sum)

停止条件:if targetsum<sum: return; if targetsum == sum: result append

递归逻辑:for i in range(start_index, len(candidates)): if targetsum == sum and i>start: continue

backtracing(candidates, i+1, result, path, targetsum, sum)

python 复制代码
class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        path = []
        result = []
        sum = 0
        candidates = sorted(candidates)
        def backtracking(candidates, path, result, start_index, sum, target):
            if sum == target:
                result.append(path[:])
                return 
            if sum>target:
                return
            for i in range(start_index, len(candidates)):
                if i>start_index and candidates[i] == candidates[i-1]:
                    continue#skip
                if sum + candidates[i]>target:
                    break
                sum += candidates[i]
                path.append(candidates[i])
                backtracking(candidates, path, result, i+1, sum, target)
                sum -= candidates[i]
                path.pop()
        backtracking(candidates, path, result, 0, sum, target)
        return result

131.分割回文串

给你一个字符串 s,请你将s分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

解题思路:

本题再添加进path之前要判断是否为回文子串,使用start_index作为切割点,start_index=0时表示未进行切割。

输入参数:def backtracking(s, start_index, path, result)

停止条件:if len(s) >= start_index

回溯逻辑:检查是否为回文子串,是的话path.append(s[start_index:i+1])

python 复制代码
class Solution:
    def partition(self, s: str) -> List[List[str]]:
        path = []
        result = []
        def backtracking(s, start_index, path, result):
            #stopping at start_index>=len
            if start_index>= len(s):
                result.append(path[:])
                return
            for i in range(start_index, len(s)):
                #判断回文子串
                if s[start_index:i+1] != s[start_index:i+1][::-1]:
                    continue
                path.append(s[start_index:i+1])
                backtracking(s, i+1, path, result)
                path.pop()
        backtracking(s, 0, path, result)
        return result
相关推荐
带多刺的玫瑰1 小时前
Leecode刷题C语言之统计不是特殊数字的数字数量
java·c语言·算法
爱敲代码的憨仔1 小时前
《线性代数的本质》
线性代数·算法·决策树
陪学1 小时前
百度遭初创企业指控抄袭,维权还是碰瓷?
人工智能·百度·面试·职场和发展·产品运营
yigan_Eins1 小时前
【数论】莫比乌斯函数及其反演
c++·经验分享·算法
阿史大杯茶1 小时前
AtCoder Beginner Contest 381(ABCDEF 题)视频讲解
数据结构·c++·算法
დ旧言~2 小时前
【高阶数据结构】图论
算法·深度优先·广度优先·宽度优先·推荐算法
张彦峰ZYF2 小时前
投资策略规划最优决策分析
分布式·算法·金融
The_Ticker2 小时前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
Lenyiin3 小时前
02.06、回文链表
数据结构·leetcode·链表
爪哇学长3 小时前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法