算法练习Day23 (Leetcode/Python-回溯算法)

46. Permutations

Given an array nums of distinct integers, return all the possible permutations. You can return the answer in any order.

Example 1:

Input: nums = [1,2,3]
Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]


思路:此题可用回溯法做排列问题。待取元素的candiate内无重复,区别于之前的组合问题,这里在横向遍历时for循环需要遍历所有元素,而不是在startIndex之后的元素(因为排列可以取[1,2,3],[1,3,2]这样的元素,组合的话就只能取[1,2,3],而无[1,3,2])。但是为了避免与纵向已经取过的元素在一个path里重复,要设置一个used元素记录之前path里已经取过的元素。这个used元素也需要在回溯中调整。
class Solution(object):
    def backtrack(self, nums, path, result, used):
        if len(path) == len(nums):
            result.append(path[:]) # 记得用[:]
            return 
        for i in range(len(nums)): # use used to remove duplicated item
            if used[i]:
                continue
            used[i] = True
            path.append(nums[i])
            self.backtrack(nums, path, result, used)
            path.pop()
            used[i] = False

    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        result = []
        used = len(nums) * [False]
        self.backtrack(nums, [], result, used)
        return result

491. Non-decreasing Subsequences

Given an integer array nums, return all the different possible non-decreasing subsequences of the given array with at least two elements. You may return the answer in any order.

Example 1:

