1. 程式人生 > 實用技巧 >字串反轉

字串反轉

題目描述:

給定一個字串,要求把字串前面的若干個字元移動到字串的尾部,如把字串“abcdef”前面的2個字元’a’和’b’移動到字串的尾部,使得原字串變成字串“cdefab”。請寫一個函式完成此功能,要求對長度為n的字串操作的時間複雜度為 O(n),空間複雜度為 O(1)。

解題思路:

對於這個問題,換一個角度思考一下。

將一個字串分成X和Y兩個部分,在每部分字串上定義反轉操作,如X^T,即把X的所有字元反轉(如,X=”abc”,那麼X^T=”cba”),那麼就得到下面的結論:(X^TY^T)^T=YX,顯然就解決了字串的反轉問題。

例如,字串 abcdef ,若要讓def翻轉到abc的前頭,只要按照下述3個步驟操作即可:

  1. 首先將原字串分為兩個部分,即X:abc,Y:def;
  2. 將X反轉,X->X^T,即得:abc->cba;將Y反轉,Y->Y^T,即得:def->fed。
  3. 反轉上述步驟得到的結果字串X^TY^T,即反轉字串cbafed的兩部分(cba和fed)給予反轉,cbafed得到defabc,形式化表示為(X^TY^T)^T=YX,這就實現了整個反轉。

如下圖所示:

func ReverseString(b []byte,from,to int) []byte {
	var fromI,toI = from,to
	for fromI < toI  {
		t := b[fromI]
		b[fromI] = b[toI]
		b[toI] = t
		toI--
		fromI++
	}
	return b
}

func LeftRotateString(s string ,m int)string {
	b := []byte(s)
	n := len(b)
	b = ReverseString(b, 0, m - 1) //反轉[0..m - 1],套用到上面舉的例子中,就是X->X^T,即 abc->cba
	b = ReverseString(b, m, n - 1)//反轉[m..n - 1],例如Y->Y^T,即 def->fed
	b = ReverseString(b, 0, n - 1) //反轉[0..n - 1],即如整個反轉,(X^TY^T)^T=YX,即 cbafed->defabc。
	return string(b)
}

  這就是把字串分為兩個部分,先各自反轉再整體反轉的方法,時間複雜度為O(n),空間複雜度為O(1),達到了題目的要求。

舉一反三:

1、連結串列翻轉。給出一個連結串列和一個數k,比如,連結串列為1→2→3→4→5→6,k=2,則翻轉後2→1→6→5→4→3,若k=3,翻轉後3→2→1→6→5→4,若k=4,翻轉後4→3→2→1→6→5,用程式實現。

2、編寫程式,在原字串中把字串尾部的m個字元移動到字串的頭部,要求:長度為n的字串操作時間複雜度為O(n),空間複雜度為O(1)。 例如,原字串為”Ilovebaofeng”,m=7,輸出結果為:”baofengIlove”。

3、單詞翻轉。輸入一個英文句子,翻轉句子中單詞的順序,但單詞內字元的順序不變,句子中單詞以空格符隔開。為簡單起見,標點符號和普通字母一樣處理。例如,輸入“I am a student.”,則輸出“student. a am I”。