7.1组合及其优化(LC77-M)

算法:

第一次取1 2 3 4
取1时,留下234

取2时,留下34

取3时,留下4

取4时,留下null


接着继续取234中的2,与1组合,得到12

取234中的3,与1组合,得到13

取234中的4,与1组合,得到14


接着继续取34中的3,与2组合,得到23

取34中的4,与2组合,得到24


接着继续取4,与3组合,得到34


回溯三部曲:

1.确定函数返回值和参数:返回值是void;参数:n、k(题目中都给出了),还要一个startindex,因为每次递归的时候,怎么知道从哪里开始取呢?这时候就需要一个index指引一下。

2.确定终止条件:当取到一个组合时,单层逻辑终止,比如取到12,就不会往下了;因为每个组合(12 13 14 23 24 34)都是树的叶子结点

3.单层递归逻辑:也就是单层搜索的逻辑。在这里就是for循环。

在for循环中,push入要取的数值1或2或3或4;

调用递归

回溯:撤销结果。pop

调试过程:

定义全局变量:result为二维数组,path为一维数组

数组List,用ArrayList和LinkedList都可以

class Solution {
//全局变量List<List<Integer>>result = new ArrayList();LinkedList<Integer>path = new LinkedList();public List<List<Integer>> combine(int n, int k) {backtracking(n,k,1);return result;}void backtracking (int n, int k, int startindex){if (path.size()==k){result.add(path);return;}for(int i=startindex;i<=n;i++){path.add(i);backtracking(n,k,i+1);//往二叉树的深处递归,所以是i+1path.pop();}}
}

原因:输出都是空集

问题出在 `result.add(path);` 这一行以及 `path.pop();` 上

调用 `result.add(path);` 时,实际上是将 `path` 对象的引用加入了 `result` 中,而不是 `path` 对象的拷贝。随后对 `path` 对象的任何修改都会影响到 `result` 中的元素。

`path` 在递归过程中被修改了多次,但是 `result` 中存储的都是同一个 `path` 对象的引用,因此最终 `result` 中的所有元素都指向了同一个 `path` 对象。

可以在将 `path` 加入 `result` 前,先创建一个 `path` 的拷贝,然后将拷贝加入 `result`。在 Java 中,可以通过 `new LinkedList<>(path)` 来创建 `path` 的拷贝另外,`path.pop()` 应该改为 `path.removeLast()`,因为 Java 中的 `LinkedList` 类使用 `removeLast` 来移除最后一个元素。

正确代码:

class Solution {
//全局变量List<List<Integer>>result = new ArrayList();LinkedList<Integer>path = new LinkedList();public List<List<Integer>> combine(int n, int k) {backtracking(n,k,1);return result;}void backtracking (int n, int k, int startindex){if (path.size()==k){result.add(new LinkedList<>(path));return;}for(int i=startindex;i<=n;i++){path.add(i);backtracking(n,k,i+1);//往二叉树的深处递归,所以是i+1path.removeLast();}}
}

剪枝优化

回溯法虽然是暴力搜索,但也有时候可以有点剪枝优化一下的。

只要改一下for循环的条件即可

来举一个例子,n = 4,k = 4的话,答案显然是[1,2,3,4]

如果像刚刚一样求,会增加很多不必要的循环:

那么第一层for循环的时候,从元素2开始的遍历都没有意义了。 在第二层for循环,从元素3开始的遍历都没有意义了。

剪枝:

缩小for循环的范围

  1. 已经选择的元素个数:path.size();

  2. 所需需要的元素个数为: k - path.size();

  3. 列表中剩余元素 >= 所需需要的元素个数

    1. n-i >=k - path.size()

  4. 在集合n中至多要从该起始位置 : i <= n - (k - path.size()) + 1,开始遍历

    1. 为什么有个+1呢,因为包括起始位置,我们要是一个左闭的集合。

剪枝优化后的正确代码:

