最长递增子序列问题

196 阅读2分钟

「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」。

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

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

Leecode

一、分析

子序列:可以不连续

[4,1,3,2,3,9,5,6]:选 1,2,3,5,6

dp[i]:子序列必须以i位置的数结尾的情况下,最长递增子序列是多长

max(dp[i])

O(N²) -> dp

  • [4,1,3,2,3,9,5,6] => [1,1,2,2,3,4,4,5]

  • 当前位置与左边一次比较,从小的dp中选出dp最大值,当前位置的值 = 左边dp最大值 + 1

O(N * logN):最优解

  • i位置,左边遍历一下找到比我小的最大的dp值 + 1,这样时间复杂度还是O(N²)
  • 找到i位置dp值不通过遍历,二分O(N * logN)
  • end[i]:目前所有长度为i+1的递增子序列最小结尾是end[i]

有效区

二、实现

    // 时间复杂度O(N²)
    public static int lengthOfLIS(int[] arr) {
        if (arr == null || arr.length == 0) {
            return 0;
        }
        int[] dp = new int[arr.length];
        dp[0] = 1;
        int maxans = 1;
        for (int i = 1; i < arr.length; i++) {
            dp[i] = 1;
            for (int j = 0; j < i; j++) {
                if (arr[i] > arr[j]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            maxans = Math.max(maxans, dp[i]);
        }
        return maxans;
    }

     // 时间复杂度O(N*logN)
    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;
    }

三、总结

模仿(先人的东西不是那么好想的!)

慢慢培养敏感度

扩展:俄罗斯套娃问题

(长度,高度):先长度从小到大排序,再高度从大到小排序

(7,2) (5,6) (1,3) (1,5) (1,2) (5,4) (7,6)

[1,5] [1,3] [1,2] [5,6] [5,4] [7,6] [7,2]

[5,3,2,6,4,6,2]:最长子序列就是能套几层

俄罗斯套娃.png