Day 29 | 回溯 491.递增子序列 、 46.全排列 、47.全排列 II

这篇具有很好参考价值的文章主要介绍了Day 29 | 回溯 491.递增子序列 、 46.全排列 、47.全排列 II。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

491.递增子序列

题目
文章讲解
视频讲解

思路:去重原则:元素,树层不可以重复取,树枝可以。hash这种去重方式不需要回溯

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> path = new LinkedList<>();

    public List<List<Integer>> findSubsequences(int[] nums) {
        backTracing(nums, 0);
        return result;
    }

    private void backTracing(int[] nums, int startIndex) {
        if (path.size() > 1) {
            result.add(new ArrayList(path));
        }
        HashSet<Integer> hash = new HashSet<>();
        for (int i = startIndex; i < nums.length; i++) {
            if (!path.isEmpty() && path.get(path.size() - 1) > nums[i] || hash.contains(nums[i]))//path不为空且比nums中元素大或者之前已在本树层存在过
                continue;//后续还要接着进行比较
            hash.add(nums[i]);//只记录每层的元素是否用过
            path.add(nums[i]);
            backTracing(nums, i + 1);
            path.removeLast();
        }
    }
}

46.全排列

题目
文章讲解
视频讲解

思路:used[i]这种去重方式需要回溯
注意比较两种去重方式 permute(排列)

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> path = new LinkedList<>();
    boolean[] used;

    public List<List<Integer>> permute(int[] nums) {
        if (nums.length == 0)
            return result;
        used = new boolean[nums.length];
        permuteHelper(nums);
        return result;
    }

    private void permuteHelper(int[] nums) {
        if (path.size() == nums.length) {
            result.add(new ArrayList(path));
            //return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (used[i])
                continue;
            used[i] = true;
            path.add(nums[i]);
            permuteHelper(nums);
            path.removeLast();
            used[i] = false;
        }
    }
}

47.全排列 II

题目
文章讲解
视频讲解

思路:去重之前一定做排序,used[i-1] == false(对树层进行去重(视频中讲是一个回溯过程,但还需再理解))或used[i-1] == true(对树枝进行去重)文章来源地址https://www.toymoban.com/news/detail-822749.html

class Solution {
    List<List<Integer>> result = new ArrayList<>(); // 存储最终结果的列表
    List<Integer> path = new LinkedList<>(); // 存储当前路径的列表
    boolean[] used; // 用于标记元素是否被使用过的布尔数组

    public List<List<Integer>> permuteUnique(int[] nums) {
        used = new boolean[nums.length]; // 初始化used数组
        Arrays.fill(used, false); // 将used数组全部初始化为false
        Arrays.sort(nums); // 对输入数组进行排序
        permuteHelper(nums, used); // 调用辅助方法进行排列
        return result; // 返回最终结果
    }

    private void permuteHelper(int[] nums, boolean[] used) {
        if (path.size() == nums.length) { // 如果当前路径长度等于输入数组长度
            result.add(new ArrayList<>(path)); // 将当前路径添加到最终结果中
            return; // 返回
        }
        for (int i = 0; i < nums.length; i++) { // 遍历输入数组
            if (i > 0 && nums[i] == nums[i - 1] && used[i-1] == false) // 如果当前元素与前一个相同且前一个未被使用
                continue; // 跳过当前循环
            if(used[i] == false){ // 如果当前元素未被使用
                used[i] = true; // 标记当前元素为已使用
                path.add(nums[i]); // 将当前元素添加到路径中
                permuteHelper(nums, used); // 递归调用辅助方法
                path.removeLast(); // 移除路径中的最后一个元素
                used[i] = false; // 标记当前元素为未使用
            }
        }
    }
}

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> path = new LinkedList<>();
    boolean[] used;

    public List<List<Integer>> permuteUnique(int[] nums) {
        used = new boolean[nums.length];
        Arrays.fill(used, false);
        Arrays.sort(nums);
        permuteHelper(nums, used);
        return result;
    }

    private void permuteHelper(int[] nums, boolean[] used) {
        if (path.size() == nums.length) {
            result.add(new ArrayList<>(path));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (i > 0 && nums[i] == nums[i - 1] && used[i-1]==true)
                continue;
            if(used[i] == true) continue;//used出现过便不可再取
            used[i] = true;
            path.add(nums[i]);
            permuteHelper(nums, used);
            path.removeLast();
            used[i] = false;
        }
    }
}

