算法leetcode每日一练剑指 Offer II 080. 含有 k 个元素的组合 | 77. 组合
Posted 二当家的白帽子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法leetcode每日一练剑指 Offer II 080. 含有 k 个元素的组合 | 77. 组合相关的知识,希望对你有一定的参考价值。
文章目录
- 剑指 Offer II 080. 含有 k 个元素的组合 | 77. 组合:
- 样例 1:
- 样例 2:
- 提示:
- 分析
- 题解
- 原题传送门:https://leetcode-cn.com/problems/uUsW3B/
- 原题传送门:https://leetcode-cn.com/problems/combinations/
剑指 Offer II 080. 含有 k 个元素的组合 | 77. 组合:
给定两个整数 n
和 k
,返回 1 ... n
中所有可能的 k
个数的组合。
样例 1:
输入:
n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
样例 2:
输入:
n = 1, k = 1
输出:
[[1]]
提示:
- 1 <= n <= 20
- 1 <= k <= n
分析
- 面对这道算法题目,二当家的陷入了沉思。
- 穷举所有组合,使用递归大法是最直观的。
- 每个数字都可以选择或者不选择。
- 由于是组合不是排列,所以我们可以从小到大取数,那第一位取数范围就是从1到n+1-k,第二位就是从2到n+2-k,第三位就是从3到n+3-k…
题解
java
class Solution
public List<List<Integer>> combine(int n, int k)
List<List<Integer>> ans = new ArrayList<>();
this.dfs(ans, new Integer[k], 0, 1, n, k);
return ans;
/**
*
* @param ans 最终结果
* @param row 行记录
* @param rowSize 行数字数量
* @param s 开始数字
* @param n
* @param k
*/
private void dfs(List<List<Integer>> ans, Integer[] row, int rowSize, int s, int n, int k)
if (rowSize == k)
ans.add(Arrays.asList(Arrays.copyOf(row, row.length)));
return;
for (int num = s; num <= n + 1 - (k - rowSize); ++num)
// 选择当前数字
row[rowSize] = num;
dfs(ans, row, rowSize + 1, num + 1, n, k);
c
/**
*
*
* @param ans 最终结果
* @param returnSize 结果行数量
* @param row 行记录
* @param rowSize 行数字数量
* @param s 开始数字
* @param n
* @param k
*/
void dfs(int **ans, int *returnSize, int *row, int rowSize, int s, int n, int k)
if (rowSize == k)
int *tmp = malloc(sizeof(int) * k);
for (int i = 0; i < k; i++)
tmp[i] = row[i];
ans[(*returnSize)++] = tmp;
return;
for (int num = s; num <= n + 1 - (k - rowSize); ++num)
// 选择当前数字
row[rowSize] = num;
dfs(ans, returnSize, row, rowSize + 1, num + 1, n, k);
int a(int n, int m)
int c = 1;
while (m > 0)
c *= n--;
m--;
return c;
/**
* 计算返回数量
*
* @param n
* @param k
* @return int
*/
int calcReturnSize(int n, int k)
k = fmin(k, n - k);
return a(n, k) / a(k, k);
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int **combine(int n, int k, int *returnSize, int **returnColumnSizes)
int **ans = malloc(calcReturnSize(n, k) * sizeof(int *));
int row[k];
*returnSize = 0;
dfs(ans, returnSize, row, 0, 1, n, k);
*returnColumnSizes = malloc(*returnSize * sizeof(int));
for (int i = 0; i < (*returnSize); ++i)
(*returnColumnSizes)[i] = k;
return ans;
c++
class Solution
private:
/**
*
* @param ans 最终结果
* @param row 行记录
* @param s 开始数字
* @param n
* @param k
*/
void dfs(vector<vector<int>> &ans, vector<int> &row, int s, int n, int k)
if (row.size() == k)
ans.push_back(row);
return;
for (int num = s; num <= n + 1 - (k - row.size()); ++num)
// 选择当前数字
row.push_back(num);
dfs(ans, row, num + 1, n, k);
row.pop_back();
public:
vector<vector<int>> combine(int n, int k)
vector<vector<int>> ans;
vector<int> row;
dfs(ans, row, 1, n, k);
return ans;
;
python
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
def dfs(s):
if len(row) == k:
ans.append(row[:])
return
for num in range(s, n + 2 - (k - len(row))):
# 选择当前数字
row.append(num)
dfs(num+1)
row.pop()
ans = []
row = []
dfs(1)
return ans
go
func combine(n int, k int) (ans [][]int)
var dfs func([]int, int, int)
dfs = func(row []int, rowSize int, s int)
if rowSize == k
ans = append(ans, append([]int, row...))
return
for num := s; num <= n+1-(k-rowSize); num++
// 选择当前数字
row[rowSize] = num
dfs(row, rowSize+1, num+1)
dfs(make([]int, k), 0, 1)
return
rust
impl Solution
pub fn combine(n: i32, k: i32) -> Vec<Vec<i32>>
fn dfs(ans: &mut Vec<Vec<i32>>, row: &mut Vec<i32>, rowSize: i32, s: i32, n: i32, k: i32)
if rowSize == k
ans.push(row.to_vec());
return;
(s..n + 2 - (k - rowSize)).for_each(|num|
// 选择当前数字
row[rowSize as usize] = num;
dfs(ans, row, rowSize + 1, num + 1, n, k);
);
let mut ans = Vec::new();
dfs(&mut ans, &mut vec![0; k as usize], 0, 1, n, k);
ans
javascript
/**
* @param number n
* @param number k
* @return number[][]
*/
var combine = function(n, k)
const dfs = (row, rowSize, s) =>
if (rowSize === k)
ans.push([...row]);
return;
for (let num = s; num <= n + 1 - (k - rowSize); ++num)
// 选择当前数字
row[rowSize] = num;
dfs(row, rowSize + 1, num + 1);
const ans = [];
dfs([], 0, 1);
return ans;
;
typescript
function combine(n: number, k: number): number[][]
function dfs(row: number[], rowSize : number, s: number)
if (rowSize === k)
ans.push([...row]);
return;
for (let num = s; num <= n + 1 - (k - rowSize); ++num)
// 选择当前数字
row[rowSize] = num;
dfs(row, rowSize + 1, num + 1);
const ans = [];
dfs([], 0, 1);
return ans;
;
原题传送门:https://leetcode-cn.com/problems/uUsW3B/
原题传送门:https://leetcode-cn.com/problems/combinations/
非常感谢你阅读本文~
欢迎【👍点赞】【⭐收藏】【📝评论】~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~
创作挑战赛 新人创作奖励来咯,坚持创作打卡瓜分现金大奖
以上是关于算法leetcode每日一练剑指 Offer II 080. 含有 k 个元素的组合 | 77. 组合的主要内容,如果未能解决你的问题,请参考以下文章
算法leetcode剑指 Offer 56 - II. 数组中数字出现的次数 II(多语言实现)