LeetCode:300.最长递增子序列
1.思路
dp[i]的状态表示以nums[i]为结尾的最长递增子序列的个数。
dp[i]有很多个,选择其中最大的dp[i]=Math.max(dp[j]+1,dp[i])
2.代码实现
1class Solution {
2 public int lengthOfLIS(int[] nums) {
3 int[] dp = new int[nums.length];
4 Arrays.fill(dp, 1);
5 for (int i = 1; i < nums.length; i++) {
6 for (int j = 0; j < i; j++) {
7 if (nums[j] < nums[i]) {
8 dp[i] = Math.max(dp[j] + 1, dp[i]);
9 }
10 }
11 }
12 int res = 0;
13 for (int i = 0; i < nums.length; i++) {
14 res = Math.max(res, dp[i]);
15 }
16 return res;
17 }
18}
3.复杂度分析
时间复杂度:O(n).
空间复杂度:O(n).
LeetCode: 674. 最长连续递增序列
1.思路
后一个状态是由当前状态推出来的,注意边界值...
2.代码实现
1class Solution {
2 public int findLengthOfLCIS(int[] nums) {
3 int[] dp = new int[nums.length];
4 Arrays.fill(dp, 1);
5
6 for (int i = 0; i < nums.length - 1; i++) {
7
8 if (nums[i + 1] > nums[i]) {
9 dp[i + 1] = dp[i] + 1;
10 }
11 }
12 int res = 0;
13 for (int i = 0; i < dp.length; i++) {
14 res = Math.max(dp[i], res);
15 }
16 return res;
17 }
18}
3.复杂度分析
时间复杂度:O(n).
空间复杂度:O(n).
LeetCode:718. 最长重复子数组
1.思路
动规dp[i][j]定义很关键,当前状态需要前一个状态推导出来。
2.代码实现
1// 暴力解法
2class Solution {
3 public int findLength(int[] nums1, int[] nums2) {
4 int maxLength = 0;
5 for (int i = 0; i < nums1.length; i++) {
6 for (int j = 0; j < nums2.length; j++) {
7
8 int length = 0;
9 int p1 = i;
10 int p2 = j;
11
12 while (p1 < nums1.length && p2 < nums2.length && nums1[p1] == nums2[p2]) {
13 length++;
14 p1++;
15 p2++;
16 }
17 maxLength = Math.max(maxLength, length);
18 }
19 }
20 return maxLength;
21 }
22}
23
24// 动规
25class Solution {
26 public int findLength(int[] nums1, int[] nums2) {
27 int res = 0;
28 int[][] dp = new int[nums1.length + 1][nums2.length + 1];
29
30 for (int i = 1; i < nums1.length + 1; i++) {
31 for (int j = 1; j < nums2.length + 1; j++) {
32 if (nums1[i - 1] == nums2[j - 1]) {
33 dp[i][j] = dp[i - 1][j - 1] + 1;
34 res = Math.max(res, dp[i][j]);
35 }
36 }
37 }
38 return res;
39 }
40}
3.复杂度分析
时间复杂度:O(n^2).
空间复杂度:O(n).