到了这里,关于Day 29 | 回溯 491.递增子序列 、 46.全排列 、47.全排列 II的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • [100天算法】-最长递增子序列的个数(day 47)

    思路 代码 JavaScript Code C++ Code 复杂度分析 时间复杂度:$O(N^2)$。N 是数组  nums  的长度。 空间复杂度:$O(N)$。N 是辅助数组  length  和  count  的长度。

    2024年02月07日
    浏览(12)
  • LeetCode46全排列(回溯入门)

    LeetCode46全排列(回溯入门)

    这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 难度:中等 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案 示例 1 示例 2 示例 3 在很多刷题文章和书籍中,此题都被用做回溯算法的第一题,可见该题

    2024年02月10日
    浏览(7)
  • LeetCode.46. 全排列(回溯法入门)

    LeetCode.46. 全排列(回溯法入门)

    写在前面: 题目链接:LeetCode.46. 全排列 编程语言:C++ 题目难度:中等 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1: 输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 示例2: 输入:nums = [0,1] 输出:

    2024年02月06日
    浏览(7)
  • leetcode46. 全排列(回溯算法-java)

    leetcode46. 全排列(回溯算法-java)

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/permutations 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1: 输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 示例 2: 输入:nums = [0,1] 输出:[[0,1],[1,0]]

    2024年02月11日
    浏览(9)
  • 力扣--深度优先算法/回溯算法47.全排列 Ⅱ

    力扣--深度优先算法/回溯算法47.全排列 Ⅱ

    思路分析: 使用DFS算法进行全排列,递归地尝试每个可能的排列方式。 使用 path 向量保存当前正在生成的排列,当其大小达到输入数组的大小时,将其加入结果集。 使用 numvisited 向量标记每个数字是否已经被访问过,以确保每个数字在一个排列中只使用一次。 在递归过程中

    2024年03月13日
    浏览(12)
  • 【算法题】47. 全排列 II

    给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。 示例 1: 输入:nums = [1,1,2] 输出: [[1,1,2],  [1,2,1],  [2,1,1]] 示例 2: 输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]   提示: 1 = nums.length = 8 -10 = nums[i] = 10 来自力扣官方题解

    2024年02月01日
    浏览(19)
  • LeetCode讲解篇之47. 全排列 II

    LeetCode讲解篇之47. 全排列 II

    初始化一个nums中元素是否被访问的数组used、记录还需要递归的深度deep 遍历nums 如果当前元素被访问过或者当前元素等于前一个元素且前一个元素没被访问过就跳过该次遍历 否则选择当前元素,继续递归 直到deep为0,将此次递归选择的数组加入到结果集,退出递归 直到搜索

    2024年01月20日
    浏览(12)
  • 算法leetcode|47. 全排列 II(rust重拳出击)

    给定一个可包含重复数字的序列 nums , 按任意顺序 返回所有不重复的全排列。 1 = nums.length = 8 -10 = nums[i] = 10 面对这道算法题目,二当家的再次陷入了沉思。 要做全排列,就用递归套娃大法,回溯是大方向。 有重复的数字,又要不重复的排列,去重也是必须的了,最慢的方

    2023年04月26日
    浏览(12)
  • day55 最长递增子序列 最长连续递增子序列 最长重复子数组

    day55 最长递增子序列 最长连续递增子序列 最长重复子数组

    题目链接 300 最长递增子序列 题意 找到整数数组nums的最长严格递增子序列的长度(子序列并不改变原始的顺序,但是可以删除元素) 动态规划 动规五部曲 1)dp数组及下标i的含义 dp[i] 表示以nums[i]为结尾的最长递增子序列的长度 2)dp数组初始化 根据定义 长度至少是1  dp

    2024年04月11日
    浏览(16)
  • [100天算法】-全排列 II(day 51)

    时间复杂度: 空间复杂度: JavaScript Code

    2024年02月06日
    浏览(5)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包