IT技术博客大学习 共学习 共进步

算法模式:子集

"地瓜哥"博客网 2026-06-03 09:03:23 累计浏览 1 次
本机暂存

在上一篇文章 算法模式:回溯 介绍一种“一步三回头”、“落棋有悔”的算法模式:回溯。本篇文章,介绍一种无需“一步三回头”,无需“落棋有悔”也可以解决排列组合问题的算法模式:子集。

子集

超级多的编程面试问题都会涉及到排列和组合问题。一般都是使用回溯来解决该类问题,回溯法属于 深度优先搜索。子集问题模式讲的是用 广度优先搜索 来处理这些问题。子集模式适用于子集与全排列。下面分别介绍:

处理子集问题

举例来说明一下这个模式:

给一组数字 [1, 5, 3]

  1. 我们从空集开始:[[]]

  2. 把第一个数 1,加到之前已经存在的集合中:[[], [1]];

  3. 把第二个数 5,加到之前的集合中得到:[[], [1], [5], [1,5]];

  4. 再加第三个数 3,则有:[[], [1], [5], [1,5], [3], [1,3], [5,3], [1,5,3]].

如果原有集合中存在重复元素,那么就需要针对这种情况特殊处理一下。流程如下:

给一组数字 [5, 1, 5]

  1. 先对原有集合进行排序: [1, 5, 3]

  2. 从空集开始:[[]]

  3. 把第一个数 1,加到之前已经存在的集合中:[[], [1]];

  4. 把第二个数 5,加到之前的集合中得到:[[], [1], [5], [1,5]];

  5. 处理第三个数,也是 5 时需要注意:

    1. 如果还是按照上述方案处理,那么就会得到如下结果: [[], [1], [5], [1,5], [5], [1, 5], [5, 5], [1,5, 5]]。这里出现了重复子集: [5], [1, 5]。该方案不通过,❌

    2. 观察最后生成的所有子集与重复的子集,会发现重复的子集,在处理第二个数时,已经处理过 [], [1],如果再次处理 5,那么就会出现重复。所以,只需要处理在处理上一个相同的数时新增加的子集即可。上一个相同数新增的子集是 [5], [1,5],只需要在这些子集后面增加当前数字即可。这样最后的子集就是:[[], [1], [5], [1,5], [5, 5], [1,5, 5]]。方案通过 ✅

建议继续学习

  1. 为什么Fibonacci数列相邻两项之比会趋于0.618? (累计阅读 5,280)
  2. 看来看去都是看数学书 (累计阅读 4,081)
  3. 小心递归次数限制 (累计阅读 3,980)
  4. 在2048里能够得到的最大的数是多少? (累计阅读 3,740)
  5. 倒置字符串中的单词 (累计阅读 3,540)
  6. 递归创建目录的一个函数 (累计阅读 3,160)
  7. 递归字符转义 (累计阅读 2,881)
  8. 程序设计中的计算复用(Computational Reuse) (累计阅读 2,620)
  9. 算法复杂度求法初学 (累计阅读 2,541)
  10. 尾递归对时间与空间复杂度的影响 (累计阅读 2,540)