代码随想录-刷题第二十九天

news2024/11/23 15:16:31

491. 递增子序列

题目连接:491. 递增子序列

思路:将问题抽象为树形结构,使用回溯法。本题求自增子序列,是不能对原数组进行排序的,排完序的数组都是自增子序列了。所以不能使用之前的去重逻辑!

491. 递增子序列1

HashSet是记录本层元素是否重复使用,新的一层set都会重新定义(清空),所以要知道set只负责本层!

class Solution {
    private List<List<Integer>> res = new ArrayList<>();
    private List<Integer> path = new ArrayList<>();

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

    // 回溯算法主函数
    private void backtracking(int[] nums, int start) {
        if (path.size() >= 2) {
            // 找到一个合法答案
            res.add(new ArrayList<>(path));
        }
        // 使用set来对本层元素进行去重
        HashSet<Integer> used = new HashSet<>();
        // 回溯算法标准框架
        for (int i = start; i < nums.length; i++) {
            // 保证集合中元素都是递增顺序
            if (!path.isEmpty() && path.get(path.size() - 1) > nums[i]) {
                continue;
            }
            // 保证不要重复使用相同的元素
            if (used.contains(nums[i])) {
                continue;
            }
            // 选择 nums[i]
            // 记录这个元素在本层用过了,本层后面不能再用了
            used.add(nums[i]);
            path.add(nums[i]);
            // 递归遍历下一层回溯树
            backtracking(nums, i + 1);
            // 撤销选择 nums[i]
            path.remove(path.size() - 1);
        }
    }
}

46. 全排列

题目链接:46. 全排列

思路:将问题抽象成树形结构,使用回溯法搜索结果。

46.全排列

此时可以感受出排列问题的不同:

  • 每层都是从0开始搜索而不是start
  • 需要used数组记录path里都放了哪些元素了
class Solution {
    private List<List<Integer>> res = new ArrayList<>();
    private List<Integer> path = new ArrayList<>();

    /* 主函数,输入一组不重复的数字,返回它们的全排列 */
    public List<List<Integer>> permute(int[] nums) {
        // 「路径」中的元素会被标记为 true,避免重复使用
        boolean[] used = new boolean[nums.length];
        Arrays.fill(used, false);
        backtracking(nums, used);
        return res;
    }

    // 路径:记录在 path 中
    // 选择列表:nums 中不存在于 path 的那些元素(used[i] 为 false)
    // 结束条件:nums 中的元素全都在 path 中出现
    private void backtracking(int[] nums, boolean[] used) {
        // 触发结束条件
        if (path.size() == nums.length) {
            res.add(new ArrayList(path));
            return;
        }

        for (int i = 0; i < nums.length; i++) {
            // 排除不合法的选择
            if (used[i]) {
                // nums[i] 已经在 path 中,跳过
                continue;
            }
            // 做选择
            path.add(nums[i]);
            used[i] = true;
            // 进入下一层决策树
            backtracking(nums, used);
            // 取消选择
            used[i] = false;
            path.remove(path.size() - 1);
        }
    }
}

另一种解法:

class Solution {
    private List<List<Integer>> res = new ArrayList<>();
    private List<Integer> path = new ArrayList<>();

    // 通过判断path中是否存在数字,排除已经选择的数字
    public List<List<Integer>> permute(int[] nums) {
        backtracking(nums);
        return res;
    }

    private void backtracking(int[] nums) {
        if (path.size() == nums.length) {
            res.add(new ArrayList<>(path));
            return;
        }
        
        for (int i = 0; i < nums.length; i++) {
            // 如果path中已有,则跳过
            if (path.contains(nums[i])) continue;
            path.add(nums[i]);
            backtracking(nums);
            path.remove(path.size() - 1);
        }
    }
}

47. 全排列II

题目链接:47. 全排列 II

思路:将问题抽象成树形结构,同一树层需要去重,同一树枝上也要判断是否使用过(注意这里是如何判断的)

47.全排列II1

一般来说:组合问题和排列问题是在树形结构的叶子节点上收集结果,而子集问题就是取树上所有节点的结果

