【Day20】LeetCode:39. 组合总和,40. 组合总和II,131. 分割回文串

文章目录

  • [LeetCode:39. 组合总和](#LeetCode:39. 组合总和)
  • [LeetCode:40. 组合总和II](#LeetCode:40. 组合总和II)
  • [LeetCode:131. 分割回文串](#LeetCode:131. 分割回文串)

LeetCode:39. 组合总和

https://leetcode.cn/problems/combination-sum/description/

思路

先将 candidates 排序。排序后,如果当前数字已经大于剩余目标值,那么它后面的数字只会更大,可以立即跳出循环。

解答

python 复制代码
class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        def backtrack(remaining, start, current):
            if remaining == 0: # 如果剩余值为0,说明当前组合有效
                result.append(list(current))
                return

            for i in range(start, len(candidates)):
                num = candidates[i]
                if num > remaining:
                    break

                current.append(num)
                backtrack(remaining - num, i, current)
                current.pop()

        candidates.sort() # 排序以便剪枝
        result = []
        backtrack(target, 0, [])
        return result

LeetCode:40. 组合总和II

https://leetcode.cn/problems/combination-sum-ii/

思路

先将 candidates 排序。同一层递归中,如果当前数字和前一个数字相同,并且前一个数字在本层已经使用过(即 i > start),那么以当前数字开头的所有组合都会与以前一个数字开头的组合重复,因此跳过。注意这里 i > start 的条件保证了我们只跳过同一层中的重复,而不影响不同层(例如 [1,1,2] 中两个 1 可以同时出现在一个组合中,因为它们在递归的不同层)。

解答

python 复制代码
class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        results = []
        n = len(candidates)

        def backtrack(remain: int, start: int, path: List[int]) -> None:
            if remain == 0:
                results.append(path[:])
                return

            for i in range(start, n):
                if candidates[i] > remain:
                    break

                # 去重:同一层递归中,如果当前数字和前一个数字相同,跳过
                if i > start and candidates[i] == candidates[i - 1]:
                    continue

                path.append(candidates[i])
                backtrack(remain - candidates[i], i + 1, path)
                path.pop()

        candidates.sort()
        backtrack(target, 0, [])
        return results

LeetCode:131. 分割回文串

https://leetcode.cn/problems/palindrome-partitioning/description/

思路

  1. 从字符串的起始位置 start 开始遍历,尝试所有可能的分割点 end

  2. 对于每个分割点,检查子串 s[start:end+1] 是否是回文。

    (1)如果是,则将该子串加入当前路径 path,然后递归处理剩余部分。

    (2)如果不是,则跳过该分割点,继续尝试下一个。

  3. start 到达字符串末尾时,说明找到了一个完整的分割方案,将当前路径加入结果。

  4. 回溯:在递归返回后,将最后加入的子串弹出,以便尝试其他分割方式。

解答

python 复制代码
class Solution:
    def partition(self, s: str) -> List[List[str]]:
        n = len(s)

        results = []
        path = []

        def backtrack(start: int):
            if start == n:
                results.append(path[:])
                return
                
            for end in range(start, n): # 枚举子串的结束位置
                sub_s = s[start:end+1]
                if sub_s == sub_s[::-1]: # 子串 s[start:end+1] 是回文
                    path.append(sub_s)
                    backtrack(end + 1)
                    path.pop()

        backtrack(0)
        return results
相关推荐
liuyunshengsir2 分钟前
PyTorch 动态量化(Dynamic Quantization)
人工智能·pytorch·python
电子云与长程纠缠10 分钟前
UE5制作六边形包裹球体效果
开发语言·python·ue5
DFT计算杂谈19 分钟前
KPROJ编译教程
java·前端·python·算法·conda
重生之我是Java开发战士31 分钟前
【笔试强训】Week5:空调遥控, kotor和气球,走迷宫,主持人调度II,体操队形,二叉树的最大路径和,排序子序列,消减整数
java·算法·动态规划
念恒123061 小时前
Python(循环中断)
开发语言·python
tsfy20031 小时前
Python 处理中文文件名的3个坑(附 Flask 上传解决函数)
开发语言·python·flask·文件上传·中文编码
AI技术控1 小时前
KV Cache 缓存机制的原理和应用:从 Transformer 推理到大模型服务优化
人工智能·python·深度学习·缓存·自然语言处理·transformer
吃好睡好便好2 小时前
用if…end…语句计算分段函数
开发语言·人工智能·学习·算法·matlab
vx-程序开发2 小时前
基于机器学习的动漫可视化系统的设计与实现-计算机毕业设计源码08339
java·c++·spring boot·python·spring·django·php
灰灰勇闯IT2 小时前
ops-memory:CANN Runtime 的 Tensor 内存管理
算法