当前位置: 首页 > article >正文

代码随想录算法训练营第二九天 | 递增子序列、排列

目录

  • 递增子序列
  • 全排列
  • 全排列 II

LeetCode 491.递增子序列
LeetCode 46.全排列
LeetCode 47.全排列 II

递增子序列

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

同一父节点下的同层上使用过的元素就不能再使用了

在这里插入图片描述
题目要求递增子序列大小至少为2,终止条件要限定。

class Solution {

    List<List<Integer>> result = new ArrayList<>();
    List<Integer> path = new ArrayList<>();

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

    private void backTracking(int[] nums, int startIndex) {
        if (path.size() > 1) {    // 至少有两个元素 
            result.add(new ArrayList<>(path));
        }
        if (startIndex >= nums.length) {
            return;
        }
        // 存储去重元素的哈希表
        HashSet<Integer> hs = new HashSet<>();

        for (int i = startIndex; i < nums.length; i++) {
            if(!path.isEmpty() && path.get(path.size() -1) > nums[i] || hs.contains(nums[i])) {
                continue;
            }
            hs.add(nums[i]);  // 记录这个元素在本层用过了,本层后面不能再用了
            path.add(nums[i]);
            backTracking(nums, i + 1);
            path.removeLast();
        }
    }
}

全排列

在这里插入图片描述

每层都是从0开始搜索而不是startIndex

需要used数组记录path里都放了哪些元素了

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

    private void backTracking(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]);
            backTracking(nums);
            path.removeLast();
            used[i] = false;
        }
    }
}

全排列 II

给定一个可包含重复数字的序列,要返回所有不重复的全排列

去重一定要对元素进行排序,这样我们才方便通过相邻的节点来判断是否重复使用了。

对同一树层,前一位(也就是nums[i-1])如果使用过,那么就进行去重。

组合问题和排列问题是在树形结构的叶子节点上收集结果,而子集问题就是取树上所有节点的结果。
在这里插入图片描述

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> path = new ArrayList<>();
    boolean[] used;
    public List<List<Integer>> permuteUnique(int[] nums) {
        used = new boolean[nums.length];
        // 加标志数组,用来辅助判断同层节点是否已经遍历
        Arrays.fill(used, false);
        // 为了将重复的数字都放到一起,所以先进行排序
        Arrays.sort(nums);
        backTracking(nums);
        return result;
    }   

    private void backTracking(int[] nums) {
        if (path.size() == nums.length) {
            result.add(new ArrayList<>(path));
            return;
        }

        for (int i = 0; i < nums.length; i++) {
            // used[i - 1] == true,说明同⼀树⽀nums[i - 1]使⽤过
            // used[i - 1] == false,说明同⼀树层nums[i - 1]使⽤过
            // 如果同⼀树层nums[i - 1]使⽤过则直接跳过
            if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {
                continue;
            }

            // 如果同⼀树⽀nums[i]没使⽤过开始处理
            if (used[i] == false) {
                used[i] = true;     // 标记同⼀树⽀nums[i]使⽤过,防止同一树枝重复使用
                path.add(nums[i]);
                backTracking(nums);
                path.removeLast(); // 回溯,说明同⼀树层nums[i]使⽤过,防止下一树层重复
                used[i] = false;
            }
        }
    }
}

http://www.kler.cn/news/234720.html

相关文章:

  • 【C++第二阶段】空指针访问成员函数常成员函数常成员属性
  • 【电路笔记】-串联电感
  • 使用C#快速创建一个非常实用的桌面应用程序
  • python笔记12
  • Shell - 学习笔记 - 2.11 - Shell数组:Shell数组定义以及获取数组元素
  • 使用Express 构建高效的Web应用程序
  • c++ STL系列——(四)queue
  • 在C++的union中使用std::string(非POD对象)的陷阱
  • 数字图像处理与Python语言实现-常见图像特效(二)
  • 振荡器设计
  • C#系列-多线程(4)
  • 极狐GitLab 使用阿里云作为 OmniAuth 身份验证 provider
  • springboot175图书管理系统
  • spring 常用的注入方式有哪些?spring 中的 bean 是线程安全的吗?spring 事务实现方式有哪些?
  • 酷开科技荣获“消费者服务之星”称号后的未来展望
  • 鸿蒙harmony--TypeScript函数详解
  • 【JAVA WEB】 百度热榜实现 新闻页面 Chrome 调试工具
  • django报错:Cannot use ImageField because Pillow is not installed
  • 设计模式-职责链模式Chain of Responsibility
  • rediss集群 三主三从集群模式
  • nginx添加lua模块
  • Learn LaTeX 015 - LaTex Typeset 抄录
  • 2.11 运算符
  • Stable Diffusion 模型下载:Samaritan 3d Cartoon(撒玛利亚人 3d 卡通)
  • 一键打造属于自己漏扫系统
  • [缓存] - Redis
  • ChatGPT高效提问—prompt常见用法
  • Netty应用(六) 之 异步 Channel
  • Flink从入门到实践(三):数据实时采集 - Flink MySQL CDC
  • C#在窗体正中输出文字以及输出文字的画刷使用