最长公共子序列、最长公共子串、连续数组最大和、最长上升子序列

总结几个容易混淆的问题

问题一:连续数组的最大和

问题描述:输入一个整型数组,数组中有正数有负数。数组中的一个或多个正数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)

解法一:动态规划方法

递推公式:f(i-1)<0: f(i)=f(i-1)+a[i]   f(i-1)>=0: f(i)=a[i];

public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        //使用动态规划的方法
        int len=array.length;
        int[] memo=new int[len];
        memo[0]=array[0];
        for(int i=1; i<len; i++){
            if(memo[i-1]>=0){
                memo[i]=array[i]+memo[i-1];
            }else{
                memo[i]=array[i];
            }
        }
        int max=array[0];
        for(int i=0; i<len; i++){
            if(memo[i]>max){
                max=memo[i];
            }
        }
        return max;
    }
}

解法二:思路来源于剑指offer 与动态规划实质是一样的,即遍历数组,如果当前求和小于0则抛弃,否则累加,然后记录最大值

public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        int max=Integer.MIN_VALUE;
        int sum=0;
        for(int i=0; i<array.length;i++){
            if(sum>0){
                sum+=array[i];
            }else{
                sum=array[i];    
            }
           if(sum>max){
                    max=sum;
           } 
        }
        return max;
    }
}

问题二:最长公共子序列

动态规划思路

递推公式为:

s1[m]==s2[n]: LCS(m, n)=1+LCS(m-1,n-1)

s1[m]!=s2[n]: LCS(m,n)=max(LCS(m-1,n), LCS(m,n-1))

其中LCS(m,n)定义为 字符串s1以m为结尾的字符串和字符串s2以n为结尾的字符串的最长公共子序列

问题三:最长公共子串

子串区别于子序列是要求连续,递推公式也有区别:

s1[m]==s2[n]: memo(m, n)=1+memo(m-1,n-1)

s1[m]!=s2[n]: 0

问题四:最长上升子序列(LIS)

解法:使用动态规划的方法,

class Solution {
    public int lengthOfLIS(int[] nums) {
        //使用动态规划的思路
        //状态转移方程为 LIS(i)=max(1+LIS(j)) if(num[i]>num[j]) 
        if(nums==null || nums.length==0)
            return 0;
        int n=nums.length;
        int max=1;
        int[] lis=new int[n];
        for(int i=0; i<n; i++){
            lis[i]=1;
        }
       
        for(int i=1; i<n; i++){
            
            for(int j=0;j<i; j++){
                if(nums[j]<nums[i]){
                    if(lis[j]+1>lis[i]){
                        lis[i]=lis[j]+1;
                    }
                }
            }
            if(lis[i]>max)
                max=lis[i];
            
        }
        return max;
        
    }
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值