【LeetCode: 300. 最长递增子序列 | 暴力递归=>记忆化搜索=>动态规划】

在这里插入图片描述

🚀 算法题 🚀

🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀
🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨
🌲 作者简介:硕风和炜,CSDN-Java领域新星创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享💎💎💎
🌲 恭喜你发现一枚宝藏博主,赶快收入囊中吧🌻
🌲 人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?🎯🎯

🚀 算法题 🚀

在这里插入图片描述

🍔 目录

    • 🚩 题目链接
    • ⛲ 题目描述
    • 🌟 求解思路&实现代码&运行结果
      • ⚡ 暴力递归1
        • 🥦 求解思路
        • 🥦 实现代码
        • 🥦 运行结果
      • ⚡ 暴力递归2
        • 🥦 求解思路
        • 🥦 实现代码
        • 🥦 运行结果
      • ⚡ 记忆化搜索
        • 🥦 求解思路
        • 🥦 实现代码
        • 🥦 运行结果
      • ⚡ 动态规划
        • 🥦 求解思路
        • 🥦 实现代码
        • 🥦 运行结果
      • ⚡ 动态规划 + 二分查找
        • 🥦 求解思路
        • 🥦 实现代码
        • 🥦 运行结果
    • 💬 共勉

🚩 题目链接

  • 300. 最长递增子序列

⛲ 题目描述

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

示例 1:

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
示例 2:

输入:nums = [0,1,0,3,2,3]
输出:4
示例 3:

输入:nums = [7,7,7,7,7,7,7]
输出:1

提示:

1 <= nums.length <= 2500
-104 <= nums[i] <= 104

🌟 求解思路&实现代码&运行结果


⚡ 暴力递归1

🥦 求解思路

  1. 根据题目的意思,让我们求得最长递增子序列的长度是什么,我们可以设计这样一个递归函数,从某一个位置开始,如果当前选择的数字是大于我们之前选择的数字的,那么我们记录长度的变量++,否则,进行下一个位置的判断,之前选择的数不变,记录长度的也不变。
  2. 接下来我们来看一下具体代码的实现。

🥦 实现代码

class Solution {
    
    public int lengthOfLIS(int[] nums) {
        return process(0,nums,0,Integer.MIN_VALUE);
    }

    public int process(int index,int[] nums,int cnt,int pre){
        if(index==nums.length){
            return cnt;
        }
        int max=Integer.MIN_VALUE;
        for(int i=index;i<nums.length;i++){
            if(nums[i]>pre){
                max=Math.max(max,process(i+1,nums,cnt+1,nums[i]));
            }else{
                max=Math.max(max,process(i+1,nums,cnt,pre));
            }
        }
        return max;
    }
}

🥦 运行结果

时间超限,使我们期待的结果!!!
在这里插入图片描述


⚡ 暴力递归2

🥦 求解思路

  1. 上面虽然实现了一个递归版本的题解,时间超限了,是我们期待的结果,但是并不是一个好的递归版本,因为状态参数太多了,不方便都维护。
  2. 接下来我们就再来想一想,还有没有可能设计一个更好的递归函数呢?
  3. 我们可以设计这样一个递归函数,以当前index位置为结尾,递归函数中每次从0到index-1的位置进行选择,如果存在元素小于当前index位置的元素,继续递归调用,下一个位置从当前小于index位置开始,重复该过程,直至结束。
  4. 我们可以看到,这个递归函数比起我们上面设计的递归函数精简不少,接下来我们就来一起看一下具体的实现。

🥦 实现代码

class Solution {
    
    public int lengthOfLIS(int[] nums) {
        int max=Integer.MIN_VALUE;
        for(int i=0;i<nums.length;i++){
            max=Math.max(max,process(i,nums));
        }
        return max;
    }

    public int process(int index,int[] nums){
        if(index==nums.length){
            return 0;
        }
        int max=1;
        for(int i=0;i<index;i++){
            if(nums[i]<nums[index]){
                max=Math.max(max,process(i,nums)+1);
            }
        }
        return max;
    }
}

🥦 运行结果

在这里插入图片描述


⚡ 记忆化搜索

🥦 求解思路

  1. 根据我们递归的分析,在递归的过程中会产生重复的子过程,所以我们想到了加一个缓存表,也就是我们的记忆化搜索。

🥦 实现代码

class Solution {
    
    public int lengthOfLIS(int[] nums) {
        int max=Integer.MIN_VALUE;
        int n=nums.length;
        int[] dp=new int[n];
        Arrays.fill(dp,1);
        for(int i=0;i<n;i++){
            max=Math.max(max,process(i,nums,dp));
        }
        return max;
    }

    public int process(int index,int[] nums,int[] dp){
        if(index==nums.length){
            return 0;
        }
        if(dp[index]!=1) return dp[index];
        int max=1;
        for(int i=index;i<nums.length;i++){
            if(nums[i]>nums[index]){
                max=Math.max(max,process(i,nums,dp)+1);
            }
        }
        return dp[index]=max;
    }
}

🥦 运行结果

在这里插入图片描述


⚡ 动态规划

