Longest Increasing Subsequence的两种解法
问题描述:
  给出一个未排序队列nums,如[10, 9, 2, 5, 3, 7, 101, 18]。找出其中最长的增长序列,但不是连续增长序列,如[2, 3, 7, 101]就是对应的最长增长序列LIS,因为序列不唯一,所以要求返回的是长度,如4.
一.动态规划 O(n^2):
比较容易想到的就是复杂度为O(n^2)的算法。这是一个备忘录算法,也是动态规划算法。需要建立一个备忘录dp,备忘录dp[i]记录序列从下标0到下标i最长的子序列长度。对于dp[j]的值则需要在nums序列红中找到0到(j-1)所有比nums[j]小元素,并在这些元素中选择备忘录dp值最大的一个如dp[k],则dp[j]=dp[k]+1;
public int lengthOfLIS(int[] nums) {
        if(nums==null || nums.length==0)
            return 0;
        int[] bigLength=new int[nums.length];
        for(int i=0;i<nums.length;i++) bigLength[i]=1;
        int maxLength=1;
        for(int i=1;i<nums.length;i++){
       //从前面找到比 nums[i]小,且dp值最大的那个。加1便是当前的值
            for(int j=0;j<i;j++){
                if(nums[j]<nums[i])
                    bigLength[i]=Math.max(bigLength[j]+1,bigLength[i]);
            }
            maxLength=Math.max(bigLength[i],maxLength);
        }
        return maxLength;
    }
二 .二分法查找O(nlg(n))
首先建立一个栈stack来存储遍历到当前时刻 i 的一个最长递增序列(栈内是递增序列,但概念和题目中的递增序列不同)。设当前时刻为 i 则
1.如果元素 i 比栈顶元素大则入栈,stack[top++]=nums[i+1];
2.如果元素 i 比栈顶元素小,则在栈中采用二分查找法找到一个位置j 替换成当前元素nums[i] 。 该做法的目的是如果出现小元素就往栈内部替换,当前替换的结果影响下一次的替换,特别是栈顶元素。栈顶元素的替换需要比较stack[top],stack[top--]及nums[i]三个的值。
3.最后输出 栈的长度。
public int lengthOfLIS(int[] nums) {
        if(nums==null || nums.length==0)
            return 0;
        int[] stack= new int[nums.length];
        int top=0;
        for(int num:nums){
            if(top==0 || stack[top-1]<num) stack[top++]=num;
            else{
              //如果在栈中没有对应的元素,则将找到的插入坐标为 j 返回-j-1. 如果找到则返回对应的坐标位置。
                int i=Arrays.binarySearch(dp,0,top,num);
                i= i<0? -i-1:i;
                dp[i]=num;
            }
        }
        return top;
    }                    
另外网上有关于只用栈没用利用二分法查找法的做法,使得复杂度变为O(n),试了下是不行的。他大概的思路是:
1.如果当前栈为空或栈顶元素小于当前元素nums[i],则入栈
2.如果nums[i]<stack[top] 且 nums[i]>stack[top-1] 则替换栈顶元素,stack[top]=nums[i]。
这种做法忽略了stack[top-1]之前的元素对stack[top-1]的影响。算法代码如下:
public int lengthOfLIS(int[] nums) {
    int len=nums.length;
    Stack<Integer> stack=new Stack<Integer>();
    for(int i=len-1; i>=0; i--)
    {
        if(stack.isEmpty())
        {
            stack.push(nums[i]);
        }else
        {
           int val= stack.pop();
           if(stack.isEmpty())
           {
               if(nums[i]>=val)
               {
                   val=nums[i];
               }else
               {
                   stack.push(val);
                   val=nums[i];
               }
           }else
           {
               int up=stack.peek();
               if(nums[i]<val)
               {
                   stack.push(val);
                   val=nums[i];
               }else if(nums[i]>val && nums[i]<up)
               {
                   val=nums[i];
               }
           }
           stack.push(val);
        }
    }
    return stack.size();
}
Longest Increasing Subsequence的两种解法的更多相关文章
- Longest Increasing Subsequence的两种算法
		
