leetcode300. 最长递增子序列 子序列(不连续)

这篇具有很好参考价值的文章主要介绍了leetcode300. 最长递增子序列 子序列(不连续)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • https://leetcode.cn/problems/longest-increasing-subsequence/

  • 给你一个整数数组 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

示例 3:
输入:nums = [7,7,7,7,7,7,7]
输出:1

LIS即最长上升子序列,指的是给定一个数列,从中选取一个子序列,使得子序列中的所有元素单调递增,并且满足子序列的长度最长。以下是LIS的动态规划代码实现(时间复杂度为 O ( n 2 ) O(n^2) O(n2)):

int lengthOfLIS(vector<int>& nums) {
    int n = nums.size();
    if (n < 2) {
        return n;
    }
    vector<int> dp(n, 1);
    int max_len = dp[0];
    for (int i = 1; i < n; ++i) {
        for (int j = 0; j < i; ++j) {
            if (nums[i] > nums[j]) {
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
        max_len = max(max_len, dp[i]);
    }
    return max_len;
}

其中, d p [ i ] dp[i] dp[i] 表示以第 i i i 个元素为结尾的最长上升子序列的长度。状态转移方程为:

d p [ i ] = max ⁡ j = 0 i − 1 { d p [ j ] + 1 } , if   n u m s [ i ] > n u m s [ j ] dp[i]=\max_{j=0}^{i-1} \{dp[j]+1\},\quad \text{if}\, nums[i] > nums[j] dp[i]=j=0maxi1{dp[j]+1},ifnums[i]>nums[j]

其中, n u m s nums nums 表示原数列。

代码中,使用双重循环来计算 d p dp dp 数组。外层循环遍历所有元素,内层循环遍历当前元素前面的所有元素,如果存在一个元素小于当前元素,那么就可以将当前元素添加进该元素为结尾的最长上升子序列中,从而得到以当前元素为结尾的最长上升子序列。

循环结束后, d p dp dp 数组中的最大值即为整个数列的最长上升子序列长度。

需要注意的是,以上代码中没有考虑数列中存在相同元素的情况。如果数列中存在相同元素,那么在转移时应该将条件 n u m s [ i ] > n u m s [ j ] nums[i] > nums[j] nums[i]>nums[j] 改为 n u m s [ i ] > n u m s [ j ]   and   d p [ i ] ≤ d p [ j ] nums[i] > nums[j] \, \text{and} \, dp[i] \leq dp[j] nums[i]>nums[j]anddp[i]dp[j],保证子序列的单调性和最长性质。文章来源地址https://www.toymoban.com/news/detail-620498.html

题解

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
    //动态规划 dp[i]为到i位置的最长严格递增子序列,结果输出dp[n-1]
    vector<int> dp(nums.size(),1);//最小值为1
    for(int i=1;i<dp.size();i++){
        for(int j=0;j<i;j++){
            if(nums[i]>nums[j])
                dp[i] =max(dp[i],dp[j]+1);
        }
    }
    int res = 0;
    for(int i=0;i<dp.size();i++){
        cout<< dp[i]<<",";
        res = max(dp[i],res);
    }
    return res;
    }
};

错解

#include <stdio.h>
#include<vector>
#include<memory>
#include<iostream>
#include<algorithm>
using namespace std;
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
    //动态规划 dp[i]为到i位置的最长严格递增子序列,结果输出dp[n-1]
    vector<int> dp(nums.size(),1);//最小值为1
    for(int i=1;i<dp.size();i++){
        for(int j=0;j<i;j++){
            if(nums[i]>nums[j])
                dp[i] =max(dp[i],dp[j]+1);
            else
                 dp[i] = 1;//前边没有更小的值了  应该去掉这个else部分
        }
    }
    int res = 0;
    for(int i=0;i<dp.size();i++){
        cout<< dp[i]<<",";
        res = max(dp[i],res);
    }
    return res;
    }
};

int main()
{

    vector<int> arr = {7,7,7,7,7,7,7};//{10,9,2,5,3,7,101,18};

    unique_ptr<Solution> mysolo = unique_ptr<Solution>(new Solution());
    int res = mysolo->lengthOfLIS(arr);
    cout<<res<<endl;
    return 0;
}


到了这里,关于leetcode300. 最长递增子序列 子序列(不连续)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【LeetCode动态规划#14】子序列系列题(最长递增子序列、最长连续递增序列、最长重复子数组、最长公共子序列)

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

    2024年02月01日
    浏览(56)
  • 算法刷题Day 52 最长递增子序列+最长连续递增子序列+最长重复子数组

    我自己想出来的方法,时间复杂度应该是 O(n2) 滑动窗口 连续的话,可以考虑用滑动窗口 动态规划 贪心算法

    2024年02月14日
    浏览(54)
  • ( 动态规划) 674. 最长连续递增序列 / 718. 最长重复子数组——【Leetcode每日一题】

    难度:简单 给定一个未经排序的整数数组,找到最长且 连续递增的子序列 ,并返回该序列的长度。 连续递增的子序列 可以由两个下标 l 和 r(l r) 确定,如果对于每个 l = i r ,都有 nums[i] nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] 就是连续递增子序列。

    2024年02月05日
    浏览(51)
  • 力扣300. 最长递增子序列

    思路: 假设 dp[i] 为前 i 个元素构成的最长递增子序列的个数,包含 nums[i]; 则 dp[i] 构成序列上一个元素 nums[j] 构成最长递增子序列 dp[j],则 dp[i] = dp[j] + 1; 如果动态取 j ∈ [0, i - 1],则选取其中最长递增子序列值中最大的,其值 + 1 来更新 dp[i] 的值;

    2024年02月04日
    浏览(41)
  • 300. 最长递增子序列

    给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如, [3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。 示例 1: 示例 2: 示例 3: 提示: 1 = nums.length = 2500 -104 = nums[i] = 104

    2024年02月09日
    浏览(42)
  • 最长递增子序列——力扣300

    2024年02月12日
    浏览(34)
  • day55 最长递增子序列 最长连续递增子序列 最长重复子数组

    题目链接 300 最长递增子序列 题意 找到整数数组nums的最长严格递增子序列的长度(子序列并不改变原始的顺序,但是可以删除元素) 动态规划 动规五部曲 1)dp数组及下标i的含义 dp[i] 表示以nums[i]为结尾的最长递增子序列的长度 2)dp数组初始化 根据定义 长度至少是1  dp

    2024年04月11日
    浏览(61)
  • 力扣--动态规划300.最长递增子序列

    一开始想到的方法非常低效,但好理解。   思路分析: 使用二维数组 dp 来记录递增子序列的长度信息,其中 dp[i][0] 表示以 nums[i] 结尾的最长递增子序列的长度, dp[i][1] 表示包含 nums[i] 的最长递增子序列的长度。 初始化 dp 数组,将以第一个元素结尾的递增子序列长度置为

    2024年01月24日
    浏览(49)
  • 【重点】【DP】300. 最长递增子序列

    题目 更好的方法是耐心排序,参见《算法小抄》的内容!!! 基础解法必须掌握!!!

    2024年01月17日
    浏览(56)
  • 动态规划9:最长递增子序列、最长连续递增序列、最长重复子数组、最长公共子序列、不相交的线、最长子序和

    例题300: 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。 确定dp数组和下标含义 dp[i]表示在第i个元素的最长子序列数

    2024年04月08日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包