问题描述

​ 有一个数组,它内部的顺序是乱序的,现在要求你找出该数组中的最长的递增子序列长度。

​ 例如:对于数组 {10, 20, 9, 33, 21, 50, 41, 60, 80},它的最长递增子序列为{10, 22, 33, 50, 60, 80},长度为 4

解决思路

  • DP 方案:

    令 \(L(i)\) 表示在 \(i\)​ 位置最长的递增子序列长度.

    • 0 < j < i 并且 arr[j] < arr[i] 时,\(L(i)=1 + max(L(j))\) \((j \in [0, i])\)​

    • i == 0 时, \(L(i) = 1\)​

    • 因此,状态转移方程为

      \[L(i)=\begin{cases}
      1 + max(L(j)) & j \in [0, i] \\
      1 & i = 0 \\
      \end{cases}
      \]
  • 贪心策略和二分搜索:

    • 定义一个数组,这个数组的元素是单调递增的。
    • 贪心策略:每次遇到一个元素将它插入到预先定义的数组中,使得整个数组的增长是最 “缓慢”的。
    • 由于插入后数组的元素元素是有序的,因此下次插入时可以使用二分查找进行替换。

实现

  • DP 方案的实现

    public class Solution {
    public static int lis(int[] array) {
    int len = array.length;
    if (1 == len) return 1; // 边界条件 int ans = 1; // 对任意的数组序列,最少的递增子序列长度至少为 1
    int[] dp = new int[len];
    dp[0] = 1;
    for (int i = 1; i < len; ++i) {
    dp[i] = 1;
    // 从小于 i 的数组索引中找到最大的递增序列长度
    for (int j = 0; j < i; ++j) {
    if (array[i] > array[j])
    dp[i] = Math.max(dp[i], dp[j] + 1);
    } // 与当前的最大递增序列长度进行比较,得到最终的最长递增子序列长度
    ans = Math.max(dp[i], ans);
    } return ans;
    }
    }
  • 贪心策略 + 二分搜索的实现

    class Solution {
    public int lis(int[] array) {
    int len = array.length;
    if (1 == len) return 1; // 边界条件检测 int ans = 1;
    int[] dp = new int[len];
    dp[0] = array[0]; // 存储有序插入结果
    for (int i = 1; i < len; ++i) {
    // 如果当前元素大于定义数组的最大元素,则直接添加它到末尾
    if (array[i] > dp[ans - 1]) {
    dp[ans++] = array[i];
    } else {
    // 查找当前元素的插入位置
    int lo = 0, hi = ans - 1, pos = 0;
    while (lo <= hi) {
    int mid = lo + (hi - lo) / 2;
    if (dp[mid] == array[i]) {
    pos = mid;
    break;
    } else if (dp[mid] > array[i]) {
    hi = mid - 1;
    } else {
    lo = mid + 1;
    pos = lo;
    }
    } dp[pos] = array[i];
    }
    } return ans;
    }
    }

