问题描述

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

​ 例如:对于数组 {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. oracle优化-分页查询的错误认识

    对于分页查询,上一篇文章总结了实现分页查询的办法.同时给出等价写法,另外在执行计划角度验证SQL的等价性https://www.cnblogs.com/handhead/p/13856505.html ...

  2. Rethinking Point Cloud Registration as Masking and Reconstruction论文阅读

    Rethinking Point Cloud Registration as Masking and Reconstruction 2023 ICCV *Guangyan Chen, Meiling ...

  3. LVS+keepalived配置高可用架构和负载均衡机制(2)

    一.概述 接上文,实际生产场景中,往往存在硬件资源数量的限制,此时需要设置DS节点复用RS节点. 所以往往最常见的架构如下图所示: 3台主机组建真实服务器集群,即3个RS 2个RS兼做DS,构建负载均 ...

  4. Python 作用域:局部作用域、全局作用域和使用 global 关键字

    变量只在创建它的区域内可用.这被称为作用域. 局部作用域 在函数内部创建的变量属于该函数的局部作用域,并且只能在该函数内部使用. 示例:在函数内部创建的变量在该函数内部可用: def myfunc() ...

  5. springMVC---GET、POST原理

    对于 java 程序员来说,特别是遵循 restful 风格的公司,controller 层用得最多的就是 下面这几个注解了: @RequestMapping @PostMapping @GetMap ...

  6. HTML DOM 之一:访问、修改、删除HTML内容

    什么是 DOM? DOM 是 W3C(万维网联盟)的标准. DOM 定义了访问 HTML 和 XML 文档的标准: "W3C 文档对象模型 (DOM) 是中立于平台和语言的接口,它允许程序和 ...

  7. [CTF/Web] PHP 反序列化学习笔记

    Serialize & unserialize 这两个方法为 PHP 中的方法, 参见 serialize 和 unserialize 的官方文档. 以下内容中可能存在 字段, 属性, 成员 ...

  8. 使用DHorse发布SpringBoot项目到K8S

    前言 在介绍DHorse的操作之前,先来介绍一下使用k8s发布应用的步骤,以SpringBoot应用为例进行说明. 1.首先从代码仓库下载代码,比如GitLab: 2.接着进行构建,比如使用Maven ...

  9. python列表添加元素之append()函数和insert()函数

    append()函数 在列表中添加新元素时,最简单的方法就是附加在末尾: list_1 = ['one', 'two', 'three'] print(list_1) list_1.append('f ...

  10. 管易云与网易互客对接集成发货单查询2.0=>编辑订单

    管易云与网易互客对接集成发货单查询2.0=>编辑订单 对接源平台:管易云 管易云是金蝶旗下专注提供电商企业管理软件服务的子品牌,先后开发了C-ERP.EC-OMS.EC-WMS.E店管家.BBC ...