Input: nums = [4,6,7,7]
Output: [[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]

思路:找出一个数组中的所有升序子序列,注意这个子序列不需要在原数组中连续。用递归写出暴力解法的思路枚举出所有可能的子序列就可以了。第i+1层横向遍历从startIndex = i+1开始。

关键点在于去重。其实只要每次横向遍历不用本次横向遍历里已经用过的元素就可以了。因为这个新元素最后可以取得的有效升序子序列之能是之前这个元素可以取得的有效子集。因为有效升序子集不需要连续!!

class Solution(object):
    def backtrack(self, nums, startIndex, path, result):
        if len(path) > 1:
            result.append(path[:])
        uset = set()
        for i in range(startIndex, len(nums)):
            if path and nums[i] < path[-1] or nums[i] in uset:  #[2,7,8,4,7,9]  比如这种情况下,第二个7就不能再被取,因为第二个7能组合出来的有效升序子序列一定能被第一个7组合出来。
                continue
            uset.add(nums[i])
            path.append(nums[i])
            self.backtrack(nums, i +1, path, result)
            path.pop()


    def findSubsequences(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        result = []
        path = []
        self.backtrack(nums, 0, path, result)
        return result 
        

47. Permutations II

此题乍一看和之前的题很像,应该是一个套路,但是 if (i>0 and nums[i] == nums[i-1] and used[i-1]) or used[i]: 这个两个条件却让我想了很久,这也是此题与之前题目的不同之处。or之后的条件和今天的第一题一致,第一个条件则是结合了排列和元素重复这两个要素得出,可以参见代码随想录里的这个例子。

比如有元素[1,1,1], 第一层取了第一个1,那么第二个和第三个1为避免重复就不可以再取了。进入第二层时,used的情况是[1,0,0]。第二层时,第一个1已经取过了,所以第二层就不可以取第一个1了(对应上述第二中情况),就轮到第二个1了,第二个1之前没有被取过,所以就可以取。第三层时,第一第二个1都不可以取了,就得取第三个1了。

在判断第二层的第二个1是不是要取时,因为第一层时,第一个1已经置true被取过了,且第一层时,第二个1没有被取过,还是false,所以可以取。第二层的第三个1,虽然第一层时第三个元素未被取过还是false,但第二个1也是false,所以为了原数组里重复元素去重,这时候第三个元素不取。

在判断第三层的第二个1是不是要取时,虽然or之前的条件判断可取,但or之后的条件显示因为第二层时,第二个1已经置true被取过了,所以最终不取,但是判断第三层第三个1时,第二层里第二个1被取过了,所以这一层就轮到了第三个1。

以上是我自己目前的理解,不能确定就是完全正确的。如果错漏还请指出。谢谢!

class Solution(object):
    def backtrack(self, nums, path, result, used):
        if len(nums) == len(path):
            result.append(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]:
                # 1. 不可以读取的情况也就是当前位和之前位置值相同,且之前位置在之前层已经被读取过了,那么接下来就要轮到当前元素被读取了。
                # 2. 或者是当前位置的值在升序序列中虽然是第一次出现,但是该元素在之前的层被用过,排列中也要去掉这个以去重。
                # 比如有元素[1,1,1], 第一层取了第一个1,那么第二个和第三个1为避免重复就不可以再取了。进入第二层时,used的情况是[1,0,0]。第二层时,第一个1已经取过了,所以第二层就不可以取第一个1了(对应上述第二中情况),就轮到第二个1了,第二个1之前没有被取过,所以就可以取。第三层时,第一第二个1都不可以取了,就得取第三个1了。
                continue
            used[i] = True
            path.append(nums[i])
            self.backtrack(nums, path, result, used)
            used[i] = False # 注意!因为回溯,处理每一个元素时,和它同层的元素的情况是未被处理的原始值,看到的处理后的都是上一层的。
            path.pop()


    def permuteUnique(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        result = []
        nums.sort()
        used = [False] * len(nums)
        self.backtrack(nums, [], result, used)
        return result 
        

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

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

相关文章

作为铭文跨链赛道龙头,SoBit 有何突出之处?

跨链桥赛道将是铭文市场长期的发展的刚需 在比特币网络中&#xff0c;Ordinals 铭文铸造的铭文总量已经超过了 5100 万枚&#xff0c;并累计费用收入超 5028 BTC。同时&#xff0c;仅 BRC-20 叙事方向的市值&#xff0c;就已经超过了 30 亿美元&#xff0c;并且随着铭文资产种类…

Apache DolphinScheduler 3.1.9 版本发布:提升系统的稳定性和性能

&#x1f680;我们很高兴宣布&#xff0c;Apache DolphinScheduler 的最新版本 3.1.9 已正式发布&#xff01;此版本在 3.1.8 的基础上进行了关键的 bug 修复和文档更新&#xff0c;共计修复了 14 个 bug 和改进了 3 个文档。 主要更新亮点 本次更新重点解决了以下几个关键问题…

3D游戏角色建模纹理贴图处理

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 在本文中&#xff0c;我们将介绍 3D 纹理的基础知识&#xff0c;并讨…

15-网络安全框架及模型-BLP机密性模型

目录 BLP机密性模型 1 背景概述 2 模型原理 3 主要特性 4 优势和局限性 5 困难和挑战 6 应用场景 7 应用案例 BLP机密性模型 1 背景概述 BLP模型&#xff0c;全称为Bell-LaPadula模型&#xff0c;是在1973年由D.Bell和J.LaPadula在《Mathematical foundations and mod…

web渗透安全学习笔记:1、入门基础知识/ XXS漏洞

前言 自编写python渗透工具编写学习笔记专栏以来&#xff0c;笔者便发现了一个较为严重的问题&#xff1a;我们大多数文章都是学习如何用python编写扫描与利用漏洞的渗透工具&#xff0c;却没有真正解析漏洞的形成原因&#xff0c;长此以往我们的学习就只会浮于表面&#xff0c…

C#中创建包含括号的数据表字段的处理方法

在C#中创建数据表时&#xff0c;有时我们会遇到需要在字段名称中包含括号的情况。这种需求可能出现在字段名称包含特殊字符、关键字或空格的情况下。本文将探讨如何处理这种情况&#xff0c;并介绍一些常用的方法。 一、为什么需要处理包含括号的数据表字段 1. 避免与C#语言保…

Spark RDD操作性能优化技巧

Apache Spark是一个强大的分布式计算框架&#xff0c;用于处理大规模数据。然而&#xff0c;在处理大数据集时&#xff0c;性能优化成为一个关键问题。本文将介绍一些Spark RDD操作的性能优化技巧&#xff0c;帮助大家充分利用Spark的潜力&#xff0c;并获得更快的处理速度。 …

【UE5.1】程序化生成Nanite植被

目录 效果 步骤 一、下载Gaea软件和树林资产 二、使用Gaea生成贴图 三、 生成地形 四、生成草地 五、生成树林 六、生成湖泊 七、其它功能介绍 7.1 调整树林生成的面积 7.2 让植物随风飘动 7.3 玩家和植物互动 7.4 雪中树林 7.5 环境音效 效果 步骤 一、下载Ga…

svn外网打不开url地址怎么解决

在家或者出差在外经常会有连接到公司内部SVN服务器的需求&#xff0c; 但是 svn外网打不开url地址怎么解决&#xff1f;如何才能连接到公司内部SVN服务器&#xff1f;今天小编教你一招&#xff0c;在本地SVN服务的内网IP端口用快解析软件添加映射&#xff0c;一步就可以提供让公…

Spring AOP—深入动态代理 万字详解(通俗易懂)

目录 一、前言 二、动态代理快速入门 1.为什么需要动态代理&#xff1f; : 2.动态代理使用案例&#xff1a; 3.动态代理的灵活性 : 三、深入动态代理 1.需求 : 2.实现 : 2.1 接口和实现类 2.2 提供代理对象的类 2.3 测试类 3.引出AOP : 四、总结 一、前言 第四节内容&…

中文版大模型 Token 成本计算器

分享一个轻量的小工具&#xff0c;10MB 左右&#xff0c;能够帮助你直观的了解大模型 Token 的计算方法。 希望能够帮助到想了解或者正在规划模型 API 使用成本的你。 写在前面 之所以折腾这个小工具&#xff0c;是因为有朋友和我提问&#xff0c;大模型 API 的 Token 到底是…

机器学习 -- 数据预处理

系列文章目录 未完待续…… 目录 系列文章目录 前言 一、数值分析简介 二、内容 前言 tips&#xff1a;这里只是总结&#xff0c;不是教程哈。 以下内容仅为暂定&#xff0c;因为我还没找到一个好的&#xff0c;让小白&#xff08;我自己&#xff09;也能容易理解&#x…

计算机网络(6):应用层

每个应用层协议都是为了解决某一类应用问题&#xff0c;而问题的解决又往往是通过位于不同主机中的多个应用进程之间的通信和协同工作来完成的。 应用层的具体内容就是规定应用进程在通信时所遵循的协议。 应用层的许多协议都是基于客户服务器方式。即使是对等通信方式&#x…

[BUG] Hadoop-3.3.4集群yarn管理页面子队列不显示任务

1.问题描述 使用yarn调度任务时&#xff0c;在CapacityScheduler页面上单击叶队列&#xff08;或子队列&#xff09;时&#xff0c;不会显示应用程序任务信息&#xff0c;root队列可以显示任务。此外&#xff0c;FairScheduler页面是正常的。 No matching records found2.原…

Linux中proc文件系统相关介绍

proc虚拟文件系统的工作原理 linux 内核是一个非常庞大、非常复杂的一个单独的程序&#xff0c;对于这样一个程序来说调试是非常复杂的。像kernel这样庞大的项目&#xff0c;给里面添加或者修改一个功能是非常麻烦的&#xff0c;因为添加一个功能可能会影响其他已经有的功能。…

Mybatis行为配置之Ⅰ—缓存

专栏精选 引入Mybatis Mybatis的快速入门 Mybatis的增删改查扩展功能说明 mapper映射的参数和结果 Mybatis复杂类型的结果映射 Mybatis基于注解的结果映射 Mybatis枚举类型处理和类型处理器 再谈动态SQL 文章目录 专栏精选摘要引言正文缓存配置项说明cacheEnabledlocal…

Ubuntu Desktop 22.04 桌面主题配置

Ubuntu Desktop 22.04 桌面主题配置 使用这么久 Ubuntu Desktop&#xff0c;本着不折腾的原则&#xff0c;简单介绍下自己的桌面主题配置。 安装 tweaks 安装 GNOME Shell 安装 GNOME theme安装 gnome-tweaks & chrome-gnome-shell sudo apt update # 安装 gnome-tweaks…

文件下载输出zip文件

文件下载输出成zip文件&#xff1a; 1、前端整个按钮&#xff0c;调js方法&#xff1a;&#xff08;参数&#xff1a;param,需要下载的id&#xff0c;用逗号拼接&#xff09; var param "?dto.id";//需要自己拼接param window.location.href "<%basePat…

maven中dependencyManagement标签

简介 dependencyManagement正如其名&#xff0c;用于项目依赖的统一管理。 在父项目中的pom.xml文件中加入dependencyManagement标签即可完成依赖版本的声明。在声明完成后&#xff0c;子项目&#xff08;module&#xff09;中引用相同的依赖时可以不指定version标签自动引入…

Android Studio实现课表

本文章主要展示课表的实现&#xff0c;里面包含很多控件的用法&#xff0c;比如吐司Toast、通知Notification、ListView&#xff0c;数值选择器NumberPicker&#xff0c;SeekBar同editText的关联。抽屉导航栏 还有一些其他的功能&#xff0c;比如InputFilter自定义的字符过滤器…