1. 程式人生 > >程式設計之法面試和演算法心得-1.1字串的旋轉

程式設計之法面試和演算法心得-1.1字串的旋轉

本部落格的創作的演算法來源於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).

三、解法二:三步反轉

三步反轉的思維比較巧妙,做法分為三步:

  1. 將字串分為兩部分,要移位的m個字元X和剩下的字元Y。如“abcdef”,則X=“abc”,Y=“def”
  2. 將X進行反轉,得到“cba”;將Y進行反轉,得到“fed”
  3. 將反轉後的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/第一章