算法-动态规划-最长递增子序列

算法-动态规划-最长递增子序列

1 题目概述

1.1 题目出处

https://leetcode.cn/problems/longest-increasing-subsequence/

1.2 题目描述

2 动态规划

2.1 思路

思考如果以dpi表示i位置的字符的最长递增子序列长度,那么很难找到dpi和dpi-1的关系,因为dpi没有携带是否取当前位置字符的信息。

那么我们以dpi表示以位置i结尾的字符的最长递增子序列长度,那么就可以找到dpi和dpi-1、dpi-2 ...的关系,只要numsj < numsi,则j 和 i就能组成递增子序列 ,我们从i-1比较到0,取dpj最大值+1作为dpi的值即可。

2.2 代码

java 复制代码
class Solution {
    int result = 0;
    public int lengthOfLIS(int[] nums) {
        if (nums.length == 0) {
            return result;
        }
        // 表示以指定位置结尾的最长递增子序列
        int[] dp = new int[nums.length];
        for (int i = 0; i < dp.length; i++) {
            dp[i] = 1;
            for (int j = i - 1; j >= 0; j--) {
                if (nums[j] < nums[i]) {
                    dp[i] = Math.max(dp[j] + 1, dp[i]);
                }
            }
            result = Math.max(result, dp[i]);
        }
        return result;
    }

}

2.3 时间复杂度

O(N^2)

2.4 空间复杂度

O(N)

3 二分查找

3.1 思路

3.2 代码

java 复制代码
class Solution {
    public int lengthOfLIS(int[] nums) {
        List<Integer> resultList = new ArrayList<>();
        resultList.add(nums[0]);
        for (int i = 1; i < nums.length; i++) {
            int lastIndex = resultList.size() - 1;
            if (nums[i] < resultList.get(lastIndex)) {
                // 比当前子序列尾元素还小,需要替换放入合适位置
                // 规则是替换掉resultList中最小的比当前元素nums[i]大的元素
                int m = 0, n = lastIndex;
                while (m < n) {
                    int mid = (m + n) / 2;
                    if (resultList.get(mid) < nums[i]) {
                        m = mid + 1;
                    } else if (resultList.get(mid) > nums[i]) {
                        n = mid - 1;
                    } else {
                        m = mid;
                        break;
                    }
                }
                if (nums[i] <= resultList.get(m)) {
                    resultList.set(m, nums[i]);
                } else {
                    resultList.set(m + 1, nums[i]);
                } 
                
            } else if (nums[i] > resultList.get(lastIndex)) {
                // 直接加入上升序列
                resultList.add(nums[i]);
            }
        }
        return resultList.size();
    }
}

3.3 时间复杂度

O(NlogN)

3.4 空间复杂度

O(K) K为最长子序列长度

参考文档

相关推荐
Fuyo_111941 分钟前
C++ AVL树保姆级详解:从平衡因子到四大旋转机制
java·c++·算法
jktantan1 小时前
每个节点 41 字节:把一棵百万节点树拆进 14 个 typed array
前端·javascript·vue.js·算法·typescript
揽星河..1 小时前
【C语言】猜数字游戏
c语言·算法·游戏
LabVIEW开发2 小时前
CTM-3 红外测温仪 + LabVIEW 温度怎么测?
算法·labview·测试·labview程序
纪念 2292 小时前
C++算法(六)
开发语言·c++·算法
Dumbness3 小时前
UIA 读微信群消息没有 id,怎么判断哪条是新的:后缀对齐在翻历史和撤回时整屏重报
python·算法
taka3 小时前
从 24x 到 141x:我用纯 Python 零依赖项目,扒开了 GPU 加速的性能黑洞
算法
UIU1144 小时前
P16237 [蓝桥杯 2026 省 B] 应急布线
数据结构·c++·算法·蓝桥杯
旖旎夜光4 小时前
LeetCode 315: 算右侧小于当前元素的个数(归并排序) —— 题解
c++·学习·算法·leetcode·排序算法
像风一样自由20204 小时前
2.如何用FastAPI把一个Python算法封装成HTTP服务
python·算法·fastapi