【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
相关推荐
m0_613856294 小时前
mysql如何利用事务隔离级别解决特定业务冲突_mysql隔离方案选型
jvm·数据库·python
昵称小白5 小时前
复杂度分析方法
算法
我的xiaodoujiao5 小时前
API 接口自动化测试详细图文教程学习系列16--项目实战演练3
python·学习·测试工具·pytest
科研前沿5 小时前
2026 数字孪生前沿科技:全景迭代报告 —— 镜像视界生成式孪生(Generative DT)技术白皮书
大数据·人工智能·科技·算法·音视频·空间计算
ID_180079054735 小时前
Python 实现亚马逊商品详情 API 数据准确性校验(极简可用 + JSON 参考)
java·python·json
时空系6 小时前
第10篇:继承扩展——面向对象编程进阶 python中文编程
开发语言·python·ai编程
CHANG_THE_WORLD7 小时前
python 批量终止进程exe
开发语言·python
liann1197 小时前
3.2_红队攻击框架--MITRE ATT&CK‌
python·网络协议·安全·网络安全·系统安全·信息与通信
云天AI实战派7 小时前
AI 智能体问题排查指南:ChatGPT、API 调用到 Agent 上线失灵的全流程修复手册
大数据·人工智能·python·chatgpt·aigc
学涯乐码堂主7 小时前
有趣的“打擂台算法”
c++·算法·青少年编程·gesp