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

力扣 最长递增子序列

动态规划,二分查找。

题目

由题,从数组中找一个最长子序列,不难想到,当这个子序列递增子序列的数越接近时是越容易拉长的。从dp上看,当遍历到这个数,会从前面的dp选一个最大的数加上当前数,注意这里的dp是每遍历到一个数都会加进去。而这里的dp数组同样是用来维护到某个数时的ans,nums数组是做了比较的,因此也有可能内循环时数组中的一些数是没有做更新的,因此最后一步肯定是加上当前的数后再进行一次与更新的dp比较进行选最大。

时间复杂度:O(n^2),空间复杂度:O(n)。

class Solution {
    public int lengthOfLIS(int[] nums) {
        int n = nums.length, ans = 0;
        int[] f = new int[n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[j] < nums[i]) {
                    f[i] = Math.max(f[i], f[j]);
                }
            }
            f[i]++;
            ans = Math.max(ans, f[i]);
        }
        return ans;
    }
}

接着是更快的,用二分查找的方法,在用二分时用mid去找目标值。而这里每遍历到数组的一个数时,同样可以与tails的数去做比较,注意如果遍历到的数与dp的数做比较时mid在大的一边没有移动过,说明这个数就是大的可以追加到原数组的尾巴,即有位置可以插入。

时间复杂度:O(nlogn),空间复杂度:O(n)。

class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] tails = new int[nums.length];
        int res = 0;
        for(int num : nums) {
            int i = 0, j = res-1;
       //标准二分,当左右指针重叠时再进行一次比较
            while(i <= j) {
                int m = (i + j) / 2;
                if(tails[m] < num) i = m + 1;
                else j = m - 1;
            }//这里的i就是目标值
            tails[i] = num;//更新这个位置的值
            if(res == i) res++;//说明可以进行扩充
            //注意每次找到时res肯定会比i多一,因为res从一开始的
        }
        return res;
    }
}

很典型的一道例题,可以用dp的状态维护,找到前面的状态,不过每到一个数都要dp两次。而二分查找目标值的方法,刚好让比目标值小的存到tails数组,比tails数组大的直接追加,以此来更新最长递增子序列。

http://www.dtcms.com/a/21063.html

相关文章:

  • 149,[4] BUUCTF WEB [GYCTF2020]FlaskApp(不会)
  • 再谈SpringCloud Gateway源码
  • 【算法进阶详解 第一节】树状数组
  • 人工智能在文化遗产保护中的创新:科技与文化的完美融合
  • Redis离线安装
  • springboot项目如何部署到tomcat中
  • 深度学习算法:开启智能时代的钥匙
  • 前端为什么要使用new Promise包裹一个函数
  • 联合概率:定义、公式和示例
  • CRISPR spacers数据库;CRT和PILER-CR用于MAGs的spacers搜索
  • 强化学习-策略梯度算法
  • 复旦:LLM知识问答任务性能预测
  • 【第13章:自监督学习与少样本学习—13.4 自监督学习与少样本学习的未来研究方向与挑战】
  • Spring Boot02(数据库、Redis)---java八股
  • 利用xtquant高效获取财务数据:量化分析的重要补充
  • Python 注解字典操作秘籍:从入门到精通
  • vue3.x的toRefs详细解读以及示例
  • 【第13章:自监督学习与少样本学习—13.1 自监督学习最新进展与实现方法】
  • Java 实现 Redis中的GEO数据结构
  • 基于 Python 和 OpenCV 的酒店客房入侵检测系统设计与实现
  • 服务网格(Istio)核心概念与关键知识点
  • Redis未授权访问漏洞导致getshell
  • 解锁机器学习核心算法 | 决策树:机器学习中高效分类的利器
  • 八、SPI读写XT25数据
  • 【Java进阶篇】——第9篇:Lambda表达式与Stream API
  • 【深度学习】计算机视觉(CV)-目标检测-Faster R-CNN —— 高精度目标检测算法
  • SpringBoot速成(12)文章分类P15-P20
  • QT 读写锁
  • linux常用命令大全(包括抓包、网络检测、路由等,做项目一点点总结而来!)
  • 请解释设备像素、CSS 像素、设备独立像素、DPR、PPI 之间的区别?