动态规划 —— 最长上升子序列全解

news2024/11/17 3:46:18

题目链接:300. 最长递增子序列 - 力扣(LeetCode)

朴素做法

设元素数组为arr,定义一维数组dp,dp[i]表示以i位置结尾的子序列中,最长的上升子序列的长度

这些子序列可以被划分成哪些子集合呢?

一般集合划分用最后一个位置分类,但这里最后一个位置限定了是i,则可以按照倒数第二个位置进行分类:

  • 没有倒数第二个数
  • 倒数第二个数为arr[0]
  • 倒数第二个数为arr[1]
  • 倒数第二个数为arr[i-1]

在这里插入图片描述

当然不是每一个分类都存在,因为有一个前提倒数第二个数比arr[i]小,才能构成上升子序列

假设倒数第二个数为arr[j],最后一个数为arr[i],则以i结尾的子序列中最长上升子序列的长度,就是

以j结尾的子序列中最长上升子序列长度+1

由于是从左往右推导dp数组,因此在计算dp[i]时,dp[j]的值一定已经计算好

我们尝试所有倒数第二个位置的分类,这些分类的最大值,就是以i为结尾的最长上升子序列长度

dp[i] = max(dp[j]) + 1,arr[j] < arr[i],j从0到i-1

public int lengthOfLIS(int[] arr) {
    int[] dp = new int[arr.length];
    dp[0] = 1;
    int max = 1;
    for (int i = 1;i<arr.length;i++) {
        dp[i] = 1;
        for (int j = 0;j < i;j++) {
            if (arr[i] > arr[j]) {
                dp[i] = Math.max(dp[i], dp[j] + 1);
                max = Math.max(max, dp[i]);
            }
        }
    }
    
    return max;
}

终极做法

朴素做法的时间复杂度为O(N^2),还有更好的做法,时间复杂度能降到O(NlogN)

我们维护一个end数组,end[i]表示:

长度为i的最长上升子序列中,结尾最小是多少

在这里插入图片描述

end数组是单调递增的

假设不是单调底层的,假设i = j + 1,end[i] <= end[j],

长度为i的上升子序列的最小值为end[i],那么这个子序列中第j个数一定小于end[i],而假设中end[j]大于等于end[i],和假设矛盾,因此end数组一定是单调递增的

当我们遍历到第k个数时,之前的数构成的上升子序列信息已经存到end数组中了

假设end中最大的长度为right

如果arr[i]比end[right]大,说明可以将arr[i]压到end[right]后面,构造出一个更长的上升子序列right++

否则在end数组中,找第一个大于等于 arr [i]的数end[l]

因为end数组单调递增,可以用二分法查找

arr[i]替换掉原来的end[l],使其变得更小:

  • 因为arr[i]大于end[l-1],将arr[i]放在end[l]位置不破坏end数组的定义
  • 原来的end[l]大于等于arr[l],替换后只可能使得end[l]更小,维持了长度为l的上升子序列中结尾最小值的定义

代码实现如下:

public int lengthOfLIS(int[] arr) {
    int[] end = new int[arr.length+1];
    int l = 0;
    int r = 0;
    int right = 1;
    end[1] = arr[0];

    for (int i = 1;i<arr.length;i++) {
        l = 1;
        r = right;

        if (arr[i] > end[r]) {
            end[++right] = arr[i];
            continue;
        }

        // 找到大于等于arr[i]的第一个数
        while (l <= r) {
            if (l == r) {
                break;
            }
            int mid = l + r >> 1;
            if (arr[i] <= end[mid]) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }

        // 将arr[i]替换掉原来的end[l],使其更小
        end[l] = arr[i];
    }

    return right;
}

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

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

相关文章

ArcGIS10.8保姆式安装教程,超详细;附安装包

安装前请关闭杀毒软件&#xff0c;系统防火墙&#xff0c;断开网络连接 参考链接&#xff1a;请点击 下载链接&#xff1a; 通过百度网盘分享的文件&#xff1a;ArcGIS10.8zip 链接:https://pan.baidu.com/s/1023fbyQpt6r6U6wtgBuReg 提取码:820w 复制这段内容打开「百度网盘A…

设计模式——解释器模式

解释器模式一、基本思想二、应用场景三、结构图四、代码五、优缺点优点缺点一、基本思想 给分析对象定义一个语言&#xff0c;并定义该语言的文法表示&#xff0c;再设计一个解析器来解释语言中的句子。 二、应用场景 当对象间存在一对多关系&#xff0c;一个对象的状态发生…

ESP32蓝牙+EC11旋转编码器实现对电脑音量控制

ESP32蓝牙EC11旋转编码器实现对电脑音量控制✨本项目基于Arduino开发框架下功能实现。 &#x1f6e0;蓝牙设备添加和连接 ⚡需要有带蓝牙硬件支持的电脑才能实现连接并控制&#xff0c;当然手机也可以连接但是不能实现对手机音量控制&#xff0c; &#x1f33f;以Win10系统电脑…

java 语法基础看这一篇文章就够了

第一章 关键字 关键字的概念1被Java语言赋予了特殊含义&#xff0c;用作专门用途的字符串(单词)关键字特点1关键字中所有字母都是小写常见关键字 classinterfaceenumbyteshortintfloatlongdoublecharbooleanvoidtruefalsenullifelseswitchcasedefaultwhiledoforbreakcontinuer…

数字信号处理音频FIR去噪滤波器(基于MATLAB GUI的开发)

1、内容简介利用MATLAB GUI设计平台&#xff0c;用窗函数法设计FIR数字滤波器&#xff0c;对所给出的含有噪声的声音信号进行数字滤波处理&#xff0c;得到降噪的声音信号&#xff0c;进行时域频域分析&#xff0c;同时分析不同窗函数的效果。将文件解压至一个目录下&#xff0…

第6章 ESP32-Kconfig配置

ESP32-Kconfig配置 1. 新建Kconfig.projbuild文件 2. 写入配置项 新建menu menu "点灯配置"endmenu运行 idf.py menuconfig&#xff0c;结果如下 powershel vscode 可以看到&#xff0c;power shell中文支持上有乱码&#xff0c;所以接下来选择英文 2. 配置menu…

开发实践:一份复杂业务系统的 RESTFul 接口规范

1. 从需求入手 对象&#xff1a;增删改查 对象列表&#xff1a;获取 对象的复杂处理&#xff1a;挖掘、整理、汇总 2. 资源分类 对象型&#xff1a;**/project/1 列表型&#xff1a;**/projects 算法型&#xff1a;**/project/search?input** 3. 设计 URI 3.1. URI 命名…

游戏盾如何防护

什么是游戏盾呢游戏盾是DDoS高防IP产品系列中针对游戏行业的安全解决方案。 游戏盾专为游戏行业定制&#xff0c;针对性解决游戏行业中复杂的DDoS攻击、游戏CC攻击等问题。目前以对抗的形式存在的高防产品形态&#xff0c;也就是防御带宽要大于攻击者的流量。如果你是做运营商商…

设计模式学习(六):Template Method模板方法模式

一、什么是Template Method模式 模板的原意是指带有镂空文字的薄薄的塑料板。只要用笔在模板的镂空处进行临摹&#xff0c;即使是手写也能写出整齐的文字&#xff0c;但是具体写出的文字是什么感觉则依赖于所用的笔。如果使用签字笔来临摹&#xff0c;则可以写出签字似的文字&a…

【ROS2入门】ROS 2 services 概述

大家好&#xff0c;我是虎哥&#xff0c;从今天开始&#xff0c;我将花一段时间&#xff0c;开始将自己从ROS1切换到ROS2&#xff0c;在上一篇中&#xff0c;我们一起了解ROS 2中Topic&#xff0c; 这一篇&#xff0c;我们主要会围绕ROS中另外一个重要的概念“Services ”&…

excel图表技巧:如何在折线图上标注极值

