作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/combinations/description/

题目描述

Given two integers n and k, return all possible combinations of k numbers out of 1 … n.

For example,
If n = 4 and k = 2, a solution is: [
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]

题目大意

找出一个数组的所有可能的组合

解题方法

方法一:递归

这个题要找到组合,组合和排列的不同之处在于组合的数字出现是没有顺序意义的。

剑指offer的做法是找出n个数字中m的数字的组合方法是,把n个数字分成两部分:第一个字符和其他的字符。如果组合中包括第一个字符,那么就在其余字符中找到m-1个组合;如果组合中不包括第一个字符,那么就在其余字符中找到m个字符。所以变成了递归的子问题。

我的做法如下,这个之中用到了if k > len(array)的做法,防止数组过界陷入死循环(其作用主要是对第二个递归而言的)。

class Solution(object):
def combine(self, n, k):
"""
:type n: int
:type k: int
:rtype: List[List[int]]
"""
res = []
self.helper(range(1, n + 1), k, res, [])
return res def helper(self, array, k, res, path):
if k > len(array):
return
if k == 0:
res.append(path)
else:
self.helper(array[1:], k - 1, res, path + [array[0]])
self.helper(array[1:], k, res, path)

方法二:回溯法

这样的思想是我们抽取第一个字符,然后从后面n-1个字符中抽出m-1个;抽取第二个字符,再从后面的n-2个字符抽出m-1个……这样循环下去。因为这样的操作每次都是往后进行寻找的,所以不用考虑去重的问题。

class Solution(object):
def combine(self, n, k):
"""
:type n: int
:type k: int
:rtype: List[List[int]]
"""
res = []
self.helper(range(1, n + 1), k, res, [])
return res def helper(self, array, k, res, path):
if k > len(array):
return
if k == 0:
res.append(path)
else:
for i in range(len(array)):
self.helper(array[i + 1:], k - 1, res, path + [array[i]])

C++代码如下:

class Solution {
public:
vector<vector<int>> combine(int n, int k) {
vector<int> nums(n, 0);
for (int i = 1; i <= n; i++) {
nums[i - 1] = i;
}
vector<vector<int>> res;
helper(nums, res, {}, 0, k);
return res;
}
void helper(const vector<int>& nums, vector<vector<int>>& res, vector<int> path, int start, int remain) {
if (start > nums.size()) return;
if (remain == 0) {
res.push_back(path);
return;
}
for (int i = start; i < nums.size(); i++) {
path.push_back(nums[i]);
helper(nums, res, path, i + 1, remain - 1);
path.pop_back();
}
}
};

日期

2018 年 3 月 11 日
2018 年 12 月 20 日 —— 感冒害的我睡不着

最新文章

  1. Lind.DDD.Messaging框架通讯组件介绍
  2. 一个update的小故事
  3. qml 封装技巧-利用数据来进行适配
  4. 学习使用:before和:after伪元素
  5. JavaScript--DOM修改元素的属性
  6. 真人动作捕捉系统 for Unity
  7. 闭包拾遗 &amp; 垃圾回收机制
  8. Android内存管理(2)HUNTING YOUR LEAKS: MEMORY MANAGEMENT IN ANDROID PART 2
  9. 1257: [CQOI2007]余数之和sum - BZOJ
  10. 使用NumberPicker定制自己喜欢的Date&amp;TimePicker
  11. 手把手教你DIY一个春运迁徙图(一)
  12. Windows下用Caffe跑自己的数据(遥感影像)
  13. 设置启动页面-Launch Image
  14. Win10玩魔兽争霸不能全屏显示的设置教程
  15. Drools学习笔记-01-在eclipse indgo集成Drools5.5
  16. Android WebView的缓存方式分析
  17. jmeter断言接口响应字段大小
  18. hdu 3078 Network (暴力)+【LCA】
  19. Linux基础第四课——文件操作
  20. 问题:mysql服务正在启动 mysql服务无法启动 &amp;&amp; mysql启动脚本 mysql关闭脚本

热门文章

  1. 60-Lowest Common Ancestor of a Binary Search Tree
  2. Excel-计算年龄、工龄 datedif()
  3. 5 — springboot中的yml多环境配置
  4. linux &quot;/tmp/crontab.14QJ49&quot;:1: bad minute errors in crontab file, can&#39;t install&quot; 错误
  5. ace
  6. Learning Spark中文版--第六章--Spark高级编程(1)
  7. DBeaver客户端工具连接Hive
  8. Linux学习 - 变量测试与内容替换
  9. spring jdbc 配置数据源连接数据库
  10. activiti工作流引擎