最长公共子序列长度

本文详细解析了贝壳笔试题中的最长递增子序列问题,提供了两种解决方案:一是动态规划方法,时间复杂度为O(n^2),二是结合贪心算法与二分查找的优化方案,时间复杂度降低至O(NlogN)。通过实例测试数据,展示了不同方法的状态转移过程及最终结果。

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

贝壳笔试题:

方法一,用动态规划 时间复杂度O(n^2)

话不多说上代码

public static int lengthOfLIS(int[] nums) {
         int max = 1;
       int length[] = new int [nums.length];
         for (int i = 0; i <nums.length;i++){  //子序列的终点
               length[i] = 1;   //默认只有自己一个
             for (int j = 0; j <i;j++) {  //从头开始向终点找序列
                 if(nums[i]> nums[j]){
                     length[i]=Math.max(length[i],length[j]+1);
                 }
             }
             max = Math.max(max,length[i]);
         }
         return max;
     }

 状态转移方程  dp[i] = max(dp[i] + dp[j]+1)  (a[i>a[j]]  0<j<i)

  dp[i] 表示长度数组

测试数据 N =8

数据为{5,1,6,8,2,4,5,10} 

 

dp[i]j=0j=1j=2j=3j=4j=5j=6j=7
dp[0]1       
dp[1]1       
dp[2]22      
dp[3]223     
dp[4]1222    
dp[5]12223   
dp[6]121134  
dp[7]22344445

   整个dp[]数组大概就是dp[1,1,2,3,2,3,4,5];  然后在取出最大的数字就行。

 方法二:  贪心+二分 时间复杂度 O(NlogN)

 只需要维护 dp[]数组,贪心的选择就是每次找最小的一个为最后一个,对于一个上升子序列如果最后一个数最小,越有利于继续往后再添加数字。 dp[] 最长长度的一个子序列,他的长度就是最长子序列长度。

还是以上的测试用例 arr{5,1,6,8,2,4,5,10}  

//二分查
    public static int lengthOfLIS(int[] nums){
        int[] top = new int[nums.length];
        int piles = 0;
        for (int i = 0; i < nums.length; i++) {
            int poker = nums[i];
            *//***** 搜索左侧边界的二分查找 *****//*
            int left = 0, right = piles;
            while (left < right){
                int mid = (left + right) / 2;
                if (top[mid] > poker) {
                    right = mid;
                } else if (top[mid] < poker) {
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }
            if (left == piles) piles++;
            top[left] = poker;
        }
        return piles;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值