首页 > 其他分享 >leet code 300.最长递增子序列

leet code 300.最长递增子序列

时间:2023-09-01 21:32:58浏览次数:43  
标签:leet code 300 递增 元素 int 数组 序列 dp

题目链接 难度:中等

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

思路历程

  • 首先明确问题,带着问题找解决办法
  • 题目给定了一个数组nums,需要找出其中最长严格递增子序列的程度
  • 严格递增子序列:需要保证子序列数组元素不重复
  • ex:nums = [10, 9, 2, 5, 3, 7, 101, 18] 输出:4
  • 最长递增子序列是:[2, 3, 7, 101] 所以输出:4

学习题解

动态规划

  • 可以定义 代表前个元素
  • 其意义是,以第leet code 300.最长递增子序列_数组个数字结尾的最长子序列的长度
  • 然后可以从小到大计算leet code 300.最长递增子序列_数组_02数组的值,在计算leet code 300.最长递增子序列_递增子序列_03之前,肯定已经计算出了leet code 300.最长递增子序列_递增子序列_04的值
  • 则状态转移方程为
  • 以数组nums = [10, 9, 2, 5, 3, 7, 101, 18]为例,过程如下
  • 对于元素10而言,子序列为1——dp[0] = 1
  • 元素9——子序列为9——dp[1] = 1
  • 元素2——子序列为2——dp[2] = 1
  • 元素3——子序列为2,3——dp[3] = 2
  • 以此类推

code+理解

public int lengthOfLIS(int[] nums) {
    // 动态规划解决,首先需要获取数组的长度.
    int n = nums.length;
    // 创建 dp 数组
    int[] dp = new int[n];
    // 定义变量输出最终结果值
    int ans = 0;
    // 循环数组处理数据
    for (int i = 0; i < nums.length; i++) {
        for (int j = 0; j < i; j++) {
            if(nums[j] < nums[i]) {
                // 小于:表示能够构成 递增子序列
                dp[i] = Math.max(dp[i], dp[j]);
            }
        }
        dp[i] += 1;
        ans = Math.max(dp[i], ans);
    }
    return ans;
}
  • 根据状态转移方程,可以知道我们需要做的事情是
  • 寻找索引和值都小于当前元素的 值.
  • 目标值能够与当前元素所构成的 最长递增子序列 长度+1
  • 然后在 循环过程中找到 最长递增的子序列

动态规划+二分查找

  • “贪心”——如果想要使上升子序列尽可能的长,那么在构建子序列的时候,期望最后加入的数字尽可能地小。
  • 以数组 nums = [10, 9, 2, 5, 3, 7, 101, 18] 为例
  • 维护一个数组 int[] lis = new int[n]; 来存放 最长递增子序列
  • 遍历到元素10——最长递增子序列为 [10] 长度为 1
  • 遍历到元素9 ——最长递增子序列为 [9] 长度为 1
  • 为什么更新最长递增子序列为[9]?
  • 因为 9 比 10 小,在向后遍历过程中的话,很显然以元素9开头更有可能构成一个最长的递增子序列
  • 遍历到元素2 ——最长递增子序列为 [2] 长度为 1
  • 遍历到元素5 ——最长递增子序列为 [2, 5] 长度为 2
  • 遍历到元素3 ——最长递增子序列为 [2, 3] 长度为 2
  • 遍历到元素7 ——最长递增子序列为 [2, 3, 7] 长度为 3
  • 遍历到元素101 ——最长递增子序列为 [2, 3, 7, 101] 长度为 4
  • 遍历到元素18 ——最长递增子序列为 [2, 3, 7, 18] 长度为 4
  • 那么算法就变成了,每遍历一个新的元素,需要判断其是否能够加入到 lis 数组中去
  • 比数组lis末尾元素大,那么追加
  • 比数组lis末尾元素小,那么替换

code+理解