🥦 求解思路

  1. 按照我们之前递归和记忆化搜索的思路,通过动态规划实现出来。

🥦 实现代码

class Solution {
    
    public int lengthOfLIS(int[] nums) {
        int n=nums.length;
        int[] dp=new int[n];
        int max=0;
        Arrays.fill(dp,1);
        for(int index=n-1;index>=0;index--){
            for(int i=index;i<n;i++){
                if(nums[i]>nums[index]){
                    dp[index]=Math.max(dp[index],dp[i]+1);
                }
            }
            max=Math.max(max,dp[index]);
        }
        return max;
    }
}

🥦 运行结果

在这里插入图片描述


⚡ 动态规划 + 二分查找

🥦 求解思路

  1. 因为题目要我们查找的是递增子序列,也就是元素按照严格递增排列的,所以我们可以想到使用二分来进行优化。
  2. 我们将每次查找的结果放到开辟的数组空间中,具体怎么做呢?
  3. 我们可以每次遍历我们nums中的数字x,然后在收集数组的区间内进行查找大于当前x做左侧的位置,最后将该位置设置为x;
  4. 如果此时查找的边界到达了我们此时数组下标位置,说明此时该元素是大于数组中所有元素的,此时数组下标位置继续向右移动。

🥦 实现代码

class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] dp = new int[nums.length];
        int res = 0;
        for (int x : nums) {
            int left = -1, right = res;
            while(left+1 < right){
                int mid = left + ((right - left) >> 1);
                if(dp[mid] < x){
                    left = mid;
                }else{
                    right = mid;
                }
            }
            dp[right] = x;
            if(right == res){
                res++;
            }
        }
        return res;
    }
}

🥦 运行结果

在这里插入图片描述


💬 共勉

最后,我想送给大家一句一直激励我的座右铭,希望可以与大家共勉!
在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

最新Tuxera NTFS2023最新版Mac读写NTFS磁盘工具 更新详情介绍

Tuxera NTFS for Mac是一款Mac系统NTFS磁盘读写软件。在系统默认状态下&#xff0c;MacOSX只能实现对NTFS的读取功能&#xff0c;Tuxera NTFS可以帮助MacOS 系统的电脑顺利实现对NTFS分区的读/写功能。Tuxera NTFS 2023完美兼容最新版本的MacOS 11 Big Sur&#xff0c;在M1芯片…

Python和Java二选一该学啥?

首先我们需要了解Python和 Java分别是什么 根据IEEE Spectrum 2022年编程语言排名前十的分别是&#xff1a;Python&#xff0c;C&#xff0c;C&#xff0c;C#&#xff0c;Java&#xff0c;SQL&#xff0c;JavaScript&#xff0c;R&#xff0c;HTML&#xff0c;TypeScript。从该…

好用的便签APP排行榜前十名?

我是一名时间管理与自律达人&#xff0c;而便签应用程序就是必备与理想的时间管理工具。经过自己长期的总结认为好用的电脑手机云便签APP应用程序应该具备以下功能。 1、多设备同步&#xff1a;可以方便地将电脑和手机之间的数据同步&#xff0c;随时随地管理便签内容。 2、分…

ijkplayer 编译增加支持更多的音视频格式

ijkplayer是B站开源的一款基于ffmpeg的移动端播放器。但为了减少播放器的体积&#xff0c;很多音视频的格式播放默认都是不支持的&#xff0c;需要自己下载ijkplayer源码进行编译。这里以mac环境下android为例&#xff0c;简述ijkplayer的编译过程&#xff0c;以及为了支持更多…

【C++ 二十】STL:遍历、查找、排序、拷贝和替换、算术生成、集合算法

STL&#xff1a;遍历、查找、排序、拷贝和替换、算术生成、集合算法 文章目录 STL&#xff1a;遍历、查找、排序、拷贝和替换、算术生成、集合算法前言1 常用遍历算法1.1 for_each1.2 transform 2 常用查找算法2.1 find2.2 find_if2.3 adjacent_find2.4 binary_search2.5 count…

零、网络基础概述(TCP/IP模型、端口、网关、DNS、ARP、IP编址与子网划分、UDP、VRP)

文章目录 前言一、网络基础1、TCP/IP模型2、端口的作用&#xff1a;3、MAC 地址4、网关&#xff08;gateway&#xff09;5、域名解析服务&#xff08;DNS&#xff09;6、TCP端口、UDP端口区别&#xff1a;7、交换机与路由器 二、ARP 理论1、定义2、查看ARP缓存3、ARP 报文种类&…

深度学习TensorFlow

博主简介 博主是一名大二学生&#xff0c;主攻人工智能研究。感谢让我们在CSDN相遇&#xff0c;博主致力于在这里分享关于人工智能&#xff0c;c&#xff0c;Python&#xff0c;爬虫等方面知识的分享。 如果有需要的小伙伴可以关注博主&#xff0c;博主会继续更新的&#xff0c…

初识Linux+Linux基本指令(一)

