• Leetcode 673.最长递增子序列的个数


    最长递增子序列的个数

    给定一个未排序的整数数组,找到最长递增子序列的个数。

    示例 1:

    输入: [1,3,5,4,7]

    输出: 2

    解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[1, 3, 5, 7]。

    示例 2:

    输入: [2,2,2,2,2]

    输出: 5

    解释: 最长递增子序列的长度是1,并且存在5个子序列的长度为1,因此输出5。

    注意: 给定的数组长度不超过 2000 并且结果一定是32位有符号整数。

    思路

    定义 dp(n,1) cnt (n,1)

    这里我用dp[i]表示以nums[i]为结尾的递推序列的长度,用cnt[i]表示以nums[i]为结尾的递推序列的个数,初始化都赋值为1,只要有数字,那么至少都是1。然后我们遍历数组,对于每个遍历到的数字nums[i],我们再遍历其之前的所有数字nums[j],当nums[i]小于等于nums[j]时,不做任何处理,因为不是递增序列。反之,则判断dp[i]和dp[j]的关系,如果dp[i]等于dp[j] + 1,说明nums[i]这个数字可以加在以nums[j]结尾的递增序列后面,并且以nums[j]结尾的递增序列个数可以直接加到以nums[i]结尾的递增序列个数上。如果dp[i]小于dp[j] + 1,说明我们找到了一条长度更长的递增序列,那么我们此时奖dp[i]更新为dp[j]+1,并且原本的递增序列都不能用了,直接用cnt[j]来代替。维护一个全局最长的子序列长度mx,每次都进行更新,到最后遍历一遍每个节点,如果长度等于mx,res+=cnt[i];

     1 import java.util.Arrays;
     2 
     3 class Solution {
     4     public int findNumberOfLIS(int[] nums) {
     5         int n=nums.length;
     6         int max_len=1;
     7         int res=0;
     8         int[] dp=new int[n];
     9         int[] cnt=new int[n];
    10         Arrays.fill(dp,1);
    11         Arrays.fill(cnt,1);
    12         for(int i=1;i<n;i++){
    13             for(int j=0;j<i;j++){
    14                 if(nums[j]<nums[i]&&dp[j]+1>dp[i]){
    15                     dp[i]=dp[j]+1;
    16                     cnt[i]=cnt[j];
    17                 }else if(nums[j]<nums[i]&&dp[j]+1==dp[i]){
    18                     cnt[i]+=cnt[j];
    19                 }
    20             }
    21             max_len=Math.max(max_len,dp[i]);
    22         }
    23         for(int i=0;i<n;i++){
    24             if(dp[i]==max_len) res+=cnt[i];
    25         }
    26         return res;
    27     }
    28 }
  • 相关阅读:
    教师资格证考试全部重点名词解释
    计算机软考中高级职称评定条件
    如何计算教师工龄?工龄和教龄的区别
    vue.js中 this.$nextTick()的使用
    数组的合并 总结的几种方法
    CSS3实现了左右固定中间自适应的几种方法
    文本溢出省略号
    MVC/MVP/MVVM
    vue中父组件给子组件传值的方法
    vue实例的生命周期
  • 原文地址:https://www.cnblogs.com/kexinxin/p/10400318.html
Copyright © 2020-2023  润新知