public int best(int[] arr) {
        int n = arr.length;
        // 定义一个数组,用来存放最长递增 子序列.
        int[] lis = new int[n];
        int pos = 0;
        for (int num : arr) {
            // 这个时候要去寻找  pos 在数组中的位置.
            int left = 0, right = pos;

            //  二分查找:这里查找什么?
            //  查找元素 num 是否能在 lis 数组中找到最接近且大于的元素.
            //  由于初始化 right = pos = 0,直接跳过二分查找步骤
            //  进入二分查找的逻辑的话,就要去寻找 最接近 num 的元素
            //  ---即,寻找第一个比当前 num 元素大的元素.
            //        如果能找到的话--进行替换
            //        如果找不到的话--进行追加
            while(left < right) {
                int mid = left + (right - left) / 2;
                if(lis[mid] < num) {
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }

            lis[left] = num;
            if(left == pos) {
                pos++;
            }
        }
        return pos;
    }


标签:leet,code,300,递增,元素,int,数组,序列,dp
From: https://blog.51cto.com/u_16079703/7326509

相关文章

  • CF1626F A Random Code Problem 题解
    题意给定长度为\(n\)的数组\(a\)和一个整数\(k\),执行下面的代码:longlongans=0;//定义一个初始值为0的长整型变量for(inti=1;i<=k;i++){ intidx=rnd.next(0,n-1);//生成一个介于0到n-1的随机数(含0和n-1) //每个数被选中的概率是相同的 an......
  • COMP SCI 3004操作系统的虚拟内存模拟
    SCI3004COMPSCI3004/7064OperatingSystemsPractical2–VirtualMemorySimulationAimBydoingthispracticalwork,youwilllearnhowtoimplementpagereplacementalgorithms,gainexperienceincreatingandevaluatingasimplesimulator,anddevelopyour......
  • Educational Codeforces Round 5 A-E
    EducationalCodeforcesRound5垫底咯,中间老师找我去聊了下新学期的机房借用和训练,但出去前就只有我没出E目录EducationalCodeforcesRound5AComparingTwoLongIntegersBDinnerwithEmmaCTheLabyrinthDLongestk-GoodSegmentE-SumofRemaindersAComparingTwo......
  • idea插件easycode
    作为Java开发者,我们经常需要编写大量的重复性代码,例如实体类的属性、Getter和Setter方法、数据库操作代码等。这些繁琐的工作占用了我们宝贵的时间和精力,影响了开发效率。幸运的是,有一款强大的IDEA插件,名为EasyCode,可以帮助我们自动生成这些重复代码,极大地提升开发效率。在......
  • AtCoder Beginner Contest 317 C - Remembering the Days
    C-RememberingtheDays原题链接题意:每个点最多经过一次,求最长路思路:数据范围很小,深搜每个点能到其他点的所有路,取最大#include<bits/stdc++.h>usingnamespacestd;constintN=110;intg[N][N];intn,m;boolst[N];intw=0;intans=0;voiddfs(intu){ st[......
  • 解决Ubuntu 安装出现E: Sub-process /usr/bin/dpkg returned an error code (1)异常(轮
     cd/var/lib/dpkg/sudomvinfo/info.bak#现将info文件夹更名sudomkdirinfo#再新建一个新的info文件夹sudoapt-getupdate#更新sudoapt-get-finstall#修复sudomvinfo/*info.bak/#执行完上一步......
  • vscode自动import导致报错
    vscode自动添加了这么一句import{Template}from"webpack";导致出现奇葩错误Can'tresolve'fs'in'/xxx/Desktop/ncpub/node_modules/.pnpm/[email protected]/node_modules/move-concurrentlyCan'tresolve'fs'in'/......
  • 重写equals为什么还要重写hashcode
    重写equals为什么还要重写hashcode1、为了保证一个原则,equals相同的两个对象hashcode必须相同。如果重写了equals而没有重写hashcode,会出现equals相同hashcode不相同这个现象。2、在散列集合中,是使用hashcode来计算key应存储在hash表的索引,如果重写了equals而没有重写hashcode,......
  • AtCoder Beginner Contest 317
    A-Potions#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongintpower(intx,inty,intp){x%=p;intans=1;while(y){if(y&1)ans=ans*x%p;y>>=1,x=x*x%p;}......
  • Java:commons-codec实现byte数组和16进制字符串转换
    (目录)commons-codec文档https://commons.apache.org/proper/commons-codec/https://mvnrepository.com/artifact/commons-codec/commons-codec坐标<dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifact......