本博客的创作的算法来源于July创作的《编程之法面试和算法心得》一书,特此声明。我再学习此书的同时在结合了自己的一些理解,用python实现了一遍。在后面的系列博客中,不再重述,直接进入正题。
一、题目描述
给定一个字符串,要求字符串前面若干个字符移到字符串的尾部。例如,将字符串“abcdef”的前三个字符移到字符串的尾部,则得到“defabc”。请写一个函数实现该功能。
二、解法一:蛮力移位
假设需要移位m个字符,字符串的总长度为n,则蛮力移位需要遍历该字符串m次,将m个需要移位的字符搬到该字符串的尾部。因此可以分成两个函数实现,首先第一个函数用来搬移第一个字符到该字符串的尾部。
def LeftShiftOne(str, n):
s = []
s = list(str)
t = s[0]
for i in range(1,n):
s[i-1] = s[i]
s[n-1] = t
return s
第二个函数写个for训练遍历m次即可得到移位的字符串。
def LeftRotateString(s, n, m):
while(m):
s = LeftShiftOne(s, n)
m = m - 1
return s
该算法想法和实现都简单,但是时间复杂度比较高,为:O(mn),空间复杂度为O(1).
三、解法二:三步反转
三步反转的思维比较巧妙,做法分为三步:
- 将字符串分为两部分,要移位的m个字符X和剩下的字符Y。如“abcdef”,则X=“abc”,Y=“def”
- 将X进行反转,得到“cba”;将Y进行反转,得到“fed”
- 将反转后的XY合并字符串在进行反转,最后得到“defabc”。
python参考代码:
def ReverseString(s, l1, l2):
s = list(s)
while(l1 < l2):
t = s[l1]
s[l1] = s[l2]
s[l2] = t
l1 = l1 + 1
l2 = l2 - 1
return s
def LeftRotateString(s, n, m):
m = m % n
s = ReverseString(s, 0, m-1)
s = ReverseString(s, m, n-1)
s = ReverseString(s, 0, n-1)
return s
四、课后题:单词反转
可以将每个单词看成一个单独的字符,再利用三步反转一步可实现,这时候移动量m=n。
python参考代码:
def ReverseWord(s, to):
start = 0
while(start < to):
t = s[start]
s[start] = s[to]
s[to] = t
start = start + 1
to = to - 1
return s
def LeftRotateWord(s):
s = s.split(" ")
n = len(s)
s = ReverseWord(s, n-1)
str = []
for i in range(2*n-1):
if(i % 2 == 0):
str.append(s[int(i/2)])
else:
str.append(" ")
str = ''.join(str)
return str
整个代码地址:https://github.com/idotc/Interview-And-Algorithm-Experience/tree/master/第一章