[牛客] 构造回文 腾讯2017暑期实习生编程题 python解法

链接:https://www.nowcoder.com/questionTerminal/28c1dc06bc9b4afd957b01acdf046e69

错误答案(感觉思路是对的,但是结果不对,,):

# -*- coding:utf-8 -*-
import sys
"""
基本思路:
删除一些字符剩下的子序列最长(注意不是子串,子串要求连续)--> 联想最长公共子序列
既然是公共,就意味着要有两个串来比较,考虑到回文串要求正串和反串的遍历结果相同,显然这两个比较对象就是原序列的正串和反串啦
"""
def lcp(strs):
    if strs == None or len(strs) == 0:
        return 0
    lens = len(strs) + 1
    r_strs = strs[::-1]  # 反转字符串

    # 初始化dp数组
    dp = [[0] * lens] * lens  # 数值为两串在该下标位置的子串的最大公共子序列长度

    # dp数组是从左到右,从上到下更新的,所以如果strs[i] == r_strs[j],那么当前位置的值就是左上方的值+1
    # 否则就是左方和上方中值最大的一个(左边代表用正串之前的状态和反串当前状态的比较,上方是指正串当前的状态和反串之前的状态进行比较)
    # 为什么不是右方和下方?因为此时dp数组还没更新到那
    for i in range(1,lens):
        for j in range(1,lens):
            if strs[i-1] == r_strs[j-1]:
                dp[i][j] = dp[i-1][j-1] + 1
            else:
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])

    return dp[lens-1][lens-1]


if __name__=='__main__':
    while True:
        line = sys.stdin.readline().strip()
        lens = len(line)
        if not line:
            break

        num_lcp = lcp(line)
        print(lens-num_lcp)

正确答案:

#  -*- coding:utf-8 -*-
import sys


def maxlcp(strs):
    if strs == None or len(strs) == 0:
        return 0
    lens = len(strs)
    dp = [0] * lens
    dp[0] = 1 if strs[0] == strs[lens - 1] else 0
    for i in range(lens):
        pre = dp[0]
        dp[0] = max(dp[0], 1 if strs[i] == strs[lens - 1] else 0)
        for j in range(1, lens):
            cur = dp[j]
            dp[j] = max(dp[j], dp[j - 1])
            if strs[i] == strs[lens - 1 - j]:
                dp[j] = max(dp[j], pre + 1)
            pre = cur

    return dp[lens - 1]


if __name__ == '__main__':
    while True:
        line = sys.stdin.readline().strip()
        lens = len(line)
        if not line:
            break
        maxLcp = maxlcp(line)
        # print lens
        # print maxLcp
        print( lens - maxLcp)

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值