对于排列问题,树层上去重和树枝上去重,都是可以的,但是树层上去重效率更高!

class Solution {
    private List<List<Integer>> res = new ArrayList<>();
    private List<Integer> path = new ArrayList<>();

    public List<List<Integer>> permuteUnique(int[] nums) {
        // 先排序,让相同的元素靠在一起
        Arrays.sort(nums);
        boolean[] used = new boolean[nums.length];
        Arrays.fill(used, false);
        backtracking(nums, used);
        return res;
    }

    private void backtracking(int[] nums, boolean[] used) {
        if (path.size() == nums.length) {
            res.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) {
                // 标记同⼀树枝nums[i]使⽤过,防止同一树枝重复使用
                path.add(nums[i]);
                used[i] = true;
                backtracking(nums, used);
                // 回溯,说明同⼀树层nums[i]使⽤过,防止下一树层重复
                used[i] = false;// 回溯
                path.remove(path.size() - 1);
            }
        }
    }
}

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

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

相关文章

【人工智能】实验二: 洗衣机模糊推理系统实验与基础知识

实验二: 洗衣机模糊推理系统实验 实验目的 理解模糊逻辑推理的原理及特点&#xff0c;熟练应用模糊推理。 实验内容 设计洗衣机洗涤时间的模糊控制。 实验要求 已知人的操作经验为&#xff1a; “污泥越多&#xff0c;油脂越多&#xff0c;洗涤时间越长”&#xff1b;“…

DDD挤水分和强行加异性为好友-UMLChina建模知识竞赛第4赛季第25轮

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 参考潘加宇在《软件方法》和UMLChina公众号文章中发表的内容作答。在本文下留言回答。 只要最先答对前3题&#xff0c;即可获得本轮优胜。第4题为附加题&#xff0c;对错不影响优胜者…

C++ Qt开发:标准Dialog对话框组件

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍标准对话框QInputDialog、QFileDialog 这两种…

阿里云RDS提示过期释放实例了怎么找到库表

做朋友&#xff0c;不需要资格&#xff01;——《全职猎人》 直截了当 一步到位 ~

Flink系列之:窗口函数Windowing table-valued functions (Windowing TVFs)

Flink系列之&#xff1a;窗口函数Windowing table-valued functions Windowing TVFs 一、窗口函数二、Tumble Windows三、Hop Windows四、Cumulate Windows四、Window Offset 适用流、批 Windows 是处理无限流的核心。 Windows 将流分割成有限大小的“桶”&#xff0c;我们可以…

Android动画(二)——补间动画

目录 介绍 Xml文件定义View动画 补充 alpha_animation.xml&#xff08;透明度&#xff09; rotate_animation.xml&#xff08;旋转&#xff09; scale_animation.xml&#xff08;伸缩&#xff09; translate_animation.xml &#xff08;平移&#xff09; group_animation.…

STM32迪文屏图标控件保姆级教程

要主图的去末尾&#xff0c;末尾福利图在等着你~~~ 文章目录 前言 开发环境 二、使用步骤 1.添加图标控件 2.设置图标属性 3.图标库ICL文件生成 4.单片机程序编写 容易踩得坑 一、前言 本篇文章主要介绍了在DGBUS平台上使用图标变量的步骤。首先需要在DGBUS中添加一个图标变量控…

项目抛异常:‘Date‘ 不是可以识别的 内置函数名称。 关键字 ‘AS‘ 附近有语法错误。

今天在解决公司C#项目bug问题&#xff0c;顺便记录一下问题及解决方案。入库日报表和出库日报表执行查询失败&#xff1a; ‘DATE’ 不是可以识别的 内置函数名称。 问题截图如下&#xff1a; 这个错误信息看起来是由于在执行远程方法 SIE.WMS.Statistics.StatisticsControll…

Windows 10如何关闭系统自动更新(实用教程)

本章教程&#xff0c;用最简洁的方式介绍在windows10中如何关闭系统自动更新。 目录 一、关闭自动更新服务 二、关闭自动更新组策略 一、关闭自动更新服务 1、 winr 2、services.msc 3、找到并双击 Windows Update 修改启动类型为禁用 二、关闭自动更新组策略 1、winr 2、gp…

