问题描述
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
输入格式
第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
第二行是一个字符串,长度为N.只包含小写字母
输出格式
如果可能,输出最少的交换次数。
否则输出Impossible
样例输入
5
mamad
样例输出
3
def judge(s, n): #判断字符串是否全为小写字母,且可以被回文处理,
temp = []
if n > 8000:
print('String too long')
return False
if n < 27: #当长度小于27时,使用字符串循环,加快处理速度
for i in range (n):
if ord(s[i]) in range(97, 124):
if s.count(s[i]) % 2 != 0:
temp.append(s[i])
else:
print('Impossible')
return False
if len(temp) > 1:
print('Impossible')
return False
else:
return True
else:
for i in range(26): # 长度大于27时, 循环a-z字母
if s.count(chr(97 + i)) % 2 != 0: #ord('a')=97
temp.append(chr(97 + i))
if len(temp) > 1:
print('Impossible')
return False
else:
return True
def shift(s, n, sl, steplist): #以字符串左端作基准,移动右端字母,形成回文
steps = [] #移动步数列表
poplist = [] #移动字母列表
single = ''
for i in range(n // 2):
if s[i:].count(s[i]) != 1: #判断是否有单独字母需要移动,不是单独字母则为成对字母,尾端字母需要移动
temp = sl.index(s[i]) #需要移动步数,将s逆序方便计算步数
poplist.append(sl.pop(temp))
steps.append(temp)
s = sl[::-1]
else:
single = s[i] #若有单独字母,标记
s.extend(poplist[::-1])
steplist = list(zip(poplist, steps))
if single != '': #最后移动单独字母
temp = n // 2 - s.index(single)
s.remove(single)
s.insert(n // 2, single)
steps.append(temp)
steplist.append((single, temp))
return steplist, sum(steps), ' '.join(s) #移动顺序,总步数,最终回文
while True:
s = list(input('string:'))
n = len(s)
sl = s[::-1]
steplist = []
if judge(s, n):
print(shift(s, n, sl, steplist))
输出格式:移动顺序,总步数,最终回文。
参考链接:https://blog.csdn.net/bianxia123456/article/details/104388390