题目描述(中等难度)

    和非常像了,区别在于这里给的数组中有重复的数字,每个数字只能使用一次,然后同样是给出所有和等于 target 的情况。

    解法一 回溯法

    只需要在上题的基础上改一下就行了。直接看代码吧。

    时间复杂度:

    空间复杂度:

    看到这里),想法很棒,为了解决重复的情况,我们可以先把数组先排序,这样就好说了。

    解法二 动态规划

    怎么去更改上题的算法满足本题,暂时没想到,只想到就是再写个函数对答案再过滤一次。先记录给定的 nums 中的每个数字出现的次数,然后判断每个 list 的数字出现的次数是不是满足小于等于给定的 nums 中的每个数字出现的次数,不满足的话就剔除掉。如果大家有直接改之前算法的好办法可以告诉我,谢谢了。

    此外,要注意一点就是上题中,给定的 nums 没有重复的,而这题中是有重复的。为了使得和之前一样,所以我们在算法中都得加上

    跳过重复的数字,不然是不能 AC 的,至于原因下边分析下。

    如果不加跳过重复的数字的话,下边的样例不会通过。

    这是因为我们求 opt 的时候每个列表的数量在以指数级增加,在上一个 opt 的基础上,每一个列表都增加 5 个 列表。

    opt [ 1 ] = [ [ 1 ],[ 1 ],[ 1 ],[ 1 ],[ 1 ] ] 数量是 5,

    opt [ 2 ] = [

    ​ [ 1,1 ], [ 1,1 ],[ 1,1 ],[ 1,1 ],[ 1,1 ],

    ​ [ 1,1 ], [ 1,1 ],[ 1,1 ],[ 1,1 ],[ 1,1 ]

    ​ [ 1,1 ], [ 1,1 ],[ 1,1 ],[ 1,1 ],[ 1,1 ],

    ​ [ 1,1 ], [ 1,1 ],[ 1,1 ],[ 1,1 ],[ 1,1 ],

    ​ [ 1,1 ], [ 1,1 ],[ 1,1 ],[ 1,1 ],[ 1,1 ],,

    ​ ] 数量是 5 * 5。

    到了 opt [ 9 ] 就是 5 的 9 次方,数量是 1953125 内存爆炸了。

    另一个算法也可以改一下

    如果不加跳过重复的数字的话,下边的样例不会通过

    会发现出现了很多重复的结果,就是因为没有跳过重复的 1。在求 opt [ 1 ] 的时候就变成了 [ [ 1 ],[ 1 ] ] 这样子,由于后边求的时候都是直接在原来每一个列表里加数字,所有后边都是加了两次了。

    和上题很像,基本上改一改就好了。排序的来排除重复的情况也很妙。还有就是改算法的时候,要考虑到题的要求的变化之处。

    windliang wechat

    添加好友一起进步~

    如果觉得有帮助的话,可以点击 给一个 star 哦 ^^