【算法Hot100系列】最长回文子串

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

前端已死,网安当立。

随着人工智能和低代码的崛起&#xff0c;“前端已死”的声音逐渐兴起。前端已死&#xff1f;尊嘟假嘟&#xff1f;快来发表你的看法吧&#xff01; 此为内容创作模板&#xff0c;在发布之前请将不必要的内容删除 一、为什么会出现“前端已死”的言论 “前端已死”的言论通常…

结构体基础全家桶(1)创建与初始化

目录 结构体概念&#xff1a; 结构体类型&#xff1a; 结构体变量的创建&#xff1a; 定义结构体变量的三种方式&#xff1a; 结构体变量的引用&#xff1a; 结构体变量的初始化: 结构体数组&#xff1a; 结构体数组定义&#xff1a; 结构体数组初始化&#xff1a; 结…

MySQL中的时间函数整理汇总

1.获取当前时间 -- 获取当前时间 SELECT NOW(); -- 获取当前日期 SELECT CURDATE(); -- 获取当前时分秒 SELECT CURTIME(); 2.获取对应日期对应的年/月/日/月份名/星期数 -- 返回对应日期对应的年/月/日/月份名/星期数 select year(now())as 年,month(now())as 月,day(now())…

Java Wait Notify

概念 所有对象继承Object方法 用于同步资源锁控制等待以及唤醒 Demo&#xff1a; Message 类同步资源 Waiter 持有Msg&#xff0c;New两个线程Waiter等待 Notifier 持有Msg&#xff0c;通过Msg通知Waiter线程继续 实战 package com.example.demo.java.base.wait;/*** messa…

LeetCode-克服链表不能随机访问的问题

1.重排链表 题目描述&#xff1a; 给定一个单链表 L 的头节点 head &#xff0c;单链表 L 表示为&#xff1a; L0 → L1 → … → Ln - 1 → Ln 请将其重新排列后变为&#xff1a; L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 不能只是单纯的改变节点内部的值&#xff0…

node 版本管理(windows/linux)

windows 下载 Releases coreybutler/nvm-windows GitHub 查看版本 nvm --version 查看已经安装的版本 nvm ls 安装指定版本 nvm install 5.8.0 卸载制定的版本 nvm uninstall 5.8.0 切换使用指定的版本 nvm use 14.21.3 linux 下载 https://github.com/nvm-sh/nvm/t…

Azure Machine Learning - 提示工程简介

OpenAI的GPT-3、GPT-3.5和GPT-4模型基于用户输入的文本提示工作。有效的提示构造是使用这些模型的关键技能&#xff0c;涉及到配置模型权重以执行特定任务。这不仅是技术操作&#xff0c;更像是一种艺术&#xff0c;需要经验和直觉。本文旨在介绍适用于所有GPT模型的提示概念和…

IP代理如何影响网站的速度?代理ip服务器有哪些作用?

目录 前言 一、如何影响速度 二、代理服务器的作用 1. 隐藏真实IP地址 2. 绕过访问限制 3. 分布式访问 4. 数据缓存和加速 总结 前言 IP代理是一种通过在用户和目标网站之间引入代理服务器来访问目标网站的方式。代理服务器充当中间人&#xff0c;将用户的请求转发给目…

基于Hadoop的农产品价格信息检测分析系统

基于Hadoop的农产品价格信息检测分析系统 前言数据处理模块1. 数据爬取2. 数据清洗与处理3. 数据存储 数据分析与检测模块1. 农产品价格趋势分析2. 农产品价格检索3. 不同市场价格对比 创新点 前言 为了更好地了解农产品市场价格趋势和不同市场之间的价格差异&#xff0c;我设…

JavaOOP篇----第一篇

系列文章目录 文章目录 系列文章目录前言一、什么是B/S架构&#xff1f;什么是C/S架构二、Java都有那些开发平台&#xff1f;三、什么是JDK&#xff1f;什么是JRE?四、Java语言有哪些特点五、面向对象和面向过程的区别 前言 前些天发现了一个巨牛的人工智能学习网站&#xff…