目录 一.&#x1f606;计算机与操作系统&#x1f606; 计算机与操作系统发展史简介: 计算机与操作系统的关系: 二.&#x1f604;Linux操作系统&#x1f604; 开源软件的代名词:Linux 非图形化界面的Liunx 三.&#x1f606;Linux基本指令之文件管理篇&#x1f606; 1.操…

SQL sever数据库----基础增删改查操作与where条件限制

where条件限制方法 在SQL sever中使用where语句&#xff0c;可以对各种操作添加限制条件 基础格式为 ———————— where 逻辑表达式 例如限制条件的查询 select 范围 from 表名 where 逻辑表达式 逻辑表达式就是一个判断 如 a > 5 、a6>9、a>5 and b>5 各种…

php+vue+mysql校园大学生兼职信息网站系统

商家功能模块 商家通过点击后台管理&#xff0c;进入页面可以进行首页、个人中心、热门兼职管理、兼职接单管理、学生咨询管理、兼职任务管理、完成评价管理等功能模块&#xff0c;进行相对应操作 兼职接单管理&#xff1a;通过兼职接单管理可以进行获取兼职名称、专业、分类、…

Jenkins 流水线

采用Jenkins的自由风格构建的项目&#xff0c;适合用于测试和学习&#xff0c;主要问题有&#xff1a; 构建过程中整体流程是不可见的&#xff0c;无法确认每个流程花费的时间出现问题不方便快速的定位无法进行版本化管理多个任务中有很多步骤需要重复搭建 Jenkins的Pipeline…

ServletConfig和ServletContext 的介绍和代码实现

目录 ServletConfig ServletConfig 基本介绍 ServletConfig 类能干什么 为什么需要 ServletContext 1. 方案 1-DB 2. 方案 2-ServletCntext 代码实战 ServletContext ServletContext 基本介绍 ServletContext 可以做什么 代码实战 代码实战2 ServletConfig Servle…

SpringBoot单元测试断言 assertions

断言 断言&#xff08;assertions&#xff09;是测试方法中的核心部分&#xff0c;用来对测试需要满足的条件进行验证。这些断言方法都是 org.junit.jupiter.api.Assertions 的静态方法。JUnit 5 内置的断言可以分成如下几个类别&#xff1a; 1、简单断言 2、数组断言 通过 …

原来情感可以这样影响用户体验设计

&#x1f525;情绪的基本情况 Emotion&#xff1a;即刻的生理反应&#xff0c; Feeling&#xff1a;物理的或者心理上的&#xff0c;是emotion经过思考后的 Mood&#xff1a;持续时间更长&#xff0c;是一种状态&#xff0c;受到很多因素影响&#xff08;天气、睡眠&#x…

OpenCV算法加速的一些学习总结

一、概述 算法加速在实际软件层面应用来说 大数据和复杂计算的过程中 算法优化&#xff0c;指降低算法计算复杂度&#xff0c;设计新算法快速求解&#xff0c;比如Hungarian匹配算法。或牺牲一些内存&#xff0c;预计算一些重复计算的过程&#xff0c;减少程序层面的复杂度。 …

微软文字转语音不能试用了,分享三个方法给大家!

最近很多小伙伴告诉我&#xff0c;微软文字转语音不能在线试用了&#xff0c;这是因为微软关闭了官方的使用页面&#xff0c;所以现在不能直接使用微软的网页版进行文字转语音了。 那么我们还有没有更好的方法去“白嫖”微软的文字转语音呢&#xff1f; 答案是肯定的&#xf…

MTU 网卡bond 简介

MTU 最大传输单元MTU&#xff08;Maximum Transmission Unit&#xff0c;MTU&#xff09;&#xff0c;是指网络能够传输的最大数据包大小&#xff0c;以字节为单位。MTU的大小决定了发送端一次能够发送报文的最大字节数。如果MTU超过了接收端所能够承受的最大值&#xff0c;或者…

被裁后找不到工作,本质上是因为原来的能力就配不上高薪,如果技术好,根本不怕被裁,相当于白送n+1!...

被裁员后&#xff0c;能要求公司补缴公积金吗&#xff1f; 一位网友问&#xff1a; 被裁员了&#xff0c;要求公司把历史公积金全部足额缴纳&#xff0c;现在月薪2.3万&#xff0c;但公司每个月只给自己缴纳300元公积金&#xff0c;结果一次补了二十多万&#xff0c;一次性取出…

Linux工具——yum和vim

目录 &#x1f34f;Linux软件包管理器-yum&#x1f34e;yum简介&#x1f34e;rzsz工具&#x1f34e;注意事项&#x1f34e;软件包查看&#x1f34e;如何安装和卸载软件 &#x1f34f;Linux编辑器-vim&#x1f34e;vim的基本概念&#x1f34e;vim的基本操作&#x1f34e;vim正常…

Linux基础——FTP原理与配置

Linux基础——FTP原理与配置 一、文件传输协议——FTP服务二、ftp配置文件解析三、FTP服务器搭建 一、文件传输协议——FTP服务 FTP是典型的C/S结构的应用层协议&#xff0c;需要由服务器软件、客户端软件两个部分共同实现文件传输功能 FTP 连接模式 FTP服务器默认使用TCP协议…