LeetCode

145 阅读1分钟

序列DP

题目难度
354. 俄罗斯套娃信封问题困难
368. 最大整除子集中等
446. 等差数列划分 II - 子序列困难
740. 删除并获得点数中等
740. 删除并获得点数中等
1035. 不相交的线困难
1143. 最长公共子序列中等
1473. 粉刷房子 III困难
1473. 粉刷房子 III困难

最长公共子序列问题(LCS)

序列dp,一般是求递增子序列。暴力解法是O(m*n),是所求子序列的长度。从i=0开始遍历目标数组target,从j-i的位置检查是否递增,用一个数组保存二米个位置的递增情况,检查结果dp[i] = Math.max(dp[i],dp[i-1]+1),求得当前位置的最大递增子序列的长度。

最长上升子序列问题(LIS)进行求解

如果target数组中的元素各不相同,可以通过二分查找的方法。dp长度为目标数组长度+1,并设置为最大值,每次从1-i+1位置的数组中,二分查找,找到以当前值为最大值的inndex,并对dp[index]进行更新,ans = Math.max(ans,index).

//leetcode_334
public static void main(String[] args) {
    int[] nums = {2,1,5,0,4,6};
    System.out.println(increasingTriplet(nums));
}
public static boolean increasingTriplet(int[] nums) {
    if(nums.length <3) return false;
    int n = nums.length;
    int ans = 0;
    int[] f = new int[n+1];
    Arrays.fill(f,Integer.MAX_VALUE);
    for (int i = 0; i < n; i++) {
        int t = nums[i];
        //在l--r维护一个以当前数字结尾的递增子序列
        int l = 1, r = i + 1;
        while (l < r) {
            //二分查找,更换将当前数字放入l-r中的数组中
            int mid = l + r >> 1;
            if (f[mid] >= t) r = mid;
            else l = mid + 1;
        }
        //找到该位置进行替换
        f[r] = t;
        ans = Math.max(ans, r);
    }
    return ans >= 3;
}