代码随想录 - Day34 - 回溯:递增子序列+排列问题

这篇具有很好参考价值的文章主要介绍了代码随想录 - Day34 - 回溯:递增子序列+排列问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

代码随想录 - Day34 - 回溯:递增子序列+排列问题

491. 递增子序列

如果有相等的整数也算递增序列
递增子序列中至少有两个元素 (遍历的时候不用遍历nums中最后一个元素)

输入:nums = [4,6,6,2,8]
输出:[[4,6],[4,6,6],[4,6,6,8],[4,6,8],[4,8],[6,6],[6,6,8],[6,8],[2,2],[2,2,8],[2,8]]
class Solution:
    def backtracking(self, nums, startIndex, path, result):
        if len(path) > 1:
            result.append(path[:])
            # 注意这里不要加return,因为要取树上的节点

        uset = set()    # 用set()对本层元素去重
        for i in range(startIndex, len(nums)):
            # 排除重复的情况,跳过递减的情况
            if (path and nums[i] < path[-1]) or (nums[i] in uset):
                continue
            uset.add(nums[i])       # 记录这个元素在本层用过了,本层后面不能再用了
            path.append(nums[i])
            self.backtracking(nums, i + 1, path, result)    # 递归
            path.pop()  # 回溯

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

题目说了数值范围,所以还可以用哈希表去重,速度比set()快很多。
但是,个人觉得没必要,因为放在实际情况中一般不会给数值范围。

class Solution:
    def backtracking(self, nums, startIndex, path, result):
        if len(path) > 1:
            result.append(path[:])
            # 注意这里不要加return,因为要取树上的节点

        used = [0] * 201  # 使用数组来进行去重操作,题目说数值范围[-100, 100]
        for i in range(startIndex, len(nums)):
            # 排除重复的情况,跳过递减的情况
            # 这里是利用数组的下标和数组中存储的元素来进行去重
            if (path and nums[i] < path[-1]) or used[nums[i] + 100] == 1:
                continue
            used[nums[i] + 100] = 1  # 标记当前元素已经使用过
            path.append(nums[i])
            self.backtracking(nums, i + 1, path, result)    # 递归
            path.pop()  # 回溯

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

46.全排列

全排列,即[1,2][2,1]算作两种排列,所以这道题的result要收集所有的叶子节点
nums 中的所有整数互不相同,因此无需考虑去重

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

这种题就要考虑新的问题了,即它每次的startIndex都是固定的,遇到取过的数时则需要跳过

class Solution:
    def backtracking(self, nums, used, path, result):
        if len(path) == len(nums):
            result.append(path[:])
            return

        for i in range(len(nums)):
            if used[i]:     # 遇到取过的数时则需要跳过
                continue
            used[i] = True  # 取过的数设为True
            path.append(nums[i])
            self.backtracking(nums, used, path, result)
            path.pop()      # 回溯
            used[i] = False # 回溯后把该数设回False

    def permute(self, nums: List[int]) -> List[List[int]]:
        result = []
        used = [False] * len(nums)
        self.backtracking(nums, used, [], result)
        return result

考虑跳过用过的数时,脑子里第一反应是dict,却忘记了用更为简单的数组也可以…

47. 全排列 II

相较于上一题,需要考虑去重的问题,dict貌似有用武之地了

输入:nums = [1,2,1]
输出:[[1,1,2], [1,2,1], [2,1,1]]
class Solution:
    def backtracking(self, nums, used, path, result):
        if len(path) == len(nums):
            result.append(path[:])
            return

        for i in range(len(nums)):
            # 要去重的是 用过且重复 的数
            if i > 0 and nums[i] == nums[i - 1] and used[i - 1] == False:
                continue
            if used[i] == False:     # 遇到取过的数时则需要跳过
                used[i] = True  # 取过的数设为True
                path.append(nums[i])
                self.backtracking(nums, used, path, result)
                path.pop()      # 回溯
                used[i] = False # 回溯后把该数设回False

    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        result = []
        used = [False] * len(nums)
        nums.sort()             # 提前排好序,方便后续去重
        self.backtracking(nums, used, [], result)
        return result