动态规划问题(三)最长递增子序列长度(LIS)的更多相关文章

  1. POJ 2533 - Longest Ordered Subsequence - [最长递增子序列长度][LIS问题]

    题目链接:http://poj.org/problem?id=2533 Time Limit: 2000MS Memory Limit: 65536K Description A numeric se ...

  2. 动态规划----最长递增子序列问题(LIS)

    题目: 输出最长递增子序列的长度,如输入 4 2 3 1 5 6,输出 4 (因为 2 3 5 6组成了最长递增子序列). 暴力破解法:这种方法很简单,两层for循环搞定,时间复杂度是O(N2). 动 ...

  3. 求解最长递增子序列(LIS) | 动态规划(DP)+ 二分法

    1.题目描述     给定数组arr,返回arr的最长递增子序列. 2.举例     arr={2,1,5,3,6,4,8,9,7},返回的最长递增子序列为{1,3,4,8,9}. 3.解答      ...

  4. 最长递增子序列(LIS)(转)

    最长递增子序列(LIS)   本博文转自作者:Yx.Ac   文章来源:勇幸|Thinking (http://www.ahathinking.com)   --- 最长递增子序列又叫做最长上升子序列 ...

  5. 最长递增子序列(LIS)

    最长递增子序列(Longest Increasing Subsequence) ,我们简记为 LIS. 题:求一个一维数组arr[i]中的最长递增子序列的长度,如在序列1,-1,2,-3,4,-5,6 ...

  6. 最长递增子序列问题—LIS

    问题:给定一组数 a0,a0,....,an-1. 求该序列的最长递增(递减)序列的长度. 最长递增子序列长度的求法有O(n^2)和O(nlogn)两种算法. 1.复杂度为O(n^2)的算法. 设L[ ...

  7. 最长公共子序列(LCS)、最长递增子序列(LIS)、最长递增公共子序列(LICS)

    最长公共子序列(LCS) [问题] 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字 ...

  8. [51Nod 1218] 最长递增子序列 V2 (LIS)

    传送门 Description 数组A包含N个整数.设S为A的子序列且S中的元素是递增的,则S为A的递增子序列.如果S的长度是所有递增子序列中最长的,则称S为A的最长递增子序列(LIS).A的LIS可 ...

  9. 动态规划(DP),最长递增子序列(LIS)

    题目链接:http://poj.org/problem?id=2533 解题报告: 状态转移方程: dp[i]表示以a[i]为结尾的LIS长度 状态转移方程: dp[0]=1; dp[i]=max(d ...

  10. 动态规划之最长递增子序列(LIS)

           在一个已知的序列{ a1,a2,……am}中,取出若干数组成新的序列{ ai1, ai2,…… aim},其中下标 i1,i2, ……im保持递增,即新数列中的各个数之间依旧保持原数列中 ...

随机推荐

  1. Mac 下使用 ffmpeg 制作 gif

    Mac 下使用 ffmpeg 制作 gif 公众号文章,gif要求  300帧数以内        .以下是从 mp4 转为 gif 的步骤. 步骤 ffmpeg 是著名的视频处理开源软件 brew ...

  2. Android利用广播监听按下HOME和电源键

    package cc.testhome; import cc.testhome.HomeKeyObserver.OnHomeKeyListener; import cc.testhome.PowerK ...

  3. sql优化的方法总结

    1.对查询进行优化,应该尽量避免全表扫描,首先应考虑在where和order by涉及的列上建立索引 2.应尽量避免在where子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表 ...

  4. 《流畅的Python》 读书笔记 第5章 一等函数 20231025

    第5章 一等函数 第四章相对偏僻,但时间上一样要花我很久,就先跳过了,回头再补.而这个第5章节是非常重要的.只是最近工作有点忙,我读的越来越慢了~继续坚持吧. 在 Python 中,所有函数都是一等对 ...

  5. Redis 6 学习笔记 1 —— NoSQL数据库介绍,Redis常用数据类型

    NoSQL数据库介绍(了解) 技术的分类1.解决功能性的问题:Java.Jsp.RDBMS.Tomcat.HTML.Linux.JDBC.SVN,2.进一步地,解决系统功能扩展性的问题:Struts. ...

  6. JUC并发编程学习笔记(四)8锁现象

    8锁现象 八锁->就是关于锁的八个问题 锁是什么,如何判断锁的是谁 对象.class模板 深刻理解锁 锁的东西无外乎就两样:1.同步方法的调用者,2.Class模板. 同一个锁中,只有当前线程资 ...

  7. Vue源码学习(十五):diff算法(二)交叉比对(双指针)

    好家伙, 本节来解决我们上一章留下来的问题, 新旧节点同时有儿子的情况本章继续解决 1.要做什么? 本章将解决, 1.在相同tag下子元素的替换问题 2.使用双指针进行元素替换, 实现效果如下:   ...

  8. 向量数据库Chroma极简教程

    引子 向量数据库其实最早在传统的人工智能和机器学习场景中就有所应用.在大模型兴起后,由于目前大模型的token数限制,很多开发者倾向于将数据量庞大的知识.新闻.文献.语料等先通过嵌入(embeddin ...

  9. RT-Thread 中 minIni 组件包无法添加的解决方法

    事件 今天在 Env 下添加 minIni 包的时候出现了无法将其添加到工程的情况.借此机会来记录一下如何解决该类问题. 如果你想快速排错可以直接到 [2.minIni 组件出现的问题]查看. 一.准 ...

  10. Python 哈希表的实现——字典

    哈喽大家好,我是咸鱼 接触过 Python 的小伙伴应该对[字典]这一数据类型都了解吧 虽然 Python 没有显式名称为"哈希表"的内置数据结构,但是字典是哈希表实现的数据结构 ...