问题描述

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

​ 例如:对于数组 {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. Strimzi Kafka Bridge(桥接)实战之一:简介和部署

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于<Strimzi Kafka Bridge( ...

  2. linux常用命令(六)

    用于查找系统文件的相关命令 grep find locate grep:查找文件中符号条件的字符串(关键词) 命令语法:grep [选项] 查找模式 [文件名] 选项 选项含义 -E 模式是一个可扩展 ...

  3. 教育法学第九章单元测试MOOC

    第九章单元测试 返回 本次得分为:100.00/100.00, 本次测试的提交时间为:2020-09-06, 如果你认为本次测试成绩不理想,你可以选择 再做一次 . 1 单选(5分) 作为教师最基本的 ...

  4. 万字长文详解Java线程池面试题

    王有志,一个分享硬核 Java 技术的互金摸鱼侠加入 Java 人的提桶跑路群:共同富裕的Java人 今天是<面霸的自我修养>第 6 篇文章,我们一起来看看面试中会问到哪些关于线程池的问题 ...

  5. Python--乱码转化为中文

    1. \u和\x的含义 \u:代表的是unicode码 \x:代表的是16进制码 2. 代码实现 :\x类型 # \xe4\xb8\xad\xe6\x96\x87 代表的意思是'中文' s = u'\ ...

  6. NW排错

    fist date VM备份失败时: NW server上(linux): > nsradmin >p type : nsr recover > cd /nsr/logs >n ...

  7. 你也许不再需要使用 CSS Media Queries(媒体查询)了

    你也许不再需要使用 CSS Media Queries(媒体查询)了 最近,CSS 引入了一项新功能:Container Queries.它可以替代 Media Queries 并实现 Media Q ...

  8. 基于Electron27+Vite4+React18搭建桌面端项目|electron多开窗口实践

    前段时间有分享一篇electron25+vite4搭建跨桌面端vue3应用实践.今天带来最新捣鼓的electron27+react18创建跨端程序.electron多开窗体(模拟QQ登录窗口切换主窗口 ...

  9. Web Woeker和Shared Worker的使用以及案例

    目录 1.前言 2.介绍 Web Worker 3.使用须知及兼容性 3.1.使用须知 3.2.兼容性 4.使用 Web Worker 4.1.创建 Web Worker 4.2.与主线程通信 4.3 ...

  10. Spring及UML

    深入浅出UML:http://blog.csdn.net/lovelion/article/details/7843437 //Component 1 package umltest.ticketma ...