• 动态规划之LIS(最长上升子序列)


    https://www.cnblogs.com/frankchenfu/p/7107019.html

    【题目描述】

    给定N个数,求这N个数的最长上升子序列的长度。
    【样例输入】
    7
    2 5 3 4 1 7 6
    【样例输出】
    4

    什么是最长上升子序列? 就是给你一个序列,请你在其中求出一段不断严格上升的部分,它不一定要连续。
    就像这样:2,3,4,7和2,3,4,6就是序列2 5 3 4 1 7 6的两种选取方案。最长的长度是4.

    朴素算法:

    使用dp[i]表示以第i个数值结尾的最长上升子序列的长度。

    int lis(int[] nums){
    if(nums==null||nums.length==0)
    return 0;
    int[]dp=new int[nums.length];
    int re=1;
    for(int i=0;i<nums.length;i++){
     dp[i]=1;
          for(int j=0;j<i;j++){
                if(nums[j]<nums[i]){
                if(dp[i]<dp[j]+1){
                      dp[i]=dp[j]+1;
                }
          }
            if(re<dp[i])
                re=dp[i];
    }
    return re;
    }  
    

    时间复杂度:O(n^2)
    空间复杂度:O(n)

    二分算法

    其实在之前有一种想法是模拟一个栈,当序列降序时,替换其中的数值。但是当时将这个想法略过去了。
    而二分法的实现是首先当nums[i]>栈顶元素时,乖乖排在队尾(栈顶)。但是当num[i]<=栈顶元素时(即降序时)因为保证最长长度不变的情况下,当使用二分算法替换在栈中的元素时,栈中元素数量不变,但是可能导致栈顶元素变小(即后来的元素有新进来的机会,栈中整体数值下降)。

    public static int lis(int[] nums) {
    		if(nums==null||nums.length==0)
    			return 0;
    		ArrayList<Integer> list=new ArrayList<Integer>();
    		list.add(nums[0]);
    		for(int i=1;i<nums.length;i++) {
    			if(nums[i]>list.get(list.size()-1))
    				list.add(nums[i]);
    			else {
    				int start=0,end=list.size()-1;
    				int mid=(start+end)/2;
    				while(start<=end) {
    					mid=(start+end)/2;
    					if(list.get(mid)<nums[i]) {
    						start=mid+1;
    					}else if(list.get(mid)==nums[i]) {
    						break;
    					}else {
    						end=mid-1;
    					}
    				}
    				if(start>end)
    					list.set(start, nums[i]);
    			}
    		}
    		return list.size();
    	}
    

    时间复杂度:O(nlogn)
    空间复杂度:O(n)
    类似地,我们可以使用二分查找改变“上确界”和“下确界”以及符号(“<”、“<=”、“>”、“>=”等)求出最长不下降、不上升、严格下降子序列问题。

  • 相关阅读:
    sql注入漏洞与防范
    微信小程序-工具,弹出当前系统代理不是安全代理处理方法
    微信小程序-02 小程序关注组件
    微信小程序-01 小数保留二位
    http 转hhttps
    php 函数-ksort
    iOS 原生二维码扫描
    iOS 打包错误 all-product-headers.yaml' not found
    iOS Tableview点击cell 会往上跳
    WKWebView 使用
  • 原文地址:https://www.cnblogs.com/code-fun/p/13826335.html
Copyright © 2020-2023  润新知