力扣题目
解题思路
java代码
力扣题目:
给你一个整数数组 nums
,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7]
是数组 [0,3,1,6,2,2,7]
的
子序列
。
示例 1:
输入:nums = [10,9,2,5,3,7,101,18] 输出:4 解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
示例 2:
输入:nums = [0,1,0,3,2,3] 输出:4
示例 3:
输入:nums = [7,7,7,7,7,7,7] 输出:1
提示:
1 <= nums.length <= 2500
-104 <= nums[i] <= 104
进阶:
- 你能将算法的时间复杂度降低到
O(n log(n))
吗?
解题思路:
-
lengthOfLIS
方法接受一个整数数组nums
作为参数,并返回最长上升子序列的长度。 -
使用了一个一维数组
dp
来存储以每个元素结尾的最长上升子序列的长度。初始化时,每个位置的dp[i]
都设置为 1,因为任何单个元素都可以构成一个长度为 1 的上升子序列。 -
使用了两层循环来填充
dp
数组:- 外层循环遍历数组
nums
的每个元素。 - 内层循环遍历当前元素之前的所有元素,以确定是否可以形成更长的上升子序列。
- 外层循环遍历数组
-
如果找到一个元素
nums[j]
,它小于当前元素nums[i]
,那么可以将nums[i]
添加到以nums[j]
结尾的上升子序列中,从而形成一个更长的上升子序列。此时,更新dp[i]
为dp[j] + 1
(如果dp[j] + 1
大于当前的dp[i]
)。 -
在填充完
dp
数组后,通过遍历dp
数组来找到最大的值,这个值就是最长上升子序列的长度。 -
main
方法中,测试了lengthOfLIS
方法,并打印了结果。
java代码:
package org.example.mouth7.today712;
public class Leetcode300 {
public static void main(String[] args) {
int[] nums = {10,9,2,5,3,7,101,18};
System.out.println(lengthOfLIS(nums));
int[] nums2 = {0,1,0,3,2,3};
int res = lengthOfLIS(nums2);
System.out.println(res);
}
//dp[i]表示以nums[i]结尾的最长上升子序列的长度
//时间复杂度O(n^2)
//空间复杂度O(n)
public static int lengthOfLIS(int[] nums)
{
int[] dp = new int[nums.length];
for (int i = 0; i < nums.length; i++)
{
dp[i] = 1;
for (int j = 0; j < i; j++)
{
if (nums[i] > nums[j])
{
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
int res = 0;
for (int i = 0; i < dp.length; i++)
{
res = Math.max(res, dp[i]);
}
return res;
}
}
更多详细内容同步到公众号,感谢大家的支持!
每天都会给刷算法的小伙伴推送明日一题,并且没有任何收费项