Leetcode:300.最长上升子序列

LeetCode300. 最长上升子序列:给定一个无序的整数数组,找到其中最长上升子序列的长度 LeetCode300. 最长上升子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 你算法的时间复杂度应该为 O(n2) 。 进阶: 你能将算法的时间复杂度降低到 O(... 阅读详情

给定一个无序的整数数组,找到其中最长上升子序列的长度。

示例:

输入: [10,9,2,5,3,7,101,18]
输出: 4 
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4

说明:

  • 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
  • 你算法的时间复杂度应该为 O(n2) 。

进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?

解题思路:

1. 普通算法

动态规划。假设数组的前n个数的所有上升子序列是vector<vector<int>> data。第n+1个数将会对data产生影响。1. 如果data[i-1].back()<nums[n+1],那么将nums[n+1]加入数组末尾。2.由于最终的结果未必包含nums[n+1],于是当加入nums[n+1]时需要将data[i-1]复制一份加入data。这样表面上解决了问题,但是实际上如果每次都需要将nums[n+1]加入data中所有序列的后端(nums升序),那么data的规模将指数上升,明显是不可取的。

后来一想,将nums[n+1]加入data的所有可能序列的末端,这个操作有很大的改进空间,因为nums[n+1]出现之后,以nums[n+1]结尾的最长升序是确定的而且是唯一的,取决于data中升序列末端小于nums[n+1]的最长一个,按照这个想法就可以很好地解决上述的内存不足的现象。

很显然data这个结构已经不适用了,改用可以自动排序的哈希容器map<int,int>mp。其中容器的key代表数字nums,val代表当前以数字nums结尾出现的最长升序列。当遇到nums[n+1]时,只需访问key比nums[n+1]小的pair,在这些key中找一个val最大的,然后当前nums[n+1]结尾的最大升序长度即是val+1。如果没有比nums[n+1]跟小的key,令nums[n+1]=1。如此,mp.size()<=nums.size(),取决于nums中不重复元素的个数,空间复杂度O(n)。时间复杂度O(n)-O(n^2)之间。已经满足了题目要求。

事实上,这个算法测试时间24ms,击败48%,仍有改进的空间。

2. 高级算法

动态规划,二分查找。假设vector<int> data是前n个数查找得到的最长升序列。当nums[n+1]出现时,可能有以下三种情况:

  1. nums[n+1]是data中的一个数,那么nums[n+1]不会影响原有的升序列。
  2. nums[n+1]恰好小于data[i],那么data[i]=nums[n+1]。原有的升序列长度不变,只需要理解为什么更新data[i]的值。我们假设最终结果里n+1之后升序列是n_val,如果满足(data[i],n_val)是升序,那么(nums[n+1],n_val)也必然是升序,这个时候讲nums[n+1]替换data[i]这一步是否存在不重要,可有可无,因为求解的是长度。如果不满足(data[i],n_val)是升序,那么,必须替将data[i]换nums[n+1],(nums[n+1],n_val)才是升序。综上,应该替换,但是由此可知,这这么一来,想要求解升序列是什么就难了。
  3. 剩下只可能是nums[n+1]大于data中的最后一个数,在末尾追加即可。
  4. 以上的查找,都用二分查找,特殊之处在于返回1,2,3三种情况。

这样一来时间复杂度就成了O(n)-O(nlogn),空间复杂度为O(n)。

 

普通解法:

C++代码
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int size = nums.size();
        if (size <= 1) return size;
        map<int, int> mp = { {nums[0],1} };
        int i;
        map<int, int>::iterator it;
        for (i = 2; i <= size; i++) {
            int max = 0;//获取nums[i-1]的最长序列
            bool sgn = false;
            for (it = mp.begin(); it != mp.end(); it++) {
                if (it->first < nums[i - 1]) {
                    sgn = true;
                    max = (it->second + 1>max ? it->second + 1 : max);
                }
                else break;
            }
            if (sgn == false) {
                mp[nums[i - 1]] = 1;
            }
            else mp[nums[i - 1]] = max;
        }
        int res=0;
        for (it = mp.begin(); it != mp.end(); it++) {
            res = (res > it->second ? res : it->second);
        }
        return res;
    }
};

 