感觉今天这几道题思路好想,代码不好写,总会在一些细节上出错,需要多练习。

以及,mermaid画图好麻烦。。文章来源地址https://www.toymoban.com/news/detail-699014.html

到了这里,关于代码随想录 - Day34 - 回溯:递增子序列+排列问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 代码随想录 Day - 59|#647 回文字串|#516 最长回文子序列

    ● 647. 回文字串 ● 516. 最长回文子序列 给你一个字符串 s ,请你统计并返回这个字符串中回文子串的数目。 回文字符串是正着读和倒过来读一样的字符串。 子字符串是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的子串,即使是由相同的字符组成

    2024年02月07日
    浏览(42)
  • 【代码随想录day19】从前序与中序遍历序列构造二叉树

    使用递归建树,流程如下: 取出后序节点创建新树的节点 找到新树的节点在中序中的索引 分割中序序列 分割后序序列 继续递归建立整颗新树

    2024年02月15日
    浏览(35)
  • 【随想录】Day34—第八章 贪心算法 part03

    题目链接:1005. K 次取反后最大化的数组和 贪心思路 : 先对数组中的元素进行排序 遍历数组,如果 当前遍历的位置值 0 k0 直接变号,之后对 k 进行 -- 如果不小于 0 ,此时需要先排序,判断 k 是否为奇数,如果是奇数直接对最小位进行取反 最终遍历数组求和 ⭐ K 次取反后最

    2024年04月27日
    浏览(44)
  • 代码随想录——回溯

    代码随想录——回溯 回溯的本质就是递归遍历,但在完成某一条路之后会撤回到上一层,然后重新选择另一条路继续遍历,是一个比较低效的算法,能进行提升的方式就是剪枝。 组合 链接:https://leetcode.cn/problems/combinations/description/ vectorvector int 作为最终返回的结果,vector

    2024年01月19日
    浏览(117)
  • 代码随想录打卡第34天

    2024年02月11日
    浏览(89)
  • 代码随想录二刷 |回溯 |分割回文串

    131.分割回文串 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。 返回 s 所有可能的分割方案。 示例: 输入: “aab” 输出: [ [“aa”,“b”], [“a”,“a”,“b”] ] 回溯三部曲 递归函数参数 全局变量数组path存放切割后回文的子串,二维数组result存放结果集 参数

    2024年01月24日
    浏览(78)
  • 代码随想录-回溯算法(分割问题)|ACM模式

    目录 前言: 131. 分割回文串 题目描述: 输入输出描述: 思路和想法: 93. 复原 IP 地址 题目描述: 输入输出描述: 思路和想法:          回溯算法中的分割问题,是可以抽象为组合问题的,其中模拟切割线、切割问题中递归如何终止以及递归循环中如何截取子串,是我们

    2024年02月15日
    浏览(56)
  • 代码随想录-回溯算法(子集问题)|ACM模式

    目录 前言: 78. 子集 题目描述: 输入输出描述: 思路和想法: 90. 子集 II 题目描述: 输入输出描述: 思路和想法: 491. 递增子序列 题目描述: 输入输出描述: 思路和想法: 如果把 子集问题、组合问题、分割问题都抽象为一棵树的话, 那么组合问题和分割问题都是收集

    2024年02月15日
    浏览(156)
  • 代码随想录刷题笔记 DAY 29 | 非递减子序列 No.491 | 全排列 No.46 | 全排列 II No. 47

    01. 非递减子序列(No. 491) 题目链接 代码随想录题解 1.1 题目 给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种

    2024年02月21日
    浏览(44)
  • 代码随想录阅读笔记-回溯【电话号码的字母组合】

    题目 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 示例: 输入:\\\"23\\\" 输出:[\\\"ad\\\", \\\"ae\\\", \\\"af\\\", \\\"bd\\\", \\\"be\\\", \\\"bf\\\", \\\"cd\\\", \\\"ce\\\", \\\"cf\\\"]. 说明:尽管上面的答案是按字典序排列的,但是你可以任意

    2024年04月13日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包