代码随想录day28

news2024/11/28 10:45:59

46. 全排列

 思路:这道题首先是一个排列问题,排列问题是讲究顺序的,例如[1,2]和[2,1]是两个不一样的排列,这里的1我们会有重复使用到,但是,在每一个排列中,每一个元素只能使用一次。所以需要一个状态数组初始化为false *len(nums)来标记。当我们第一次使用的时候发现这个元素没有被用过就加入到path中,加入完了之后要把他的状态变为true,标识我们当前这个元素已经用过了。然后进行撤销,因为我们已经把这个排列加入了结果集中,收获到了结果,需要进行回溯 回到上一层,然后再次从头开始搜索,这里状态就又要成为false.

 回溯三部曲:

        递归参数:因为是排列问题,每个组合都会重复用到一个元素,就不需要startindex了,这里只需要一个index,我们最后调用的时候从0开始调用就行。所以参数是nums,index.

        终止条件:

当我们的收获到的path的长度已经和nums的长度一样了,说明我们完全遍历完了,也就是该收获的时候了,所以加入结果集然后return

        单层循环逻辑:if used[i]==false,那我们就加入到path中,开始递归  改变状态 然后回溯+撤销。

代码:

def permute(self, nums: List[int]) -> List[List[int]]:
        res = []
        track = []
        used = [False] * len(nums)
        def back_trace(nums,index):
            if len(track)==len(nums):
                #深度优先遍历时,返回列表是为空的
                res.append(track[:])
                return 
            for i in range(len(nums)):
                '如果当前节点没有被访问过'
                if used[i]==False:
                    '就加入到track中并且状态改为已访问'
                    track.append(nums[i])
                    used[i]=True
                    '回溯'
                    back_trace(nums,0)
                    track.pop()
                    used[i] = False
                else:
                    continue
        back_trace(nums,0)
        return res

47. 全排列 II

  和上一个题不一样的是,nums数组中出现了重复的元素,并且我们的输出结果中,也有重复的元素,但是要求返回不重复的排列

这就是涉及到了我们的去重操作,在前面都有提到过,关于组合和子集的去重方式。

转换为树的结构来看

 分为了树枝去重和树层去重,这个题是数层去重,也就是同一层,前面用过的元素后面不能再用了。

但是树枝是可以重复使用的。

首先要做的就是对nums数组进行排序,通过相邻的数字判断是否有被用过。

回溯三部曲:

                递归参数:nums,index

                终止条件:同样的,如果path的长度等于数组的长度,说明找到了一组

                单层循环逻辑:if  i>0&当前元素等于前一个元素&并且前一个元素没有被使用过

那么就continue循环。否则加入path 然后递归回溯撤销一起走

为什么这里我们要判断上一个元素没有被使用过呢?

实际上是因为我们第一次在做撤销选择的时候,将他的状态码改为了false。实际上在这一层他是已经使用过的。

代码:

def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        #路径长度
        n = len(nums)
        nums.sort()
        #答案数组
        res = []
        #路径数组
        path = []
        #当前状态
        stats = [False] * n

        def dfs(index,nums):
            if len(path)==n:
                res.append(path[:])
                return 
            for i in range(n):
                if stats[i]==False:
                    '''如果上一个数字和当前数字相同并且上一个数字没有被使用过,那就继续循环'''
                    if i >0 and nums[i-1]==nums[i] and stats[i-1]==False:
                        continue
                    path.append(nums[i])
                    stats[i]=True
                    #回溯
                    dfs(0,nums)
                    stats[i]=False
                    path.pop()
                
        dfs(0,nums)
        return res

 leetcode491递增子序列

力扣

思路: 

这个递增子序列比较像是取有序的子集。而且本题也要求不能有相同的递增子序列。

这又是子集,又是去重,是不是不由自主的想起了刚刚讲过的90.子集II (opens new window)。

就是因为太像了,更要注意差别所在,要不就掉坑里了!

在90.子集II (opens new window)中我们是通过排序,再加一个标记数组来达到去重的目的。

而本题求自增子序列,是不能对原数组经行排序的,排完序的数组都是自增子序列了。

所以不能使用之前的去重逻辑!

本题给出的示例,还是一个有序数组 [4, 6, 7, 7],这更容易误导大家按照排序的思路去做了。

为了有鲜明的对比,我用[4, 7, 6, 7]这个数组来举例,抽象为树形结构如图:

 首先明确两点:在树的同一层下,重复的元素不可以使用

                        在树的分支上,要和上一个元素进行对比,因为是递增子序列,所以一定要大于等于上一次的元素。