参考的高级解法:

C++代码
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
      int size = nums.size();
      vector<int> dp;
      for (int i = 0; i < size; i++) {
        int index = binarySearch(dp, nums[i]);
        if (index == dp.size()) {
          dp.push_back(nums[i]);
        } else if (dp[index] > nums[i]) {
          dp[index] = nums[i];
        }
      }
      return dp.size();
    }
  
    int binarySearch(const vector<int>& nums, int target) {
      int low = 0, high = nums.size();
      while (low < high) {
        int mid = low + (high - low) / 2;
        if (nums[mid] == target)
          return mid;
        else if (nums[mid] < target)
          low = mid + 1;
        else
          high = mid;
      }
      return low;
    }
};

 

leetcode 300:最长上升子序列 leetcode 300:最长上升子序列 题目描述:给定一个无序的整数数组,找到其中最长上升子序列的长度。最长上升子序列不要求是连续的。 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 解题步骤: 1、 状态定义:采用一维数组dp[i]来表示代表 nums 前i个数字的最长子序列长度,其中nums[i]表示上升过... 阅读详情

相关推荐

2023-10-20 - MacBook - 优化外接2k显示器体验:告别字小与字虚的终极指南

本文针对MacBook外接2K显示器时普遍遇到的字体过小和边缘发虚问题,提供了终极解决方案。通过深入解析macOS的HiDPI与Retina显示原理,并详细指导使用SwitchResX等工具开启隐藏的HiDPI模式,实现完美的2倍整数缩放,从而在保证字体大小合适的同时获得清晰锐利的显示效果,彻底告别字小与字虚的困扰。

solidity8miner的博客 454

Leetcode——最长上升子序列

300.给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 你算法的时间复杂度应该为 O(n2) 。 进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗? 思路: 1.D...

IT荻的博客 1227

python【力扣LeetCode算法题库】300 最长上升子序列(动态规划)

最长上升子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 你算法的时间复杂度应该为 O(n2) 。 进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗? d...

NJU phd 在读。 853

Leetcode 每日一题】300.最长上升子序列

题目描述 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是[2,3,7,101],它的长度是 4。 说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 你算法的时间复杂度应该为O(n2) 。 进阶: 你能将算法的时间复杂度降低到O(n log n) 吗...

ColorGalaxy 619

leetcode300.最长上升子序列(动态规划多种解法, java实现)