class Solution {
//全局变量List<List<Integer>>result = new ArrayList();LinkedList<Integer>path = new LinkedList();public List<List<Integer>> combine(int n, int k) {backtracking(n,k,1);return result;}void backtracking (int n, int k, int startindex){if (path.size()==k){result.add(new LinkedList<>(path));return;}for(int i=startindex; i <= n - (k - path.size())+1;i++){path.add(i);backtracking(n,k,i+1);//往二叉树的深处递归,所以是i+1path.removeLast();}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/285680.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ElasticSearch详细搭建以及常见错误high disk watermark [ES系列] - 第497篇

导读 历史文章&#xff08;文章累计490&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六…

PHP使用symfony/process来实现多进程请求url或执行多个php文件

1、什么是symfony/process&#xff1f; Symfony/Process是Symfony框架中的一个组件&#xff0c;用于处理和管理子进程。它提供了一个简单易用的API&#xff0c;可以执行外部命令&#xff0c;并与子进程进行交互。 Symfony/Process可以执行各种操作系统命令&#xff0c;如运行…

Amazon CodeWhisperer 在 vscode 的应用

文章作者:旧花阴 CodeWhisperer 是一款可以帮助程序员更快、更安全地编写代码的工具&#xff0c;可以在他们的开发环境中实时提供代码建议和推荐。亚马逊云科技发布的这款代码生成工具 CodeWhisperer 最大的优势就是对于个人用户免费。以在 vscode 为例&#xff0c;演示安装过程…

百度地图添加坐标点,并返回坐标信息

1、创建地图容器 在mounted中初始化地图、鼠标绘制工具和添加鼠标监听事件 vue data中添加地图和绘制工具对象 2、添加初始化化地图方法 initMap(longitude, latitude) {let that thisthat.map new BMapGL.Map("container");// 创建地图实例if (longitude null ||…

使用SQL和Python处理Excel文件数据

目录 一、引言 二、使用SQL查询Excel文件数据 1、导入必要的库 2、创建数据库连接 3、读取Excel文件数据 4、将数据写入数据库 5、使用SQL查询数据 三、使用Python读取和处理Excel文件数据 1、导入必要的库 2、读取Excel文件数据 3、数据处理和分析 4. 将数据可视化…

【C盘清理】Jetbrains全家桶(PyCharm、Clion……)更改 IDE 特定文件(配置、缓存、插件、日志等)存储位置

文章目录 一、官网说明二、更改 IDE 目录的位置1. 转到“帮助”|“编辑自定义属性”2. 各文件位置3. 以PyCharm系统目录为例4. 修改idea.properties 三、清理旧的 IDE 目录 一、官网说明 IDE 使用的目录官网说明 二、更改 IDE 目录的位置 默认情况下&#xff0c;PyCharm 将每…

【DOM笔记一】什么是DOM?获取元素的方法有哪些?什么是事件以及事件的三要素包括哪些?

文章目录 1 引入1.1 JS组成1.2 API 和 Web API1.3 DOM1.4 DOM树 2 获取元素2.1 通过ID获取2.2 通过标签名获取2.3 通过类名的方法获取2.4 获取特殊元素 3 事件基础 1 引入 1.1 JS组成 JS基础 阶段&#xff1a;ECMAScript 只是标准规定的基本语法&#xff0c;做不了常用的网页…

GaussDB数据库表创建行访问控制策略

目录 一、前言 二、GaussDB中的行访问控制 1、CREATE ROW LEVEL SECURITY POLICY语法 2、ALTER ROW LEVEL SECURITY POLICY语法 3、ROW LEVEL SECURITY策略与适配SQL语法关系 三、GaussDB中的行访问控制策略示例 1、实现GaussDB行访问控制的一般步骤 2、行访问控制策略…

利用canvas封装录像时间轴拖动(uniapp),封装上传uniapp插件市场

gitee项目地址,项目是一个空项目,其中包含了封装的插件,自己阅读,由于利用了canvas所以在使用中暂不支持.nvue,待优化; 项目也是借鉴了github上的一个项目,timeline-canvas,​​​​​​​ ​​​​​​​

【赠书活动】OpenCV4工业缺陷检测的六种方法

文章目录 前言机器视觉缺陷检测工业上常见缺陷检测方法延伸阅读推荐语 赠书活动 前言 随着工业制造的发展&#xff0c;对产品质量的要求越来越高。工业缺陷检测是确保产品质量的重要环节&#xff0c;而计算机视觉技术的应用能够有效提升工业缺陷检测的效率和精度。 OpenCV是一…

openwrt docker nginx 站点搭建

应为家里一直是 openwrt 软路由&#xff0c;这样以来也不用 重新买服务器了&#xff0c;就直接在 openwrt 上面跑个 nginx就行了。把自己的一些东西就可以放上面了。资源再利用哈哈&#xff1b; 先 ssh 连接上 openwrt &#xff1a;我这里的 openwrt 最近刚更新的固件&#xff…

网络安全之Linux环境配置及Linux基础知识讲解<三>

目录 一.下载安装Vmware二.下载安装Kali三.Linux目录结构四.Linux文件属性五.文件目录管理六.vim编辑器 一.下载安装Vmware Vmware官网&#xff1a;https://www.vmware.com 二.下载安装Kali Kali包含数百种工具&#xff0c;可用于各种信息安全任务&#xff0c;例如渗透测试、…