回溯三部曲:终止条件,当我们的startindex已经等于数组长度的时候,说明遍历完毕,可以return了

                        递归参数:nums,startindex,然后需要初始化我们的path和result结果集

                       单层逻辑:这里我们创建一个set(),深度遍历的时候,每一层都会创建一个新的set判断本层元素是否重复使用

 对path路径进行判断是否为空,如果不为空,那就同时判断上一次的元素也就是path[-1]是否大于我们当前的元素,如果上一个元素大于当前元素,或者当前元素已经在我们的used_set中了,那么久continue。否则,我们就加入used_set&path中,然后递归,然后是我们的撤销 回溯 

def findSubsequences(self, nums: List[int]) -> List[List[int]]:
        self.path = []
        self.result = []
        self.traceback(nums,0)
        return self.result

    def traceback(self,nums,startindex):
        if len(self.path) >=2:
            self.result.append(self.path[:])
        #终止条件 
        if startindex==len(nums):
            return 
        #递归
        #同层横向遍历
        # 深度遍历中每一层都会有一个全新的usage_list用于记录本层元素是否重复使用
        used_set = set() 
        for i in range(startindex,len(nums)):
            if (self.path and nums[i] < self.path[-1]) or nums[i] in used_set:
                continue
            used_set.add(nums[i])
            self.path.append(nums[i])
            self.traceback(nums,i+1)
            self.path.pop()

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

外贸行业企业邮箱选择:安全好用的邮箱服务

随着全球化的发展&#xff0c;外贸行业在全球经济中越来越重要。作为一家从事对外贸易的企业&#xff0c;可靠、安全、易用的邮箱系统对于成功的国际交易至关重要。为您的企业选择正确的邮箱解决方案可能是一个挑战。为了使选择过程更加简化&#xff0c;我们在这里提供了一些提…

C++模板的简单练习

运行代码&#xff1a; #include"std_lib_facilities.h"template <class T>struct S { private:T val; public:S<T>() :val(T()) {}S<T>(T tt) : val(tt) {};T& get();void set(T tt) { val tt; }ostream& operator << (ostream&a…

为什么 Splashtop 是更好用的 iOS 远程桌面应用

全球远程桌面软件市场最近达到19.2亿美元&#xff0c;表明使用任意设备实现随处远程控制越来越受欢迎。 近年来&#xff0c;企业的运营方式发生了重大改变&#xff0c;远程桌面软件已成为广泛使用的解决方案。Splashtop 是目前最好用的远程桌面工具之一&#xff0c;安全可靠且…

Android安卓实战项目(2)---健身UI APP(源码在文末)

Android安卓实战项目&#xff08;2&#xff09;—健身UI APP&#xff08;源码在文末&#xff09; 一.项目运行介绍 1.大致浏览 2.功能介绍 &#xff08;1&#xff09;功能一 第一个界面点击后可以弹出图像&#xff0c;如图&#xff1a; &#xff08;2&#xff09;功能二 界…

[Spring] 三级缓存解决循环依赖详解

什么是循环依赖 注册一个bean对象的过程&#xff1a; Spring扫描class得到BeanDefinition – 根据得到的BeanDefinition去生成bean – 现根据class推断构造方法 – 根据推断出来的构造方法&#xff0c;反射&#xff0c;得到一个对象 – 填充初始对象中的属性(依赖注入) – 如果…

window的anaconda下安装opencv

window安装opencv 阿巴阿巴&#xff0c;安装了多少遍的opencv今天居然搞了这么久。整理一下笔记把。 解决思路主要来源于&#xff1a;(37条消息) 导入import cv2时出现ImportError:DLL load fail:找不到指定模块的解决办法_import cv2 importerror: dll load failed: 找不到指定…

【C进阶】指针进阶(1)_二次复习版

目录 1. 字符指针 1.1常量字符串的修改 加上const解决问题 打印常量字符串 1.2数组存放的字符串 1.3例题:数组创建与常量池的区别 2. 指针数组 2.1字符指针数组 2.2整型指针数组 2.3使用3个一维数组,模拟实现一个二维数组 2.4例题: 3.数组指针 3.1 数组指针的定义…

快速上手Webpack打包指南:用简单的步骤掌握Webpack的使用技巧

目录 概念&#xff1a;1. webpack 打包简介1.0 多个 JS 文件打包&#xff1a;1.1 webpack 数组形式1.2 webpack 对象形式 总结 Webpack的打包过程可以总结为以下几个步骤&#xff1a; 1.入口点配置&#xff1a;在Webpack的配置文件中&#xff0c;我们需要指定一个或多个入口点…

