代码随想录学习Day 25

491.递增子序列

题目链接

讲解链接

本题的是求自增子序列,所以不能对原数组进行排序,排完序的数组都是自增子序列了,所以不能使用之前的去重逻辑!如果仍旧使用之前的逻辑,那么当遇到数组为{4,7,6,7}这种情况时仍会使用到第二个“7”,导致结果出现重复。所以需要考虑采用集合或者哈希表来进行去重。

回溯三部曲:

1.递归函数参数及返回值:参数必须要有的就是原数组nums和确定每次递归开始位置的startindex

def backtracking(self, nums, startindex):

2.递归终止条件:当path的长度大于等于2时收集结果,但是不需要return,因为要收集所有符合条件的树节点。

if len(self.path) >= 2:
    self.result.append(self.path[:])

3.单层搜索逻辑:重点在于如何在树层上去重,同一父节点下的同层上使用过的元素就不能再使用了,所以需要使用一个set来负责每层的去重。used只记录本层元素是否重复使用,新的一层used都会重新定义(清空),所以used只负责本层的去重,在下面不需要对其进行回溯。

used = set()
for i in range(startindex, len(nums)):
    if (self.path and nums[i] < self.path[-1]) or nums[i] in used:
        continue
    used.add(nums[i])
    self.path.append(nums[i])
    self.backtracking(nums, i + 1)
    self.path.pop()

整体代码如下:

class Solution:
    def __init__(self):
        self.path = []
        self.result = []
    def backtracking(self, nums, startindex):
        if len(self.path) >= 2:  # 长度大于等于2的时候收集一个结果
            self.result.append(self.path[:])  # 不需要进行return
        used = set()  # 用于去重的集合,在每一层递归时都会新建一个,只记录本层使用过的元素,不需要回溯
        for i in range(startindex, len(nums)):
            if (self.path and nums[i] < self.path[-1]) or nums[i] in used:  # 如果path不为空且当前元素小于path最右边的元素,或者当前元素已经在本层被使用过,则直接进行下一轮循环
                continue
            used.add(nums[i])  # 将使用过的元素添加到集合中
            self.path.append(nums[i])
            self.backtracking(nums, i + 1)
            self.path.pop()
    def findSubsequences(self, nums: List[int]) -> List[List[int]]:
        self.backtracking(nums, 0)
        return self.result

46.全排列

题目链接

讲解链接

本题的树形结构如下所示:

回溯三部曲:

1.递归函数参数及返回值:首先排列是有序的,也就是说 [1,2] 和 [2,1] 是两个集合,这和之前分析的子集以及组合有所不同。可以看出元素1在[1,2]中已经使用过了,但是在[2,1]中还要在使用一次1,所以处理排列问题不使用startIndex,而是需要一个used数组,标记已经选择的元素。

def backtracking(self, nums, used):

2.递归终止条件:因为要求的是全排列,所以当path的长度与nums长度相同时,说明到达叶子节点,此时收集结果并返回。

if len(self.path) == len(nums):
    self.result.append(self.path[:])
    return

 3.单层搜索逻辑:在排列问题中,每次都要从头开始搜索,例如元素1在[1,2]中已经使用过了,但是在[2,1]中还要再使用一次1。而used数组就是用来记录此时path里都有哪些元素使用了,一个排列里一个元素只能使用一次

for i in range(0, len(nums)):
    if used[i] == True:
        continue
    used[i] = True
    self.path.append(nums[i])
    self.backtracking(nums, used)
    used[i] = False
    self.path.pop()

 整体代码如下:

class Solution:
    def __init__(self):
        self.path = []
        self.result = []
    def backtracking(self, nums, used):
        if len(self.path) == len(nums):  # 长度相等作为终止条件
            self.result.append(self.path[:])
            return
        for i in range(0, len(nums)):
            if used[i] == True:  # used[i]为True则说明当前元素已使用过,直接跳过
                continue
            used[i] = True  # 将使用的元素在used数组中的位置标为True
            self.path.append(nums[i])
            self.backtracking(nums, used)
            used[i] = False  # 回溯操作
            self.path.pop()
    def permute(self, nums: List[int]) -> List[List[int]]:
        used = [False] * len(nums)
        self.backtracking(nums, used)
        return self.result

47.全排列Ⅱ

题目链接

讲解链接

本题难点在于数组中存在重复的元素,如果像前一题来做的话结果中会有很多重复,因为在搜索过程中会将重复的元素再搜索一遍导致产生多余的结果。因此需要考虑针对这些重复元素该怎样去重。采用递增子序列问题中的集合方法来去重是可以的,代码如下:

