最长递增子序列&&得到子序列的最少次数

Posted 秦枫-_-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长递增子序列&&得到子序列的最少次数相关的知识,希望对你有一定的参考价值。

基础:求一个序列的最长递增子序列

二分+贪心:
最长子序列的长度一定小于等于数组的长度,那么使用二分法,在遍历数组过程中,找到合适位置插入当前数据,如果当前查找位置比nums[i]小那么nums[i]应该放在当前位置的右侧,反之当前位置>=nums[i],那么右侧的范围应该缩小,使得当前较大位置数据替换成nums[i],如此我们可以得到最长递增子序列

class Solution {
    public int lengthOfLIS(int[] nums) {
    int []mm=new int[nums.length];
    int ans=0;
    for(int i=0;i<nums.length;i++){
        int left=0,right=ans;
        while(left<right){
            int mid=(right-left)/2+left;
            if(mm[mid]<nums[i])left=mid+1;
            else right=mid;
        }
        mm[left]=nums[i];
        if(left==ans)ans++;

    }
    return ans;
    }
}

进阶:求得是另外一个不重复序列为当前序列的子序列的最少操作次数?

有两种思路:
一种求得两个序列的最长子序列的长度len,然后用targe.length-len就为答案,但是源于此题设置数据长度太长,内存回超
第二种:
找出arr[]中 含有target的数,然后用list记录这些数在target的位置,那么由此转化为求得[0,1,2,3,4,5…](target各个数的位置)和list的最长公共子序列,[0,1,2,3,4,5…]是一个不重复的递增子序列,那么他们的最长公共子序列一定是递增序列同时,即为求得list的最长递增子序列长度len即可。结果即为target.length-len

class Solution {
    public int minOperations(int[] target, int[] arr) {
    Map<Integer,Integer> map=new HashMap<>();
    for(int i=0;i<target.length;i++){
        map.put(target[i],i);
    }
    List<Integer> list=new ArrayList<>();
    for(int i=0;i<arr.length;i++){
        if(map.containsKey(arr[i]))
        list.add(map.get(arr[i]));
    }
    int []num=new int[list.size()];
    int len=0;
    for(int i=0;i<list.size();i++){
        int left=0,right=len;
        while(left<right){
            int mid=(right-left)/2+left;
            if(num[mid]<list.get(i))
            left=mid+1;
            else right=mid;
        }
        num[left]=list.get(i);
        if(left==len)len++;
        
    }
    return target.length-len;
    }
}

以上是关于最长递增子序列&&得到子序列的最少次数的主要内容,如果未能解决你的问题,请参考以下文章

力扣LeetCode-1713. 得到子序列的最少操作次数-题解-最长递增子序列

LeetCode1143. 最长公共子序列/300. 最长递增子序列//1713. 得到子序列的最少操作次数(好题!!!!!)

最长递增子序列 && 最大子序列最长递增子序列最长公共子串最长公共子序列字符串编辑距离

最长上升子序列的长度&最长上升子序列的个数

最长递增子序列

求最长单调递增子序列