最大子序列,最大连续递增子序列,最大公共子列的Python实现

整理一下近期写的代码:
经典子序列的问题:

最大子序列(连续的)

给定一个列表,求出和最大的一个连续子序列

my_num=8
my_arr=[-2,6,-1,5,4,-7,2,3]
#最大子序列(是连续的)
# 暴力循环
# 初始化最大和列表的第一个元素

# 三层循环
def method1(Num,arr):
    ans = arr[0]
    for i in range(Num):
        for j in range(i,Num):
            s=0
            for k in range(i,j+1):
                s+=arr[k]
            if s>ans:
                ans=s
    print(ans)
# 简单的优化,先求出一个和数组
def method2(Num,arr):
    sum=[-float('Inf') for i in range(Num+1)]
    sum[0],ans=0,arr[0]
    for i in range(1,Num):
        sum[i]=arr[i]+sum[i-1]
    for i in range(1,Num+1):
        for j in range(i,Num+1):
            if sum[j]-sum[i-1]>ans:
                ans=sum[j]-sum[i-1]
    print(ans)
# 第三种递归实现
def findMaxSum(arr,left,right):
    # 设置终止条件
    # 分组
    if left==right:
        return arr[left]
    mid=(left+right)//2
    leftMaxSum=findMaxSum(arr,left,mid)
    rightMaxSum=findMaxSum(arr,mid+1,right)
    left_max,right_max,temp=-float('Inf'),-float('Inf'),0
    for i in range(mid,left-1,-1):
        temp+=arr[i]
        if temp>left_max:
            left_max=temp
    temp=0
    for i in range(mid+1,right+1):
        temp+=arr[i]
        if temp>right_max:
            right_max=temp
    cross_max=left_max+right_max
    return max(leftMaxSum,rightMaxSum,cross_max)
#动态规划1 递推公式
# dp[n] = max(0, dp[n-1]) + arr[n]
def method4(arr):
    dp=arr[:]
    maxvalue,start,end=arr[0],0,0
    for n in range(1,len(arr)):
        if dp[n-1]>0:
            dp[n]=dp[n-1]+arr[n]
        else:
            dp[n]=arr[n]
            start=n
        if dp[n]>maxvalue:
            maxvalue=dp[n]
            end=n
    print(maxvalue,arr[start:end+1])
# 动态规划2:可以标识起始点
# sum(j)=max(sum(j-1)+aj,aj)
def method5(arr):
    maxvalue,temp,begin,end=0,0,0,0
    for i in range(len(arr)):
        if temp>0:
            temp+=arr[i]
        else:
            temp=arr[i]
            begin=i
        if temp>maxvalue:
            maxvalue=temp
            end=i
    print(maxvalue,arr[begin:end+1])

最大连续递增子序列

连续递增的子序列(动态规划法):

my_num=8
my_arr=[0,1,2,3,-1,0,1,2,3,-4,-5]
#最长连续递增序列
def method1(arr):
    temp,maxl,end=1,0,0
    for i in range(1,len(arr)):
        if arr[i]>arr[i-1]:
            temp+=1
        else:
            temp=1
        if temp>maxl:
            maxl=temp
            end=i
    print(maxl,arr[end+1-maxl:end+1])
# method1([1,9,2,5,7,3,4,6,8,0,11,15,17,17,10])

最大公共子列LCS

# 求最长公共子序列,可以不连续
# 动态规划
def LCS(arr1,arr2):
    len1,len2=len(arr1),len(arr2)
    vals=[[0 for i in range(len2+1)] for j in range(len1+1)]
    #新建一个方向列表,用于回溯
    directions = [[None for i in range(len2+1)] for j in range(len1+1)]
    for i in range(len1):
        fi=i+1
        for j in range(len2):
            fj=j+1
            if arr1[i]==arr2[j]:
                vals[fi][fj]=vals[i][j]+1
                directions[fi][fj]='ok'
            elif vals[i][fj]>vals[fi][j]:
                vals[fi][fj] = vals[i][fj]
                directions[fi][fj]='top'
            elif vals[i][fj]<=vals[fi][j]:
                vals[fi][fj]=vals[fi][j]
                directions[fi][fj] = 'left'
    maxNum=vals[len1][len2]
    (row,col)=(len1,len2)
    commons=[]
    while directions[row][col]:
        if directions[row][col]=='ok':
            commons.append(arr1[row-1])
            row-=1
            col-=1
        elif directions[row][col]=='top':
            row-=1
        elif directions[row][col]=='left':
            col-=1
    output=commons[::-1]
    return (maxNum,output)
print(LCS([2,3,4,0,1,3],[0,1,2,3,3,4]))

不足之处:如果存在多个最大公共子列,输出其中一个。输出全部的有待进一步优化。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值