LeetCode 300. 最长递增子序列

题目描述

🔥 300. 最长递增子序列

image-20230306132026731

思路分析

我们可以使用动态规划来解决这个问题。具体思路如下:

  1. 创建一个数组 dp,其中 dp[i] 表示以 nums[i] 结尾的最长递增子序列的长度。
  2. 初始化 dp 数组,每个位置的初始值为 1,因为每个元素至少可以形成一个长度为 1 的递增子序列。
  3. 使用双重循环,外层循环遍历每个元素,内层循环遍历当前元素之前的所有元素:
    • 如果 nums[j] < nums[i],则可以将 nums[i] 加入到以 nums[j] 结尾的递增子序列中,更新 dp[i]max(dp[i], dp[j] + 1)
  4. 最后,返回 dp 数组中的最大值,即为最长递增子序列的长度。

参考代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
func lengthOfLIS(nums []int) int {
	if len(nums) == 0 {
		return 0
	}

	// dp[i] 表示以 nums[i] 结尾的最长递增子序列的长度
	dp := make([]int, len(nums))
	for i := range dp {
		dp[i] = 1 // 每个元素至少可以形成一个长度为 1 的递增子序列
	}

	res := 1

	for i := 1; i < len(nums); i++ {
		for j := 0; j < i; j++ {
			if nums[j] < nums[i] {
				dp[i] = max(dp[i], dp[j]+1)
			}
		}
		res = max(res, dp[i])
	}

	return res
}
  • 时间复杂度O(n^2),其中 n 是数组 nums 的长度。需要两层循环来遍历数组。
  • 空间复杂度O(n),用于存储 dp 数组。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
func lengthOfLIS(nums []int) int {
	if len(nums) == 0 {
		return 0
	}
	// dp[i] 表示以 nums[i] 结尾的最长递增子序列的长度
	dp := make([]int, len(nums))
	dp[0] = 1
	res := 1
	for i := 1; i < len(nums); i++ {
		dp[i] = 1
		for j := 0; j < i; j++ {
			if nums[i] > nums[j] {
				dp[i] = max(dp[i], dp[j]+1)
			}
		}
		res = max(res, dp[i])
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

🍏 点击查看 Java 题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
    public int lengthOfLIS(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n];
        Arrays.fill(dp, 1);
        int res = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[j] < nums[i]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            res = Math.max(res, dp[i]);
        }
        return res;
    }
}
本文作者:
本文链接: https://hgnulb.github.io/blog/2022/87131039
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!