题目描述:

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

  • 所有数字(包括目标数)都是正整数。
  • 解集不能包含重复的组合。

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[[1, 7],[1, 2, 5],[2, 6],[1, 1, 6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[[1,2,2],[5]
]

要完成的函数:

vector<vector<int>> combinationSum2(vector<int>& candidates, int target)

说明:

1、这道题给定一个vector,里面装着几个正整数,正整数可以是重复的,还给了一个正整数的target。

要求找出所有组合,使得每个组合中的正整数的和等于target。

不能重复使用某一个数。

每个组合以一维vector的形式存储,最终所有组合存储在二维vector中,返回二维vector。

2、举个例子,[10,1,2,7,6,1,5],target是8,我们人类是怎么解决这道题的?

第一个数10,不满足。

第二个数1,可以,但我们还需要7,第三个数2,可以,但我们还需要5,第四个数7不行,第五个数6不行,第六个数1可以,但我们还需要4,第七个数5不行。

然后我们回退到第六个数,我们不要1了,我们还需要5,试探第七个数5,刚好可以。[1,2,5]

接着再回退一步,我们不要第三个数2了,这时候我们还要7,试探第四个数7,刚好可以。[1,7]

接着再回退一步,我们不要第四个数7了,这时候我们还需要7,试探第五个数6,可以,我们还需要1,试探第六个数1,刚好可以。[1,6,1]

接着再回退一步,我们不要第六个数1,我们还需要1,试探第七个数5,不可以,结束。

接着再回退一步……

你会发现这就是一个不断试探的过程,这种题我们适合用递归来做。

要求每个数只能使用一次,这个也简单,我们递归的时候,起始index设置在下一个就好了。

但我们还没有解决重复组合的问题,比如[2,5,2,1,2],target是5。

如果我们用递归来做,我们会得到[2,2,1],[2,1,2],[5],[2,1,2]这样的组合。

对待重复这件事,排序有奇效。

我们简单排个序,变成[1,2,2,2,5],同样递归来做,得到[1,2,2],我们看到下一个数跟当前数是一样的,那么再往前走一步,试探5,就不要试探第三个2了。

这样可以快速地解决重复组合的问题。

代码如下:(附详解)

    vector<vector<int>>res;//全局变量,最终要返回的二维vectorvector<int>res1;//全局变量,存储每次可能的组合void digui(vector<int>& candidates,int index,int target,vector<int>& res1){if(target==0)//满足退出条件{res.push_back(res1);//每个组合插入到res中return;//返回到上一层递归}while(index<candidates.size())//不断地试探{if(candidates[index]<=target){res1.push_back(candidates[index]);//进入递归前,设置好res1digui(candidates,index+1,target-candidates[index],res1);res1.pop_back();//退出递归后,恢复res1}else//如果发现candidates[index]大于target了,那么不要再试了,直接返回到上一层的递归return;while(candidates[index]==candidates[index+1])//想要更新index,如果下一个值跟当前值一样,不断地往前走index++;index++;}}vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {sort(candidates.begin(),candidates.end());//排个序,升序digui(candidates,0,target,res1);//直接进入递归return res;//最终返回res}

上述代码实测8ms,beats 98.51% of cpp submissions。

对于这个过程还不太清晰的同学,可以自己手工推导一下所有过程,逻辑会清晰很多。

也可以参考博主上一篇博文leetcode-39-组合总和(有趣的递归),可以说是同个类型的题目。

转载于:https://www.cnblogs.com/chenjx85/p/9474784.html

leetcode-40-组合总和 II相关推荐

  1. LeetCode 40. 组合总和 II(排列组合 回溯)

    1. 题目 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在每个组合中只 ...

  2. leetcode —— 40. 组合总和 II

    给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在每个组合中只能使用一次. ...

  3. leetcode 40. 组合总和 II 思考分析

    题目 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在每个组合中只能使用 ...

  4. LeetCode 40 组合总和 II

    题目描述 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合.candidates 中的每个数字在每个组合中只能使 ...

  5. LeetCode 40. 组合总和 II(回溯)

    题目描述 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在每个组合中只能 ...

  6. leetcode 39. 组合总和 40. 组合总和 II

    leetcode 39. 组合总和 40. 组合总和 II 组合总和 给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和 ...

  7. 77.组合 | 40.组合总和II | 39.组合总和 | 784.字母大小写全排列

    77.组合 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合. 你可以按 任何顺序 返回答案. 示例 1: 输入:n = 4, k = 2 输出: [   [2,4], ...

  8. Suzy找到实习了吗 Day27 | 回溯进行中:39. 组合总和,40. 组合总和 II,131.分割回文串

    39. 组合总和 题目 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 , ...

  9. leetcode系列--40.组合总和 II

    leetcode系列–第40题.组合总和 II 给你一个由候选元素组成的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合 ...

  10. python两两组合求和_LeetCode-python 40.组合总和 II

    题目链接 难度:中等       类型: 深度优先搜索 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. ca ...

最新文章

  1. 面试被问到Redis实现发布与订阅,手摸手教
  2. 【CVPR 2018】腾讯AI lab提出深度人脸识别中的大间隔余弦损失
  3. vue解决线上跨域的问题_vue前后端分离解决跨域问题
  4. Tomcat源码调试环境搭建
  5. python写sql语句_简单的(笨的)用python以及SQL语句书写增删改查
  6. 软测第二周作业WordCount
  7. 小米答题题库_拼多多果园答题题库74(每日更新)
  8. (34)FPGA原语设计(BUFGMUX)
  9. 2018牛客多校第一场 B.Symmetric Matrix
  10. 雇员查询java面试题经典29例【第八季_常瑞鹏】
  11. LINUX下载编译lua
  12. java中文转繁体汉字
  13. 苹果录屏没声音_苹果手机外放没声音,自己动手就能解决
  14. AutoK3s v0.4.8 发布 与 Harvester 梦幻联动
  15. Linux中ssh基于密匙的安全验证过程是怎样的?
  16. 在ssd上win10和linux双系统,windows 10 ssd ubuntu hdd双系统
  17. MyBatis-Plus 扩展篇 > 自动填充功能
  18. 常见的电子器件,这篇文章总结得很到位,你还不收藏吗?
  19. Android aab的打包、调试、安装
  20. 360云 Ubuntu安装Dokcer

热门文章

  1. Visual Studio 2008 SDK Version 和Microsoft Visual Studio 2008 Shell发布了
  2. 【产品】产品经理常用的五大分析法
  3. [Python学习25] 关于函数更多的练习
  4. Java并发 乐观锁和悲观锁 乐观锁的一种实现方式CAS
  5. 利用微信公众号实现zabbix告警
  6. 有人问我:Linux下命令行里 password:的时候 用键盘密码打不了
  7. cocos2dx飞机大战开发记录(3)
  8. UPNP解读2-含netbios,wins,DNS
  9. Hyper-v下安装网络流量监测图形分析工具 Cacti
  10. python文件和路径操作