题目描述
农场有n只鸡鸭排为一个队伍,鸡用“C”表示,鸭用“D”表示。当鸡鸭挨着时会产生矛盾。需要对所排的队伍进行调整,使鸡鸭各在一边。每次调整只能让相邻的鸡和鸭交换位置,现在需要尽快完成队伍调整,你需要计算出最少需要调整多少次可以让上述情况最少。例如:CCDCC->CCCDC->CCCCD这样就能使之前的两处鸡鸭相邻变为一处鸡鸭相邻,需要调整队形两次。
输入描述
输入一个长度为N,且只包含C和D的非空字符串。
输出描述
使得最后仅有一对鸡鸭相邻,最少的交换次数
输入
CCDCC
输出
2
问题分析
这个题目其实目的很简单,就是说要把鸡放在一端把鸭放在另一端,我们不可能真的去模拟交换,这样简直太麻烦了,而且会增加很多的时间复杂度。当然啦为了思维好想,我们还是要写一下交换程序的。
class solution:
def __init__(self,st):
self.st = st
def adjust(self):
sumsC = sumsD = 0
tmp = self.st[:]
for i in range(len(self.st)):
if self.st[i] == 'D':
continue
elif self.st[i] == 'C':
j = i
cont = 0
while j > 0 and st[j-1] == 'D':
self.st[j-1],self.st[j] = self.st[j],self.st[j-1] # 交换
cont += 1
j -= 1
sumsC += cont
for i in range(len(tmp)):
if tmp[i] == 'C':
continue
elif tmp[i] == 'D':
j = i
cont = 0
while j > 0 and tmp[j - 1] == 'C':
tmp[j - 1], tmp[j] = tmp[j], tmp[j - 1]
cont += 1
j -= 1
sumsD += cont
return min(sumsC,sumsD)
st = input()
st = list(st)
s = solution(st)
res = s.adjust()
print(res)
然而我们发现交换是没有必要的,反而会增加时间复杂度。因为这题目的场景特别清晰,我们可以用模拟的方式来解决这个问题。我们可以维持一个index指向当前已经挪动好的C或者D,这样我们对每次i 与 index的值取差,再求和,就知道挪动的次数了。
class solution:
def __init__(self,st):
self.st = st
def adjust(self):
count = 0
sumsC = sumsD = 0
for i in range(len(self.st)):
if st[i] == 'C':
sumsC += i - count # i - count是需要交换的次数
count += 1 # 更新C的计数
count = 0
for i in range(len(self.st)):
if st[i] == 'D':
sumsD += i - count
count += 1
return min(sumsC,sumsD)
st = input()
st = list(st)
s = solution(st)
res = s.adjust()
print(res)
来源:CSDN
作者:BJFU_vth
链接:https://blog.csdn.net/weixin_41687289/article/details/104024647