参考代码随想录
对组合、排列问题的去重进行总结一下。
刷过的去重题目如下。
-
40.组合总和II
给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
-
90.子集II
给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。
-
491. 递增子序列
给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。
数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。
-
47. 全排列 II
给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。
可分为两大类
0 去重模板
去重理论(对数组排序后,)同一节点的本层(一个for循环中)中的元素不能重复,在深度上可以重复使用。
步骤
- 对原数组进行排序【可选,但有时必须排序】;
- 判断当前元素是否跟之前的重复
- 使用哈希表
- 判断当前元素跟上一个元素是否重复(这个做法要求数组有序)
下面将讨论什么时候必须对原数组排序。
1 组合问题的去重
组合问题的去重还能继续分为两类。
1.1 对结果没有顺序要求
见
- 40.组合总和II
- 90.子集II
以子集二为例,组合总和二和这个类似。
之前我对去重的理解错误了,我之前的理解如下:
若使用nums[i]==nums[i-1]这个方法来去重,则要求数组有序;
若使用哈希表来去重,则对数组是否有序不做要求。
显然,在上面这个例子中,我的理解出了问题。
因为在上面的例子中,如果不对数组排序,并且使用哈希表来去重,那么会出现重复的子集。
因此,这类问题,无论是判断当前元素是否和上一个元素相等来去重还是使用哈希表来去重,都必须先对数组排序
。
1.2 对结果有顺序要求
见 491. 递增子序列
这道题对顺序有要求,即升序。
因此如果出现(1,2)、(2,1)这种情况,(2,1)是不会被加入到结果集中的,因为不符合题意。
这道题会自动过滤同一个组合中交换顺序的情况,因此这类题的去重操作对数组元素顺序不做要求。
而且该题是注重顺序的,不能对数组排序。
2 排列问题的去重
见 47. 全排列 II
排列问题中(1,2)和(2,1)本来就不一样,故排列问题的去重对数组顺序不做要求。