栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

算法——》最长递增子序列(LIS)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

算法——》最长递增子序列(LIS)

参考链接:
leetcode——》最长递增子序列
leetcode中文——》最长递增子序列

给你一个整数数组 nums ,找到其中 最长 严格 递增子序列 的长度。

子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。
例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

分析过程

整数数组 nums :[3 , 1 , 2 , 6 , 4 , 5]
数组下标 : 0 1 2 3 4 5
最长递增子序列 : [1 , 2 , 3 , 5]
长度 :4

整数数组 nums :[6 , 3 , 1 , 3 , 4 , 9]
数组下标 : 0 1 2 3 4 5
最长递增子序列 : [1 , 3 , 4]
长度 :3

解答过程一

整数数组 nums :[3 , 1 , 2 , 6 , 4 , 5]
数组下标 : 0 1 2 3 4 5
辅助数组dp :[ 1 , 1 , 2 , 3 , 3 , 4 ]
最长递增子序列 : [1 , 2 , 4 , 5 ]
长度 :4

根据整数数组 nums,生成辅助数组 dp

dp[0] = 以mus[0]为结尾的最长递增子序列长度 = [3] = 1
dp[1] = 以mus[1]为结尾的最长递增子序列长度 = [1] = 1
dp[2] = 以mus[2]为结尾的最长递增子序列长度 = [1,2] = 2
dp[3] = 以mus[3]为结尾的最长递增子序列长度 = [1,2,6] = 3
dp[4] = 以mus[4]为结尾的最长递增子序列长度 = [1,2,4] = 3
dp[5] = 以mus[5]为结尾的最长递增子序列长度 = [1,2,4,5] = 4
解答过程二

整数数组 nums :[3 , 2 , 1 , 4 , 6 , 5 ]
数组下标 : 0 1 2 3 4 5
辅助数组dp :[1 , 1 , 1 , 2 , 3 , 3 ]
辅助数据ends :[ 1 , 4 , 5]
最长递增子序列 : [1 , 4 , 5 ]
长度 :3

根据整数数组 nums,生成辅助数组 ends (只是为了给dp加速,它不是最长递增子序列)

ends[i] = 在所有长度为i+1的递增子序列里,最小的结尾

  dp[0] = 1
ends[0] = 3 = 在所有长度为1的递增子序列里,最小的结尾是3

  dp[1] = 1 
ends[0] = 2 = 在所有长度为1的递增子序列里,最小的结尾原来是3,现在变成2

  dp[2] = 1
ends[0] = 1 = 在所有长度为1的递增子序列里,最小的结尾原来是2,现在变成1

  dp[3] = 2
ends[1] = 4 = 在所有长度为2的递增子序列里,最小的结尾是4

  dp[4] = 3
ends[2] = 6 = 在所有长度为3的递增子序列里,最小的结尾是6

  dp[5] = 3
ends[2] = 5 = 在所有长度为3的递增子序列里,最小的结尾是原来6,现在变成5

整数数组 nums :[4 , 1 , 2 , 6 , 4 , 7 , 3 ]
数组下标 : 0 1 2 3 4 5 6
辅助数组dp :[1 , 1 , 2 , 3 , 3 , 4 , 3 ]
辅助数据ends :[ 1 , 2 , 3 , 7]
最长递增子序列 :[ 1 , 2 , 4 , 7]
长度 :4

根据整数数组 nums,生成辅助数组 ends  (只是为了给dp加速,它不是最长递增子序列)

ends[i] = 在所有长度为i+1的递增子序列里,最小的结尾
    
  dp[0] = 1    
ends[0] = 4 = 在所有长度为1的递增子序列里,最小的结尾是4

  dp[1] = 1
ends[0] = 1 = 在所有长度为1的递增子序列里,最小的结尾原来是4,现在变成1

  dp[2] = 3
ends[1] = 2 = 在所有长度为2的递增子序列里,最小的结尾是2

  dp[3] = 3
ends[2] = 6 = 在所有长度为3的递增子序列里,最小的结尾是6

  dp[4] = 3
ends[2] = 4 = 在所有长度为3的递增子序列里,最小的结尾原来是6,现在变成4

  dp[5] = 4
ends[3] = 5 = 在所有长度为4的递增子序列里,最小的结尾是7

  dp[6] = 3
ends[2] = 3 = 在所有长度为3的递增子序列里,最小的结尾原来是4,现在变成3

整数数组 nums :[5 , 6 , 7 , 1 , 2 , 3 , 4 ]
数组下标 : 0 1 2 3 4 5 6
辅助数组dp :[1 , 2 , 3 , 1 , 2 , 3 , 4 ]
辅助数据ends :[ 1 , 2 , 3 , 4]
最长递增子序列 :[ 1 , 2 , 3 , 4]
长度 :4

根据整数数组 nums,生成辅助数组 ends  (只是为了给dp加速,它不是最长递增子序列)

ends[i] = 在所有长度为i+1的递增子序列里,最小的结尾
    
  dp[0] = 1    
ends[0] = 5 = 在所有长度为1的递增子序列里,最小的结尾是5

  dp[1] = 2
ends[0] = 1 = 在所有长度为2的递增子序列里,最小的结尾是6

  dp[2] = 3
ends[1] = 7 = 在所有长度为3的递增子序列里,最小的结尾是7

  dp[3] = 1
ends[2] = 1 = 在所有长度为1的递增子序列里,最小的结尾原来是5,现在变成1

  dp[4] = 2
ends[2] = 2 = 在所有长度为2的递增子序列里,最小的结尾原来是6,现在变成2

  dp[5] = 3
ends[3] = 3 = 在所有长度为3的递增子序列里,最小的结尾原来是7,现在变成3

  dp[6] = 4
ends[2] = 4 = 在所有长度为4的递增子序列里,最小的结尾是4
代码示例
public class Code03_LIS {

    public static int lengthOfLIS(int[] arr) {
        if (arr == null || arr.length == 0) {
            return 0;
        }
        int[] ends = new int[arr.length];
        ends[0] = arr[0];
        int right = 0;
        int l = 0;
        int r = 0;
        int m = 0;
        int max = 1;
        for (int i = 1; i < arr.length; i++) {
            l = 0;
            r = right;
            while (l <= r) {
                m = (l + r) / 2;
                if (arr[i] > ends[m]) {
                    l = m + 1;
                } else {
                    r = m - 1;
                }
            }
            right = Math.max(right, l);
            ends[l] = arr[i];
            max = Math.max(max, l + 1);
        }
        return max;
    }

}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/867118.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号