【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
相关推荐
小鸡吃米…2 小时前
Python—— 环境搭建
python
io_T_T2 小时前
python 文件管理库 Path 解析(详细&基础)
python
明明如月学长2 小时前
AI 更新太快学不过来?我用OpenClaw打造专属AI学习工作流
算法
黎阳之光2 小时前
【黎阳之光:以无线专网与视频孪生,赋能智慧广电与数字中国】
算法·安全·智慧城市·数字孪生
刀法如飞3 小时前
Agentic AI时代,程序员必备的算法思想指南
人工智能·算法·agent
刀法如飞4 小时前
Agentic AI时代程序员必备算法思想详解(附实战案例)
算法·ai编程·编程开发·agentic
渔阳节度使4 小时前
SpringAI实时监控+观测性
后端·python·flask
铁手飞鹰4 小时前
Visual Studio创建Cmake工程导出DLL,通过Python调用DLL
android·python·visual studio
飞Link4 小时前
告别盲目找Bug:深度解析 TSTD 异常检测中的预测模型(Python 实战版)
开发语言·python·算法·bug