LeetCode 300. Longest Increasing Subsequence -动态规划的使用

Given an unsorted array of integers, find the length of longest increasing subsequence.

For example, Given [10, 9, 2, 5, 3, 7, 101, 18], The longest
increasing subsequence is [2, 3, 7, 101], therefore the length is 4.
Note that there may be more than one LIS combination, it is only
necessary for you to return the length.

Your algorithm should run in O(n2) complexity.

Follow up: Could you improve it to O(n log n) time complexity?

最开始的思路是贪心算法,以每个元素为起点,终点都是尾元素,遍历然后找出所有的上升子序列,发现这样不行,只能过一部分数据,后来查看input数据后发现这样的思路是不行的,因为我的判断条件当前元素小于下一个元素,那么以下一个元素为当前元素,继续遍历下去找大于当前元素的。这样的贪心算法势必会漏掉很多合适的答案。贴下错误代码

class Solution {
 public static int lengthOfLIS(int[] nums) {

     if(nums.length==0)
         return 0;
    int max=-1;
    int tempMax=1;
    for(int i=0;i<nums.length;i++){
        int key=nums[i];
        for(int j=i+1;j<nums.length;j++){

            if(key<nums[j]){
                key=nums[j];
                tempMax++;
            }

        }
        if(tempMax>max)
            max=tempMax;
        tempMax=1;


    }
    return max;

    }
}

那么贪心会漏掉,那么肯定会想到动态规划了,具体思路是这样的
自底向上,从第一个元素出发,慢慢的加元素进来,看他与前面的所有子串能构成多长的子序列,都记录下来,具体判断方法就是加进来一个元素x,就与之前的元素y比较,如果小于之前元素,则构成上升序列,将x存储的上升序列长度与1+y所存储的上升子序列长度比较,谁大取谁。
这里写图片描述
拿图中元素举例:
当只有一个元素的时候,那么最长序列就是本身了,如元素10
继续往下遍历,那么当前元素9与前一个元素10比较发现小于它,不构成上升序列,那么此时长度还是1。
继续往下遍历,当元素为2的时候发现前面两个元素都大于它,不构成上升,所以还是1。
继续遍历当元素为5的时候,发现5大于2,难么5就可以接入2的最长上升序列后面,所以5的初始值是1加上2存储的最长子序列值1得出2
继续遍历到元素为3的时候此时比它小的只有2,加上2的值,所以此时为2
继续遍历到元素为7的时候那么前面的元素2和元素3都小于7,此时当然取最大的相加了,因为要最长子序列。
依次类推…

public static int max(int a,int b)
    {
        if(a>b)
            return a;
        else
            return b;
    }
    public static int lengthOfLIS(int[] nums) {
        int N=nums.length;
        if(N<=1)
            return N;
        int Max=-1;
        int keynums[]=new int[nums.length];
        for(int i=0;i<N;i++)
            keynums[i]=1;
        for(int i=1;i<N;i++)
        {
            int temmax=1;
            for(int j=i-1;j>=0;j--)
            {
                if(nums[i]>nums[j]){
                    temmax=max(temmax,keynums[j]+keynums[i]);
//                  System.out.println(temmax);
                }
            }
            keynums[i]=temmax;
            if(temmax>Max)
                Max=temmax;
        }


        return Max;
    }

这个题目做完可以做一个类似的题目Leet code 376. Wiggle Subsequence加深一下理解。

猜你喜欢

转载自blog.csdn.net/hjsir/article/details/79424921