问题描述

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

​ 例如:对于数组 {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. 《流畅的Python》 读书笔记 231007(第二章第一部分)

    第2章 数据结构 ABC语言是Python的爸爸~ 很多点子在现在看来都很有 Python 风格:序列的泛型操作.内置的元组和映射类型.用缩进来架构的源码.无需变量声明的强类型 不管是哪种数据结构,字 ...

  2. 【matplotlib 实战】--直方图

    直方图,又称质量分布图,用于表示数据的分布情况,是一种常见的统计图表. 一般用横轴表示数据区间,纵轴表示分布情况,柱子越高,则落在该区间的数量越大.构建直方图时,首先首先就是对数据划分区间,通俗的说即 ...

  3. 小景的Dba之路--Oracle用exp导出dmp文件很慢

    小景最近在系统压测相关的工作,其中涉及了Oracle数据库相关的知识,之前考的OCP证书也在此地起了作用.今天的问题是:Oracle用exp导出dmp文件很慢,究竟是什么原因,具体的解决方案都有哪些呢 ...

  4. 低代码平台探讨-MetaStore元数据缓存

    背景及需求 之前提到我们模型驱动的实现选择的是解释型,需要模型的元数据信息,在接到请求后动态处理逻辑. 此外,应用的通用能力中还包括:页面dsl查询,菜单查询等. 而且后期加入触发器,用户自定义api ...

  5. K8s之MySQL实现数据持久化

    这个是一个只写配置及验证的博文: 实现过程: 1. 搭建nfs存储 2. 创建PV 3. 确认PVC 4. 确认PV与PVC的状态 5. 创建pod+svc (service) 6. 进入MySQL数 ...

  6. ELK日志企业案例:(5.3版本)

    1.shell三剑客同居.分析nginx日志: 1)在企业生产环境中,日志内容主要用来做什么? 日志内容主要用于运维人员.开发人员.DBA排错软件服务故障的,因为通过日志内容能够第一时间找到软件服务的 ...

  7. 用结构化思维解一切BUG(1):核心思路

    面对万"卷"世界,有人选择拼命学习新技术,解决眼前的.点状问题:有人提升思维层级,解决未来的.系统问题.您选择什么? 背景 我有10多年编程经验和研发管理经历,虽很久不写代码,但有 ...

  8. JUC并发编程学习(十一)四大函数式接口(必备)

    四大函数式接口(必备) 程序员:泛型.反射.注解.枚举 新时代程序员:lambda表达式.链式编程.函数式接口.Stream流式计算 函数式接口:只有一个方法的接口 @FunctionalInterf ...

  9. coco漫画获取隐藏的图片链接

    网站分析 打开目标网站:https://www.cocomanhua.com/, 随便打开一部漫画: https://www.cocomanhua.com/10330/1/205.html F12 打 ...

  10. 题解 CF1401C

    题目大意: 给定一序列 \(A\),定义当且仅当 \(\gcd(a_i,a_j)=a_{min}\) 时,元素 \(a_i\) 和 \(a_j\) 可以交换. 问当前给定的序列 \(A\) 能否转化为 ...