题目:

给定两个整数 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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/combinations
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

参考:代码随想录视频 & 代码随想录题解

回溯(递归) + 剪枝  注意:有回溯就会有递归

回溯可以想象成一棵树,集合的大小代表数的深度,递归的深度代表数的深度。

回溯三步曲:

1.确定回溯函数的参数及返回值

参数根据具体问题来补充,返回值一般为void

void backtracking(参数)

2.确定终止条件,终止条件一般都是找到叶子结点(具体问题具体分析)

if (终止条件){
存放结果
return;
}

3.遍历过程--单层递归逻辑

for (本层集合中的元素){  //横向遍历
处理当前结点;
backtracking(路径,选择列表); //纵向遍历
回溯,撤销; }

n相当于树的宽度,K相当于树的深度

思路:

1.定义两个全局遍历,一个temp用来存放符合条件的单一结果,一个result用来存放符合条件结果集合

2.递归的参数,一个为n,一个为k,还有一个startIndex代表下一层递归搜素的起始位置,为了防止取到重复组合

3.递归内部结构:

①temp这个数组的大小如果达到k,说明我们找到了一个子集大小为k的组合,用result把temp保存起来,并终止本层递归。

②for循环用来横向遍历树(集合元素),for循环每次从startIndex开始遍历,然后用path保存取到的节点i,再使用backtracking()进行递归下一层,最后再进行回溯的操作,撤销本次处理的结果。

剪枝优化:i <= n - (k - temp.size()) + 1

看上图当n = 4, k=3 时,起始位置最多只能取到2,才能满足后续有三个数字。取3,4后都不能满足我们需要的三位数取也没有意义了。

过程:

优化过程如下:

①已经选择的元素个数:temp.size();

②还需要的元素个数为: k - temp.size();

③在集合n中至多要从该起始位置 : n - (k - temp.size()) + 1,开始遍历

加1的意义:当n = 4, k=3 时,加入temp.size() = 0时,最多只能取到2,4 -(3-0)+1 =2,从1-2开始搜索都可以,超过2就不行了,不满足三个元素了。

代码:

 1 class Solution {
2 List<List<Integer>> result = new ArrayList<>();
3 List<Integer> temp = new ArrayList<>();
4 public List<List<Integer>> combine(int n, int k) {
5 int startIndex = 1;
6 backatring(n, k, startIndex);
7 return result;
8 }
9 public void backatring(int n, int k, int startIndex){
10 if (temp.size() == k){
11 result.add(new ArrayList<>(temp));
12 return;
13 }
14 for (int i = startIndex; i <= n - (k - temp.size()) + 1; i++){
15 temp.add(i);
16 backatring(n, k, i+1);
17 temp.remove(temp.size() - 1);
18 }
19 }
20 }