class Solution:
    def __init__(self):
        self.path = []
        self.result = []
    def backtracking(self, nums, used):
        if len(self.path) == len(nums):
            self.result.append(self.path[:])
            return
        uset = set()  # 使用集合在树层层面进行去重
        for i in range(0, len(nums)):
            if nums[i] in uset or used[i] == True:  # 若该元素在树枝上已取过或者在集合中则跳过
                continue
            uset.add(nums[i])  # 将本层使用过的元素添加到集合中
            used[i] = True
            self.path.append(nums[i])
            self.backtracking(nums, used)
            used[i] = False
            self.path.pop()
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        used = [False] * len(nums)
        self.backtracking(nums, used)
        return self.result

但是使用set进行去重存在内存占用高的问题,可以将去重部分的逻辑修改为如下代码:

if (i > 0 and nums[i] == nums[i - 1] and not used[i - 1]) or used[i]:
    continue

这样做的话需要先对nums数组进行排序,这样才能保证相同的元素处于相邻的位置。当used[i - 1] = False时,说明前一个元素在当前层已经使用过了,在经历了回溯过程之后从True变成了False,这种情况下对重复元素就不再进行搜索,而是直接跳过。完整代码如下:

class Solution:
    def __init__(self):
        self.path = []
        self.result = []
    def backtracking(self, nums, used):
        if len(self.path) == len(nums):
            self.result.append(self.path[:])
            return
        for i in range(len(nums)):
            if (i > 0 and nums[i] == nums[i - 1] and not used[i - 1]) or used[i]:
                continue
            used[i] = True
            self.path.append(nums[i])
            self.backtracking(nums, used)
            used[i] = False
            self.path.pop()
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        used = [False] * len(nums)
        self.backtracking(sorted(nums), used)
        return self.result

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

思迈特软件与上海德拓签署战略合作协议,携手赋能企业数字化转型

3月27日&#xff0c;广州思迈特软件有限公司&#xff08;简称“思迈特软件”&#xff09;与上海德拓信息技术有限公司&#xff08;简称“德拓信息”&#xff09;正式签约建立战略合作伙伴关系。双方将在数字化转型、数据服务、数据应用以及市场资源等多个领域展开深度合作&…

2024年贵州省职业院校技能大赛云计算应用赛项赛题第2套

#需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件包…

xilinx AXI CAN驱动开发

CAN收发方案有很多&#xff0c;常见的解决方案通过是采用CAN收发芯片&#xff0c;例如最常用的SJA1000,xilinx直接将CAN协议栈用纯逻辑实现&#xff0c;AXI CAN是其中一种&#xff1b; 通过这种方式硬件上只需外接一个PHY芯片即可 上图加了一个电平转换芯片 软件设计方面&…

【Labview】虚拟仪器技术

一、背景知识 1.1 虚拟仪器的定义、组成和应用 虚拟仪器的特点 虚拟仪器的突出特征为“硬件功能软件化”&#xff0c;虚拟仪器是在计算机上显示仪器面板&#xff0c;将硬件电路完成信号调理和处理功能由计算机程序完成。 虚拟仪器的组成 硬件软件 硬件是基础&#xff0c;负责将…

提取COCO数据集中特定的类—vehicle 4类

提取COCO数据集中特定的类—vehicle 4类 1 安装pycocotools2 下载COCO数据集3 提取特定的类别4 多类标签合并 1 安装pycocotools pycocotools github地址 pip install githttps://github.com/philferriere/cocoapi.git#subdirectoryPythonAPI2 下载COCO数据集 COCO官网下载2…

Java中的Stream流常用接口和方法

​TOC 第一章&#xff1a;Stream流是什么 1.1&#xff09;简单介绍 学习Stream流就绕不开Lambda表达式&#xff0c; 需要了解Lambda表达式可以看一下这篇–>&#xff1a;Lambda表达式学习 1.其实“流”是个抽象概念&#xff0c;我们把现实世界中与Stream流有相同特性的…

破解极域电子教室控屏

以管理员身份运行cmd 输入代码

CentOS7安装Docker及禅道

https://blog.csdn.net/weixin_46453070/article/details/136183615?ops_request_misc%257B%2522request%255Fid%2522%253A%2522171246925816800222886233%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id171246925816800222886233&biz_i…

C++ //练习 11.22 给定一个map<string, vector<int>>,对此容器的插入一个元素的insert版本,写出其参数类型和返回类型。

