链接: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)