leetcode300: Longest Increasing Subsequence

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

Example:

Input: [10,9,2,5,3,7,101,18]
Output: 4
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.

solution 1: 动态规划(无序)

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int num = nums.size();
        if(num==0) return 0;
        if(num==1) return 1;
        int max_length[num];
        int max = 0;
        for(int m=0; m<num; m++)
        {
            max_length[m] = 1;
        }
        for(int i= 1; i < num;i++)
        {
            int j;
            for(j = i - 1; j >= 0; j--)
            {
                if(nums[j] < nums[i])
                {
                    if(max_length[j]+1 > max_length[i])
                    {
                        max_length[i]= max_length[j] + 1;
                    }
                }
            }

            max = max_length[i]>max? max_length[i]:max;
        }         
        return max;        
    }
};

上述方法生成了一个固定大小的数组max_length,其中的每个元素与原vector数组相对应,max_length[i]里面存储的数据表示的是对应的nums[i]被选中作为上升序列数组时,从nums[0]到nums[i]之间最大的上升序列个数,也可以理解为动态规划的方法。
solution2: 动态规划 + lower_bound(二分法->有序)

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int num = nums.size();
        if(num==0) return 0;
        vector<int> DP;
        DP.push_back(nums[0]);
        for(int i= 1; i < num;i++)
        {
            if(nums[i]>DP.back())
            
                DP.push_back(nums[i]);
            else
                *lower_bound(DP.begin(), DP.end(), nums[i]) = nums[i];
            
        }         
        return DP.size();        
    }
};

该方法中用到了lower_bound,替代了遍历过程, lower_bound针对有序的数列,采用二分法进行查找,因此运行时间优于采用直接遍历。 动态规划产生的数组DP中的数都是有序的,如果下一个遍历的数小于DP末尾的数, 那lower_bound查找出DP 中第一个大于遍历数的数,并将其替换,eg, 若如果DP 最后一个数为6, nums中下一个遍历的数是5,由于不存在重复的数, 因此6是DP中、中第一个大于5的数,这个6可以理解为前面小于6的数有X个, 后面的5也可以表示为小于5的数有X个, 因此可以直接替换掉6. 如果下一个遍历的数大于DP末尾的数,那么直接在DP末尾添加此数。
lower_bound(ptr1, ptr2, x):查找ptr1和ptr2范围内第一个大于x的数,并返回其指针。
upper_bound(ptr1, ptr2,x):查找ptr1和ptr2范围内第一个大于等于x的数,并返回其指针。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值