C Primer&#xff08;第5版&#xff09; 练习 11.22 练习 11.22 给定一个map<string, vector<int>>&#xff0c;对此容器的插入一个元素的insert版本&#xff0c;写出其参数类型和返回类型。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具…

图形化界面使用MQ!!!

一、docker安装 1、拉去镜像 docker pull rabbitmq:3.10-management 2、Docker运行&#xff0c;并设置开机自启动&#xff08;第一个-p是MQ默认配置的端口&#xff0c;第二个-p是图形化界面配置的端口&#xff09; docker run -d --restartalways --name rabbitmq -p 5672:5672…

5毛钱的DS1302 N/Z串行实时时钟IC

推荐原因&#xff1a; 便宜&#xff0c;够用 该器件最早为DALLAS的产品&#xff0c;所以冠有DS&#xff0c;现国内有多个厂家生产&#xff0c;部分价格不到5毛钱的含税价格&#xff0c;有此自行车&#xff0c;还要什么宝马&#xff1f; 下述为简介&#xff0c;使用前请参阅相应…

汇编语言第一讲:计算机的组织架构和汇编语言介绍

第一讲&#xff1a;计算机的组织架构和汇编语言介绍 汇编语言计算机组织架构 数字电路术语回顾数制 数字电路 硬件电路数字电路的问题 汇编语言的开始 程序的节(sections)调用操作系统的系统调用列出文件(Listing files)汇编和链接调试汇编程序反汇编现有的程序 附录 课程资源 …

SpringBoot项目 jar包方式打包部署

SpringBoot项目 jar包方式打包部署 传统的Web应用进行打包部署&#xff0c;通常会打成war包形式&#xff0c;然后将War包部署到Tomcat等服务器中。 在Spring Boot项目在开发完成后&#xff0c;确实既支持打包成JAR文件也支持打包成WAR文件。然而&#xff0c;官方通常推荐将Sp…

LeetCode初级算法书Java题解日常更新

LeetCode初级算法高效题解&#xff08;含思路注释&#xff09; 文章目录 LeetCode初级算法高效题解&#xff08;含思路注释&#xff09;前言一、数组1.删除排序数组中的重复项2.买卖股票的最佳时机 II3.旋转数组4.存在重复元素 总结 前言 决定用四个月过一下算法 一、数组 1.…

下载python电子书

下面展示一些 内联代码片。 import requests from lxml import etree from urllib import parse from pprint import pprint from tqdm import tqdm class PythonBook: def init(self): self.url“https://m.jb51.net/books/list476_1.html” self.url_page“https://m.jb51.n…

二维码门楼牌管理应用平台:促进二手交易市场的透明化与规范化

文章目录 前言一、二维码门楼牌管理应用平台的建设背景二、二维码门楼牌管理应用平台的功能特点三、二维码门楼牌管理应用平台在二手交易市场中的应用四、二维码门楼牌管理应用平台的未来展望 前言 随着互联网的快速发展&#xff0c;二维码技术已广泛应用于各个领域。在二手交…

【操作系统】python实现银行家算法

银行家算法是最具有代表性的避免死锁的算法。 1、算法原理 银行家算法&#xff1a;当一个新进程进入系统时&#xff0c;该进程必须申明在运行过程中所需要的每种资源的最大数目&#xff0c;且该数目不能超过系统拥有的资源总量。当进程请求某组资源时&#xff0c;系统必须先确…

HarmonyOS 应用开发-自定义Swiper卡片预览效果实现

介绍 本方案做的是采用Swiper组件实现容器视图居中完全展示&#xff0c;两边等长露出&#xff0c;并且跟手滑动效果。 效果图预览 实现思路 本解决方案通过维护所有卡片偏移的数组&#xff0c;实时更新卡片的偏移量&#xff0c;以实现swiper子组件内图片居中展示&#xff0c…

DHT11温度检测系统

DHT11温湿度传感器 产品概述 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器&#xff0c;应用领域&#xff1a;暖通空调&#xff1b;汽车&#xff1b;消费品&#xff1b;气象站&#xff1b;湿度调节器&#xff1b;除湿器&#xff1b;家电&#xff1b;医…

好物推荐:六款让人眼前一亮的个人博客

1.前言 总是有人在问零基础如何搭建个人博客、有哪些好用的博客系统推荐、个人博客和国内技术社区怎么选择&#xff1f;诸如此类的很多问题。对于最后一个问题&#xff0c;我个人的看法很简单&#xff0c;看需求&#xff01; 目前国内做的还不错的技术类社区/论坛其实还是比较…