[Programmer Code Interview Guide] longest increasing sequence (two points, DP)

topic

Example: arr = [2,1,5,3,6,4,8,9,7], 1,3,4,8,9 longest increasing sequence

answer

step1: Get the length of the longest contiguous subsequence

  • DP [] stored in arr [i] at the end of the case, arr length of the longest increasing sequence [0..i] in.
  • Extra ends a [] array, initialization ends [0] = arr [0], and 0 otherwise. It has an effective area ends [0, r] number makes sense only effective area. ends [i] = num represents traversed Currently, all increasing sequence of length i + 1, at the end of the minimum number num.
  • Traversing arr [i], to find the active region ends leftmost> = arr [i] of number, from left to right to find the process can be represented even in increasing the length of a contiguous sequence arr [i] before.
    • If found, referred to as ends [j], described ends [j] and the latter number is greater than arr [I], it is dp [i] = j + 1, ends [j] to update
    • If not found, indicating the number of ends [] active area than arr [i] is small, so dp [i] = +1 length of the active area, the active area right boundary r ++, ends [r] update.
  • Because ENS [] is a non-decreasing sequence, it is possible to use a binary search
  • The time complexity of O (nlogn)
    Step2: longest continuous output sequence element
    found dp = length of the longest element value of [] stored, denoted as dp [I] corresponding to arr [i] is the last element. Get then forward the stored value = -1 && longest length corresponding arr [j] <arr [i ] position, i.e. the penultimate element ...

other

  • This question is used in a classic binary search: binary search to find first a value larger than a given element.
  • Ultimately it must be l = r = mid, then when the last element is greater than the given element, l pointing to it, l that is obtained. Conversely, ++ l, l that is obtained.
  • So: The cycling conditions with a number =, L is returned, if not found will return to the right boundary position +1.

Code

public class Main {
    public static void main(String args[]) {
        int[] arr= {2,1,5,3,6,4,8,9,7};
        int[] incSec=getLongestIncSeq(arr);
        for(int num:incSec) {
            System.out.println(num);
        }
    }
    
    public static int[] getLongestIncSeq(int[] arr) {
        if(arr==null||arr.length==0) {
            return null;
        }
        
        int[] dp=getDp(arr);
        return getIncSeq(dp,arr);
    }
    
        //得到dp数组
    public static int[] getDp(int[] arr) {
        int[] dp=new int[arr.length];
        dp[0]=1;
        
        int[] ends=new int[arr.length];
        ends[0]=arr[0];
        int end=0;
        for(int i=0;i<arr.length;++i) {//遍历arr
            int pos=firstBigger(arr[i],ends,end);//遍历ends
            if(pos!=end+1) {//找到比arr[i]大的上升子序列结尾元素
                //更新dp和ends
                dp[i]=pos+1;//长度+1
                ends[pos]=Math.min(ends[pos], arr[i]);
            }
            else {//未找到比arr[i]大的上升子序列结尾元素
                //更新dp和ends
                dp[i]=end+1+1;//原长度+1
                ++end;
                ends[end]=arr[i];
            }
        }
        return dp;
    }
    
        //二分查找第一个比num小的元素
    public static int firstBigger(int num,int[] ends,int end) {//二分查找第一个比num小的元素
        int l=0;
        int r=end;
        while(l<=r) {//**
            int mid=(l+r)/2;//
            if(ends[mid]>=num) {
                r=mid-1;//
            }
            else {
                l=mid+1;//  
            }
        }
        return l;//**
    }
    
        //输出最长递增子序列
    public static int[] getIncSeq(int[] dp,int[] arr) {
        int len=Integer.MIN_VALUE;//代表新数组长度 ,并表示新数组索引
        int pos=-1;
        for(int i=0;i<dp.length;++i) {
            len=len>dp[i]?len:dp[i];
            pos=len>dp[i]?pos:i;//dp索引,arr索引
        }
        
        int[] incSeq=new int[len];
        incSeq[--len]=arr[pos];
        
        for(int j=pos;j>=0;--j) {
            if(dp[j]==len&&arr[j]<arr[pos]) {
                incSeq[--len]=arr[j];
                pos=j;
            }
        }
        return incSeq;
    }
}

Guess you like

Origin www.cnblogs.com/coding-gaga/p/11072343.html