300. 最长上升子序列 难度中等 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 你算法的时间复杂度应该为 O(n2) 。 进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗? 分析 首先,需要对「子序列」和「子串」这两个概念进行区分; 子序列(subsequen

Viper的程序员修炼手册 1252

LeetCode 300.最长上升子序列(超详细)

LeetCode 300.最长上升子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 你算法的时间复杂度应该为 O(n2) 。 进阶: 你能将算法的时间复杂度降低到 ...

struct_hsj的博客 672

【力扣LeetCode300 最长上升子序列

题目描述(难度中) 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。你算法的时间复杂度应该为 O(n2) 。 进阶: 你能将算法的时间复杂度降低到 O(nlogn) 吗? 链接 h...

Jiewang的博客 1161

LeetCode300. 最长上升子序列(python)

LeetCode300. 最长上升子序列(python) 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 你算法的时间复杂度应该为 O(n2) 。 进阶: 你能将算法的...

wk的博客 3223

leetcode题:300. 最长上升子序列(中等)

一、题目描述:300. 最长上升子序列(中等) 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是[2,3,7,101],它的长度是 4。 说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 你算法的时间复杂度应该为O(n2) 。 进阶: 你能将算法的时间复杂...

tankpanv的博客 199

LeetCode 300 最长上升子序列 Python

LeetCode 300 最长上升子序列 Python 题目描述如下: 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 你算法的时间复杂度应该为 O(n2) 。...

Tianchi_M的博客 4695

Leetcode 300. 最长上升子序列 C++

Leetcode 300. 最长上升子序列 题目 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 你算法的时间复杂度应该为 O(n2) 。 题解 动态规划 令dp[i]表示以nums[i]结尾的最长上升子序列的长度。显然,dp[i] = max(dp[i],dp[j]+1),其中j

weixin_43750513的博客 216

LeetCode:300.最长上升子序列

题目 LeetCode:300.字符串的最大公因子 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 你算法的时间复杂度应该为 O(n2) 。 进阶: 你能将算法的时间复杂度降低到...

Doraemon_Zzn的博客 271

LeetCode 300最长上升子序列

LeetCode 300最长上升子序列 题目简述:给定一个无序的整数数组,找到其中最长上升子序列的长度。 输入:[10,9,2,5,3,7,101,18] 输入:4 解释:最长的上升子序列是 [2,3,7,101],它的长度是 4。 思路:动态规划 状态表示:f[i]表示所有以i结尾的上升子序列 状态属性:上升子序列的长度最大值 状态计算:最后一个数都是第i个数,倒数第二个数为分类依据,可以分成i类,按照倒数第二个数分别依次是null、0、1、2......i-1分类,再求倒数第二个数

XBlog 250

力扣:300.最长上升子序列(LIS)

力扣:300.最长上升子序列(LIS) 1、 题目 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。 示例 1: 输入:nums = [10,9,2,5,3,7,101,18] 输出:4 解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。 示例 2: 输入:nums = [0,1,0,3,2,3] 输出:4 示例

meraki的博客 354

最长上升子序列_LeetCode题记——300最长上升子序列

LeetCode 300 最长上升子序列,难度:中等,标签:面试高频题意:给定一个无序的整数数组,找到其中最长上升子序列的长度。示例:输入: [10,9,2,5,3,7,101,18]输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。说明:可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。你算法的时间复杂度应该为 O(n2) 。进阶: 你能将算法的时间复杂...

weixin_39870700的博客 78

Leetcode 300.最长上升子序列(Longest Increasing Subsequence)

Leetcode 300.最长上升子序列 1 题目描述(Leetcode题目链接)   给定一个无序的整数数组,找到其中最长上升子序列的长度。 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 你算法的时间复杂度应该为 O(n2)O(n^...

qq_39378221的博客 297

Leetcode 300 最长上升子序列 C++,Python,Java

Leetcode300 最长上升子序列 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/longest-increasing-subsequence 博主Github:https://github.com/GDUT-Rp/LeetCode 题目: 给定一个无序的整数数组,找到其中最长上升子序列的长度。c 示例 1: 输入: [10,9,2,...

Rp的博客 282

leetcode 300. 最长上升子序列

@(labuladong的算法小抄)[dp] leetcode 300. 最长上升子序列 题目描述 解题思路 参考:动态规划设计之最长递增子序列 class Solution { public int lengthOfLIS(int[] nums) { if (nums.length == 0) return 0; /* 定义:dp[i]表示以nums[i]结尾的最长上升子序列的长度 */ int[] dp = new int[nums.length

Charison的编程妙妙屋 111

LeetCode练习-中等 - 300. 最长上升子序列

LeetCode练习-中等 - 300. 最长上升子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度。 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 你算法的时间复杂度应该为 O(n2) 。 进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗? 思路一:暴力 时间复杂度: O(2^N) 空间复杂度: O(N) 这也

河神的博客 209

【华为OD机试真题】7、字符串筛选排序 | 机试真题+思路参考+代码解析(C++、Java、Py)

题目描述 >输入一个由N个大小写字母组成的字符串 按照ASCII码值从小到大进行排序 查找字符串中第K个最小ASCII码值的字母(k>=1) 输出该字母所在字符串中的位置索引(字符串的第一个位置索引为0) k如果大于字符串长度则输出最大ASCII码值的字母所在字符串的位置索引 如果有重复字母则输出字母的最小位置索引

KJ.JK 2230

重绘CListCtrl的scrollbar,headerctrl和items的代码

MFC重绘CListCtrl的scrollbar,headerctrl和items的代码.用于MFC的UI的设计。

上一篇: Leetcode:Nim游戏
下一篇: Leetcode:306. 累加数
Liao_Hong_XiDian
博客等级 码龄12年 9粉丝 154原创
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值