力扣77(Java)-组合(中等)的更多相关文章

  1. 力扣1438. 绝对差不超过限制的最长连续子数组-C语言实现-中等难度

    题目 传送门 文本 给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit . 如果不存在满足条 ...

  2. 力扣算法经典第一题——两数之和(Java两种方式实现)

    一.题目 难度:简单 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数, 并返回它们的数组下标. 你可以假设每种输入只会对应一 ...

  3. 力扣1689. 十-二进制数的最少数目-C语言实现-中等难度题

    题目 传送门 如果一个十进制数字不含任何前导零,且每一位上的数字不是 0 就是 1 ,那么该数字就是一个 十-二进制数 .例如,101 和 1100 都是 十-二进制数,而 112 和 3001 不是 ...

  4. 力扣1052. 爱生气的书店老板-C语言实现-中等难度

    题目 传送门 文本 今天,书店老板有一家店打算试营业 customers.length 分钟.每分钟都有一些顾客(customers[i])会进入书店,所有这些顾客都会在那一分钟结束后离开. 在某些时 ...

  5. 力扣算法——135Candy【H】

    老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分. 你需要按照以下要求,帮助老师给这些孩子分发糖果: 每个孩子至少分配到 1 个糖果.相邻的孩子中,评分高 ...

  6. 【力扣leetcode】-787. K站中转内最便宜的航班

    题目描述: 有 n 个城市通过一些航班连接.给你一个数组 flights ,其中 flights[i] = [fromi, toi, pricei] ,表示该航班都从城市 fromi 开始,以价格 p ...

  7. 刷题-力扣-518. 零钱兑换 II

    518. 零钱兑换 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/coin-change-2/ 著作权归领扣网络所有.商业转载 ...

  8. 力扣算法题—069x的平方根

    实现 int sqrt(int x) 函数. 计算并返回 x 的平方根,其中 x 是非负整数. 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去. 示例 1: 输入: 4 输出: 2 示例 ...

  9. JS数据结构第六篇 --- 二叉树力扣练习题

    1.第226题:翻转二叉树 递归+迭代两种实现方式: /** 反转二叉树 * Definition for a binary tree node. * function TreeNode(val) { ...

  10. 力扣(LeetCode)删除排序链表中的重复元素II 个人题解

    给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字. 思路和上一题类似(参考 力扣(LeetCode)删除排序链表中的重复元素 个人题解)) 只不过这里需要用到一个前 ...

随机推荐

  1. be动词 系动词 连缀动词 Linking Verb

    be动词 系动词 连缀动词 Linking Verb be 原型 am 第一人称单数形式 is 第三人称单数形式 are 第二人称单数和复数形式 been 过去分词 being 现在分词 was 第一 ...

  2. 用户不在 sudoers 文件中。此事将被报告

    在终端,进入root模式 vim /etc/sudoers 在    sudo (ALL:ALL) ALL下 添加 用户名 (ALL:ALL) ALL

  3. vivo统一接入网关VUA转发性能优化实践

    作者:vivo 互联网服务器团队 - Qiu Xiangcun 本文将探讨如何通过使用Intel QuickAssist Technology(QAT)来优化VUA的HTTPS转发性能.我们将介绍如何 ...

  4. SVN 提交文件报错:svn: E155015: Aborting commit:

    svn 提交文件报错: svn: E155015: Commit failed (details follow): svn: E155015: Aborting commit: '文件名称' rema ...

  5. vim下删除swp文件

    vim下删除swp文件 几个选项的内涵 [O]pen Read-Only 只读的方式打开 (E)dit anyway 编辑模式打开,但是不会载入存盘的内容 (R)ecover 编辑模式打开并且加载暂存 ...

  6. JS(循环)

    一 for循环 在程序中,一组被重复执行的语句被称之为循环体,能否继续重复执行,取决于循环的终止条件.由循环体及循环的终止条件组成的语句,被 称之为循环语句 1 语法结构 for循环主要用于把某些代码 ...

  7. python基础八(迭代器、生成器、生成式、递归、匿名函数、面向过程编程)

    一 迭代器 1.什么是迭代器 迭代器指的是迭代取值的工具,迭代是一个重复的过程,每次重复都是基于上一次的结果而 继续的,单纯的重复并不是迭代2.为何要有迭代器 迭代器是用来迭代取值的工具,而涉及到把多 ...

  8. 你对SPA单页面的理解,它的优缺点分别是什么?如何实现SPA应用呢?

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.什么是SPA SPA(single-page application),翻译过来就是单页应用SPA是一种网络应用程序或网站的模型,它通 ...

  9. 记录--iview 使用爬坑

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前段时间公司需要开发一个后台管理系统,时间比较急迫,一两天时间.想一想自己一点一点的搭建起来可能性不太大,就想着有没有现成的可以改一改,就 ...

  10. Redis无法向磁盘写入RBD数据

    2020-12-09 11:52:25|21965|ERROR|storage/DRedisAsyncCallback.cpp:394[cbIncrby]Cmd 'INCRBY' failed, ke ...