<LeetCode OJ> 300. Longest Increasing Subsequence

本文介绍了两种解决「最长递增子序列」问题的方法:动态规划与二分法。详细解释了每种方法的原理、步骤,并通过实例演示如何应用这些算法。动态规划通过定义子问题并利用前缀最大值动态计算,而二分法则通过维护有序栈优化搜索过程。文章旨在帮助读者理解这两种方法的核心思想及其实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

300. Longest Increasing Subsequence

My Submissions
Total Accepted: 11127  Total Submissions: 34521  Difficulty: Medium

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?

Credits:
Special thanks to @pbrother for adding this problem and creating all test cases.

Subscribe to see which companies asked this question



分析:

典型的动态规划问题

定义子问题:dp[i]表示第i个及其以前的元素的最大上升个数
显然第i个元素的最大上升序列是前面某个子问题的最大长度+1
当遍历到i时,重新将前面的遍历一遍,如果nums[i]>nums[j]并且dp[j]+1 > dp[i]
显然dp[i]就是dp[j]+1,遍历完0到j就是dp[i]就求出来了

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        if(nums.size()==0)
            return 0;
        int maxLen=1;
        vector<int> dp(nums.size(),1);
        for(int i=1;i<nums.size();i++)
            for(int j=0;j<i;j++)
               if(nums[i]>nums[j] && dp[j]+1 > dp[i])
                { 
                   dp[i]=dp[j]+1;
                   if(maxLen < dp[i])
                        maxLen = dp[i];
                }
        return maxLen;
    }
};




第二种解法:

贪心策略+二分法

开辟一个栈,每次取“栈”(这里采用数组来实现)顶元素s和读到的元素a做比较,如果a>s,  则加入栈(将会有序);如果a<s,则二分查找栈中的比a大的第1个数,并替换。  最后序列长度为栈的长度。  我们替换之后最长序列长度没有改变,但序列Q的''潜力''增大,我们总是贪心的营造这种能产生最长长度的“潜力”,并且不影响其长度。  
举例:原序列为1,5,8,3,6,7  
栈为1,5,8,此时读到3,则用3替换5,得到栈中元素为1,3,8,  再读6,用6替换8,得到1,3,6,再读7,得到最终栈为1,3,6,7  ,最长递增子序列为长度4。 

参考自己以前的博文:

http://blog.youkuaiyun.com/ebowtang/article/details/45373557#t12


注:本博文为EbowTang原创,后续可能继续更新本文。如果转载,请务必复制本条信息!

原文地址:http://blog.youkuaiyun.com/ebowtang/article/details/50424074

原作者博客:http://blog.youkuaiyun.com/ebowtang

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值