【中等】力扣算法题解析LeetCode300:最长递增子序列
LeetCode 300题要求计算数组的最长递增子序列(LIS)。采用贪心+二分查找策略,维护一个严格递增的tail数组,tail[i]记录长度为i+1的LIS的最小末尾值。遍历时,若当前数大于tail末尾则扩展数组,否则二分查找替换位置,确保tail始终最优。算法时间复杂度为O(n log n),空间复杂度O(n)。Java实现通过二分优化替换操作,最终tail长度即为LIS长度,高效满足进阶要
·
题目来源:LeetCode300:最长递增子序列
问题抽象: 给定一个整数数组 nums,要求计算并返回该数组中 最长严格递增子序列(Longest Increasing Subsequence, LIS)的长度,满足以下核心需求:
-
子序列定义:
- 严格递增:序列中每个后续元素 严格大于 前一个元素(即
nums[i] > nums[j]对所有i > j成立); - 非连续性:子序列可从数组中 非连续 选取(通过删除部分元素实现),但必须保持原始顺序。
- 严格递增:序列中每个后续元素 严格大于 前一个元素(即
-
计算目标:
- 返回最长递增子序列的长度(整数
≥1); - 结果无需输出具体子序列(仅需长度)。
- 返回最长递增子序列的长度(整数
-
输入约束:
- 数组长度
1 ≤ n ≤ 2500,元素值-10^4 ≤ nums[i] ≤ 10^4; - 时间复杂度 O(n log n)(需优于暴力法
O(n^2)); - 空间复杂度 O(n)(存储动态规划状态或贪心序列)。
- 数组长度
-
边界处理:
- 单元素数组:输出
1(如[5]); - 全降序数组:输出
1(如[5,4,3]中每个元素自成子序列); - 全相同元素:输出
1(如[2,2,2]因非严格递增); - 大值波动:如
[0,8,4,12,2,10]→ 最长子序列[0,4,10]或[0,2,10]→ 长度3。
- 单元素数组:输出
输入:整数数组 nums
输出:最长递增子序列长度(整数)。
解题思路
贪心 + 二分查找(时间复杂度 O(n log n))
- 核心思想:维护一个数组
tail,其中tail[i]表示长度为i+1的最长递增子序列的末尾元素的最小值。该数组严格递增。 - 遍历数组:
- 若当前元素
num大于tail的最后一个元素,则将其加入tail末尾(表示最长递增子序列长度增加)。 - 否则,在
tail中二分查找第一个大于等于num的位置,将其替换为num(保证相同长度的子序列末尾元素最小)。
- 若当前元素
- 最终结果:
tail的长度即为最长递增子序列的长度。
优势: 二分查找确保时间复杂度为 O(n log n)。 仅需一个额外数组,空间复杂度为 O(n)。
代码实现(Java版)🔥点击下载源码
class Solution {
public int lengthOfLIS(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
int n = nums.length;
int[] tail = new int[n]; // 存储长度为 i+1 的最长递增子序列的最小末尾值
int len = 0; // 当前 tail 的有效长度
for (int num : nums) {
// 如果 num 大于 tail 的最后一个元素,直接添加到末尾
if (len == 0 || num > tail[len - 1]) {
tail[len++] = num;
} else {
// 二分查找第一个大于等于 num 的位置
int left = 0, right = len - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (tail[mid] < num) {
left = mid + 1;
} else {
right = mid;
}
}
// 替换该位置的元素
tail[left] = num;
}
}
return len;
}
}
代码说明
- 初始化:
tail数组存储不同长度递增子序列的最小末尾值,初始长度为0。
- 遍历数组:
- 若当前元素
num大于tail的末尾元素,则扩展tail(长度len++)。 - 否则,通过二分查找在
tail[0..len-1]中找到第一个大于等于num的位置left,并替换tail[left] = num。
- 若当前元素
- 二分查找细节:
- 使用左闭右闭区间
[left, right],确保高效定位。 - 循环终止条件
left < right保证精确找到目标位置。
- 使用左闭右闭区间
- 返回值:
len即为最长递增子序列的长度。
亮点:
- 贪心策略保证最小末尾值,减少后续元素插入的阻碍。
- 二分查找优化替换操作至
O(log n)。 - 仅需单次遍历和线性空间,满足进阶要求。
提交详情(执行用时、内存消耗)

更多推荐

所有评论(0)