首页 > 其他分享 >最长递增子序列

最长递增子序列

时间:2022-11-28 15:33:42浏览次数:53  
标签:信封 int 递增 数组 序列 最长 dp

最长递增子序列

最长递增子序列

传送门

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

动态规划解法

1、确定 base case

数组中的每一个数,不和其他值比时,最初的长度都为1

2、明确 dp 函数/数组的定义

dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列的长度。

public int lengthOfLIS(int[] nums) {
		int len = nums.length;
		//以num[i]结尾的构成的最长递增子序列的长度
		int dp[] = new int[len];
    //base case
		Arrays.fill(dp, 1);
		for(int i=0;i<len;i++) {
			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<len;i++) {
			res = Math.max(res, dp[i]);
		}
		return res;
    }

二分解法

未完待续.....

俄罗斯套娃信封问题

[传送门]( 354. 俄罗斯套娃信封问题 - 力扣(LeetCode) )

给你一个二维整数数组 envelopes ,其中 envelopes[i] = [wi, hi] ,表示第 i 个信封的宽度和高度。

当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。

请计算 最多能有多少个信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。

注意:不允许旋转信封。

这道题目其实是最长递增子序列的一个变种,因为每次合法的嵌套是大的套小的,相当于在二维平面中找一个最长递增的子序列,其长度就是最多能嵌套的信封个数

这道题的解法比较巧妙:

先对宽度 w 进行升序排序,如果遇到 w 相同的情况,则按照高度 h 降序排序;之后把所有的 h 作为一个数组,在这个数组上计算 LIS 的长度就是答案

public int maxEnvelopes(int[][] envelopes) {
        int n =envelopes.length;
    //先对宽度w进行升序排序,如果遇到w相同的情况,则按照高度h降序排序
        Arrays.sort(envelopes, new Comparator<int[]>(){
        	public int compare(int[] a,int[] b) {
        		return a[0]==b[0]?b[1]-a[1]:a[0]-b[0];
        	}
		});
        int[] height = new int[n];
        for(int i=0;i<n;i++) {
        	height[i]=envelopes[i][1];
        }
        return lengthOfLIS(height);//这里引用动态规划解法会超时
    }

标签:信封,int,递增,数组,序列,最长,dp
From: https://www.cnblogs.com/ANDQE/p/16932309.html

相关文章