折线图是大家日常工作中经常使用的一类基础图表&#xff0c;作用是体现数据的变化趋势。例如将每月的销售额通过折线图展示出来&#xff0c;数值变化就会很直观&#xff1a;抛开图表的美化&#xff0c;基本上大家做出来的折线图都是上图中的样子&#xff0c;而老菜鸟做出来的折…

<Linux>进度条小程序和git使用详解

进度条小程序和git使用详解 文章目录进度条小程序和git使用详解一、Linux第一个小程序 - 进度条1.\r && \n2.行缓冲3.进度条二、git使用详解1.git概述1.1.历史背景1.2.版本控制1.3.集中式与分布式的区别2.Gitee仓库创建2.1.新建仓库2.2.复制仓库链接2.3.克隆仓库2.4.扩…

Redis基础命令操作四之集合类型HASH

HASH命令 命令举例说明HSETHSET [OUTKEY] [INKEY][INVALUE]集合添加键值对[INKEY][INVALUE]HGETHGET [OUTKEY] [INKEY]获取集合中inkey对应的valueHGETALLHGETALL [OUTKEY]获取集合中所有key,value信息HDELHDEL [OUTKEY] [INKEY]从集合中删除inkey键值对HLENHLEN [OUTKEY]获…

linux部署KubeSphere和k8s集群(二)

上一篇文章讲述了在单个节点上安装 KubeSphere和k8s&#xff0c;这节主要讲解k8s多节点集群部署 第一步&#xff1a;设置主机名称hostname--(3台机器都设置) hostnamectl set-hostname k8s-master hostnamectl set-hostname k8s-node1 hostnamectl set-hostname k8s-node2 第二…

_Linux多线程--生产者消费者模型篇

文章目录1. 为何要使用生产者消费者模型2. 基于BlockingQueue的生产者消费者模型3. C queue模拟阻塞队列的生产消费模型条件变量使用规范简单测试1. BlockQueue (缓存--超市)2. ConProd.cc3. 结果展示升级版测试&&设计与RAII风格的加锁方式1. BlockQueue.hpp2. Task.hp…

MATLAB 实现路由算法详细教程(完整代码+数据)

问题描述&#xff1a;鉴于我们小组成员都来自计通学院&#xff0c;我们对专业知识计算机网络内的路由器进行研究。我们知道在整个互联网中&#xff0c;有着很多个小的无法互相连通的小网络&#xff0c;早在上世纪六十年代&#xff0c;针对不同网络无法互联的问题&#xff0c;路…

IC芯片类元件创建

--摘自凡亿教育 一、VS1003音频芯片 首先&#xff0c;先创建新的元器件库 按箭头所指的即可。 然后&#xff0c;我们右击箭头所指的键&#xff0c;选择第六个矩形。 然后&#xff0c;依次放置管脚 点击箭头所指&#xff0c;既可放置管脚。 由于我们放置管脚的时候&#xff…

python的webdriver应用

本文总结如何使用python的webdriver插件&#xff0c;应用自动化测试以及爬虫抓取数据。工具选择谷歌版本下载&#xff1a;https://www.iplaysoft.com/tools/chrome/webdriver版本&#xff1a;http://npm.taobao.org/mirrors/chromedriver/ 或https://chromedriver.storage.goog…

顺序表学习指南,请查收~

作者&#xff1a;爱塔居的博客_CSDN博客-JavaSE,数据结构领域博主 专栏&#xff1a;数据结构 作者简介&#xff1a;大三学生&#xff0c;希望一起进步&#xff01; 文章目录 目录 文章目录 一、顺序表基本概念 二、练习 一、顺序表基本概念 &#x1f33a;顺序表是用一段物理地…

常用工具的常用操作

写在前面 记录可能用到的各种工具常见技巧。 1&#xff1a;sublime 1.1&#xff1a;操作多列 首先选中要操作的列所在的行&#xff1a; 然后点击selection&#xff0c;spit lines&#xff1a; 接下来移动左右键就可以操作了&#xff0c;删除或者批量添加内容&#xff1a; 1…