题目:

给定两个整数 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. vue-helper 组件 跳转 | Vue Jump to Tag 好用,需自己设定快捷键 | Path Intellisense

    vue-helper 组件 跳转 组件名称 除首字母大写,其他不能有大写字母,否则不能跳转 比如 mycomponent 这个名字可以 Mycomponent 这个名字可以 myComponent 这 ...

  2. KETTLE4个工作中有用的复杂实例--2、两表数据比较,循环取数据,比较后自动同步(部门、单位数据同步)

    附:Kettle实战视频教程,需要的朋友可以看看学习下哈~~ kettle实战第一讲-文件和数据库表的互相转换处理_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili kettle实战第二讲-数据库单 ...

  3. 封装TornadoFx常用控件库

    github:https://github.com/Stars-One/common-controls 为TornadoFx的封装的常用控件与工具,基于Jfoenix,借鉴Kfoenix 前言 这个开 ...

  4. day01-2-@RequestMapping和Rest

    @RequestMapping和Rest 1.@RequestMapping 1.1基本使用 @RequestMapping注解可以指定 控制器(处理器) 的某个方法的请求url 1.2@Reques ...

  5. CMake 用法总结(转载)

    原文地址 什么是 CMake All problems in computer science can be solved by another level of indirection. David ...

  6. HISI3520DV300 折腾记录(一)之 《Uboot-Start.S分析 以及 相关启动流程分析》

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  7. linux介绍、安装、shell

    1-Linux发展介绍 零 什么是Linux Linux:和我们常见的Windows一样,都是操作系统,但不同的是: Windows: 收费,不开源,主要用于日常办公.游戏.娱乐多一些. Linux: ...

  8. uniapp 微信对接地图的三种操作

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 1.uni.getLocation 获取当前经维度 先上代码 let that = this // 获取用户是否开启 授权获取当前的地理位 ...

  9. LOTO示波器的变长存储深度和分段存储

    LOTO示波器的变长存储深度和分段存储 经常有客户咨询和不理解LOTO示波器的存储深度为什么是变长的,也表示对LOTO示波器的分段存储功能不理解,本文对LOTO示波器的存储机制做一次完整的梳理,帮助我 ...

  10. 解决raw.githubusercontent.com图片无法访问的问题(github图床图片无法显示,但仓库已存储成功)

    解决raw.githubusercontent.com无法访问的问题(picgo+github配置图床图片不显示,但仓库已存储成功) 关于如何配置picgo+github图床参考我的这篇文章: htt ...