Hot100:组合总和(Combination Sum)回溯剪枝 / 可重复选取 ACERS 解析

副标题 / 摘要 组合总和是回溯专题里第一道真正把“组合模板 + 目标约束 + 剪枝”揉在一起的题。你要学会的不只是枚举,而是怎样用排序和剩余值 remain 把搜索树收紧。 预计阅读时长:12~15 分钟 标签:Hot100、回溯、组合、剪枝 SEO 关键词:Combination Sum, 组合总和, 回溯, 剪枝, DFS 元描述:通过 LeetCode 39 建立组合型回溯加剪枝模板,理解可重复选取、排序与 remain 约束。 目标读者 已经做过 78. 子集,准备把回溯模板升级到“带约束搜索”的学习者 想搞清楚“同一个数可以重复使用”时递归边界怎么写的开发者 需要做资源打包、预算组合、规格拼装类组合搜索的工程师 背景 / 动机 这题是很多人真正开始理解“回溯不是暴力乱搜”的分水岭。 因为它同时有三件事: 仍然是组合问题,所以要保持顺序无关 候选数字可以重复使用 目标和 target 给了你天然剪枝条件 如果你只会硬搜,代码虽然也许能过,但模板不稳定。 而一旦你把“排序 + remain + 从 i 开始递归”的逻辑想清楚,这一类题都会顺很多。 核心概念 path:当前正在尝试的一组组合 remain:当前还差多少才能凑到目标值 从 i 继续递归:表示当前数字可以重复使用 排序剪枝:若 candidates[i] > remain,后面的数更大,可直接停止 A — Algorithm(题目与算法) 题目还原 给定一个无重复元素的整数数组 candidates 和一个目标值 target, 找出所有和为 target 的不同组合。 ...

2026年4月2日 · 6 分钟 · map[name:Jeanphilo]

为什么组合优于继承:灵活性、可测试性与演进成本

副标题 / 摘要 继承容易让系统变脆,组合让系统更灵活。本文解释为什么组合更适合工程演进,并给出实用示例。 目标读者 写面向对象代码的工程师 负责模块演进与重构的开发者 做代码评审与架构设计的团队 背景 / 动机 继承会把父类的实现细节暴露给子类,容易导致“脆弱基类问题”。 组合通过“把能力作为对象注入”来降低耦合,更易测试与替换。 核心概念 继承(Inheritance):is-a 关系,强耦合 组合(Composition):has-a 关系,弱耦合 脆弱基类问题:父类改动导致子类行为改变 实践指南 / 步骤 优先建接口,延后继承 把可变行为抽成组件 用组合注入行为 通过依赖替换实现测试 只在“稳定共性”时使用继承 可运行示例 class Logger: def log(self, msg: str) -> None: print(msg) class FileSaver: def save(self, data: str) -> None: print("save", data) class ReportService: def __init__(self, logger: Logger, saver: FileSaver): self.logger = logger self.saver = saver def run(self, data: str) -> None: self.logger.log("start") self.saver.save(data) self.logger.log("done") if __name__ == "__main__": svc = ReportService(Logger(), FileSaver()) svc.run("report") 解释与原理 组合让行为可替换(如 Logger 可以换成 Mock)。 继承则把依赖固定在父类上,一旦父类变化,子类难以控制影响。 ...

2026年1月24日 · 1 分钟 · map[name:Jeanphilo]