LeetCode300.最长递增子序列(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

看了半天,题都看不懂,我也是无语,后来发现,题上有坑,只是告诉你子序列,没有告诉你这个就是它的最长递增子序列,审题呀!

方法一:DFS,过不了

	static int count = 0;
	
	static public int lengthOfLIS(int[] nums) {
		dfs(nums, new ArrayList<>(), 0, 0);
		return count;
	}



	public static void dfs(int[] nums, List<Integer> list, int index, int sum) {
		count = Math.max(sum, count);
		if (nums.length - index + list.size() <= count) {// 剩下的不够了,不需要往下走
			return;
		}
		for (int i = index; i < nums.length; i++) {
			if (list.size() == 0 || list.get(list.size() - 1) < nums[i]) {// 满足递增
				list.add(nums[i]);
				dfs(nums, list, i + 1, sum + 1);
				list.remove(list.size() - 1);
			} else {// 不满足递增,则继续往下寻找能满足递增的值
				dfs(nums, list, i + 1, sum);
			}
		}
	}

方法二:动态规划

我们分析

int[] nums1 = { 5, 7, -24, 12, 13, 2, 3, 12, 5, 6, 35 };

5:前面没有数,为1个长度

7:左有比7小的5,Math.max(dp[0]+1,dp[1]),取2

-24:左有5、7>-24,不满足题意,设长度为1

12:左边的都<12,取他们中间dp最大的+1

13:左边的都<13,取他们中间dp最大的+1

2:前面只有-24<2,取它的dp值+1

3:前面-24,-2<3,取中间dp最大的+1

12:前面5、7、-24、2、3<12,但是根据题意,最多-24、2、3、12或者5、7、12连成子序列,选取最大的dp+1

5:-24,2,3<5,取dp最大的+1

6:5、-24、2、3、5<6,取dp最大的+1

35:左边都比35小,取左边dp最大的+1

LeetCode300.最长递增子序列(Java+动态规划)_第1张图片

// 动态规划
	static public int lengthOfLIS2(int[] nums) {
		if (nums.length == 0) {
			return 0;
		}
		int[] dp = new int[nums.length];
		dp[0] = 1;
		int max = dp[0];
		for (int i = 1; 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);
				}
			}
			max = Math.max(max, dp[i]);
		}
		return max;
	}
}

总结:动态规划我现在做起来真的太难了。

你可能感兴趣的:(LeetCode刷题)