问题描述:给出一个序列a1,a2,a3,a4,a5,a6,a7-.an,求它的一个子序列(设为s1,s2,-sn),使得这个子序列满足这样的性质,s1<s2<s3<-<sn并且 ...
 - [LeetCode] Longest Increasing Subsequence 最长递增子序列
		
Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...
 - 最长上升子序列 LIS(Longest Increasing Subsequence)
		
引出: 问题描述:给出一个序列a1,a2,a3,a4,a5,a6,a7….an,求它的一个子序列(设为s1,s2,…sn),使得这个子序列满足这样的性质,s1<s2<s3<…< ...
 - Longest Increasing Subsequence - LeetCode
		
Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...
 - [LeetCode] 300. Longest Increasing Subsequence 最长递增子序列
		
Given an unsorted array of integers, find the length of longest increasing subsequence. Example: Inp ...
 - [tem]Longest Increasing Subsequence(LIS)
		
Longest Increasing Subsequence(LIS) 一个美丽的名字 非常经典的线性结构dp [朴素]:O(n^2) d(i)=max{0,d(j) :j<i&& ...
 - [LintCode] Longest Increasing Subsequence 最长递增子序列
		
Given a sequence of integers, find the longest increasing subsequence (LIS). You code should return ...
 - Leetcode 300 Longest Increasing Subsequence
		
Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...
 - [LeetCode] Number of Longest Increasing Subsequence 最长递增序列的个数
		
Given an unsorted array of integers, find the number of longest increasing subsequence. Example 1: I ...
 
随机推荐
- BZOJ 2818 GCD 素数筛+欧拉函数+前缀和
			
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2818 题意:给定整数N,求1<=x,y<=n且Gcd(x,y)为素数的数对( ...
 - JAVA基础 XML生成与解析和String包装类下 .replace方法的使用以及char和字符序列的使用场景
			
ptLink0.setText(arbu.getPtLink().replace("&","&")); // 如果像 '&','& ...
 - 第一次玩github,第一个开源小项目——xxoo
			
引言 由于最近的工作写代码比较少,这让LZ产生了一丝危机感.于是便想找一个办法可以没事自己写写代码,自然而然就想到了github.接下来便是一阵捣鼓的过程,其实整个过程很快,主要过程就是注册一个账号, ...
 - File System Object(FSO对象)A
			
FSO对象模型包含在Scripting 类型库 (Scrrun.Dll)中,它同时包含了Drive.Folder.File.FileSystemObject和TextStream五个对象: 1.Dri ...
 - 理解unittest(六)
			
unittest,顾名思义就是一个单元测试框架,但是它不仅适用于单元测试,还适用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成 ...
 - Unity3D — —存读档【转载】
			
详细可参考此篇博文: Unity序列化之XML,JSON--------合成与解析 简单例子(SiKi学院教程): using System.Collections; using System.Col ...
 - 信息提示 - bootStrap4常用CSS笔记
			
.alert 基类 .alert-{success.info.warning.danger.primary.secondary.light.dark} 各种类型的配色样式 .fade..show 设置 ...
 - 解决Ubuntu“下载额外数据文件失败 ttf-mscorefonts-installer”的问题 (转载)
			
解决Ubuntu“下载额外数据文件失败 ttf-mscorefonts-installer”的问题 发表于 2017-09-15 | 更新于 2018-04-29 | 分类于 Linux | 评论数: ...
 - GNU Radio GRC HackRF实现FM接收
			
本文内容.开发板及配件仅限用于学校或科研院所开展科研实验! 淘宝店铺名称:开源SDR实验室 HackRF链接:https://item.taobao.com/item.htm?spm=a1z10.1- ...
 - 基于Python的信用评分卡模型分析(一)
			
信用风险计量体系包括主体评级模型和债项评级两部分.主体评级和债项评级均有一系列评级模型组成,其中主体评级模型可用“四张卡”来表示,分别是A卡.B卡.C卡和F卡:债项评级模型通常按照主体的融资用途,分为 ...