Android Studio 代码模板插件实现

Android Studio 代码模板插件 背景 可以跳过背景和简述&#xff0c;从模板插件实现开始看. 开发新页面时&#xff0c;原先需要写一堆模板代码。比如用Databinding写列表结构的页面&#xff0c;需要手写以下文件&#xff1a; XxActivity.ktXxFragment.ktXxViewModel.ktXxListA…

从零开始学习CTF

前言 CTF简介 中文一般译作夺旗赛&#xff0c;在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式 CTF起源于1996年DEFCON全球黑客大会&#xff0c;以代替之前黑客们通过互相发起真实攻击进行技术比拼的方式 竞赛模式 解题模式&#xff1a; 在解题模式…

如何引导客户进行自助服务,提高员工工作效率?

搭建帮助中心是大多数企业都在尝试做的事情&#xff0c;它的重要性对于企业来说不言而喻。现在对于企业来说&#xff0c;搭建帮助中心或许不是什么难事&#xff0c;但是关于帮助中心&#xff0c;有几个问题需要思考清楚&#xff0c;才能让其发挥最大的价值。 一、如何让用户养成…

Android手机app页面布局方法

app页面布局方法 1. FrameLayout&#xff08;帧布局&#xff09; (1) FrameLayout是最简单的布局了。所有放在布局里的控件&#xff0c;都按照层次堆叠在屏幕的左上角。后加进来的控件覆盖前面的控件。 2. LinearLayout&#xff08;线性布局&#xff09; (1) LinearLayout按…

第九章 多组学简介

第一节 什么是多组学 多组学encode计划是一个大型国际合作计划&#xff0c;旨在研究各种生物体系中的功能元件和基因组功能。该计划的目标是建立一个全面的生物信息学数据库&#xff0c;包括人类和其他生物的基因组和表观基因组、转录组、蛋白质组、代谢组和表型组等。 多组学…

高等数学❤️第一章~第三节~极限❤️间断点及其分类

【精讲】高等数学中的间断点及其分类 博主&#xff1a;命运之光的主页 专栏&#xff1a;高等数学 目录 【精讲】高等数学中的间断点及其分类 导言 一、间断点的概念 二、间断点的分类 必需记忆知识点 知识点1 知识点2 例题&#xff08;用于熟悉高等数学中的间断点及其…

dp算法篇Day11

“哎呀&#xff0c;哎呀&#xff0c;流云开一朵&#xff0c;哟诶嘿哟&#xff0c;哟诶嘿哟~” 51、目标和 (1) 题目解析 包括之后的一些题目&#xff0c;乍一眼看可能你不会发现它与dp问题有何相连&#xff0c;可是按照按照题目又难以想出 思路、写出代码来。因此&#xff0c;…

PostgreSQL——编码“GBK“的字符0x0xa8 0x27在编码“UTF8“没有相对应值`

问题&#xff1a;编码"GBK"的字符0x0xa8 0x27在编码"UTF8"没有相对应值 原因&#xff1a;客户端编码与服务端编码不一致 select name,setting,context from pg_settings where name like %encoding%; 解决方案&#xff1a;修改客户端编码方式和服务端一致…

Jmeter接口测试工具的一些使用小技巧

如何使用英文界面的JMeter Jmeter启动时会自动判断操作系统的locale 并选择合适的语言启动&#xff0c;所以&#xff0c;我们启动jmeter后&#xff0c;其会出现一个倍感亲切的中文界面。但由于jmeter本身的汉化工作做得不好&#xff0c;你会看到有未被汉化的选项及元件的参数。…

脸书营销,跨境电商不能忽视的营销新趋势

Facebook营销就是在Facebook上通过有针对性的广告、商业品牌群组等地方推广您的业务。随着社交媒体继续成为我们日常生活中不可或缺的一部分&#xff0c;Facebook产品在社交商务方面的扩展使该平台成为吸引新客户的重要渠道。 您应该注意到&#xff0c;很多企业都通过Facebook…

3个能免费使用的AI绘画软件,效果精致

通过AI绘画软件&#xff0c;设计小白也能轻松创作出精美的图画创作。本文将为大家介绍3款能免费使用的AI绘画软件&#xff0c;它们能帮助设计小白或者经验丰富的设计师快速设计出精美的图画作品&#xff0c;一起来看看吧&#xff01; 1、即时灵感 即时灵感是国产的AI绘画软件…

【复习45-51题】【每天40分钟,我们一起用50天刷完 (剑指Offer)】第三十七天 37/50

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…