演算法之旋轉字串

2021-08-10 02:24:53 字數 1774 閱讀 8995

題目描述

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

分析與解法

解法一:暴力移位法

初看此題,可能最先想到的方法是按照題目所要求的,把需要移動的字元乙個乙個地移動到字串的尾部,如此我們可以實現乙個函式leftshiftone(char* s, int n) ,以完成移動乙個字元到字串尾部的功能,**如下所示:

void leftshiftone(char* s, int n)

s[n - 1] = t;

}

因此,若要把字串開頭的m個字元移動到字串的尾部,則可以如下操作:

void leftrotatestring(char* s, int n, int m)

}

下面,我們來分析一下這種方法的時間複雜度和空間複雜度。

針對長度為n的字串來說,假設需要移動m個字元到字串的尾部,那麼總共需要 m*n 次操作,同時設立乙個變數儲存第乙個字元,如此,時間複雜度為o(m * n),空間複雜度為o(1),空間複雜度符合題目要求,但時間複雜度不符合,所以,我們得需要尋找其他更好的辦法來降低時間複雜度。

解法二:三步反轉法

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

將乙個字串分成x和y兩個部分,在每部分字串上定義反轉操作,如x^t,即把x的所有字元反轉(如,x="abc",那麼x^t="cba"),那麼就得到下面的結論:(x^ty^t)^t=yx,顯然就解決了字串的反轉問題。

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

首先將原字串分為兩個部分,即x:abc,y:def;

將x反轉,x->x^t,即得:abc->cba;將y反轉,y->y^t,即得:def->fed。

反轉上述步驟得到的結果字串x^ty^t,即反轉字串cbafed的兩部分(cba和fed)給予反轉,cbafed得到defabc,形式化表示為(x^ty^t)^t=yx,這就實現了整個反轉。

**則可以這麼寫:

void reversestring(char* s,int from,int to)

}void leftrotatestring(char* s,int n,int m)

這就是把字串分為兩個部分,先各自反轉再整體反轉的方法,時間複雜度為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」。

演算法題 字串旋轉

對於乙個字串,和字串中的某一位置,請設計乙個演算法,將包括i位置在內的左側部分移動到右邊,將右側部分移動到左邊。給定字串a和它的長度n以及特定位置p,請返回旋轉後的結果。測試樣例 abcdefgh 8,4 返回 fghabcde 正常解法 1.用 按特定位置訪問逐字元拷貝 class stringr...

演算法 左旋轉字串

對於乙個給定的字串行 s,把其迴圈左移 n 位後的序列輸出。例如字串行 s abcdef 輸出迴圈左移3位後的結果,即 defabc 字串 s 為abcdef,n 3,設x abc,y def,原字串可以表示成xy。此時用t表示翻轉,x的翻轉為xt,即xt cba,同理yt fed,那麼yx xty...

演算法整理 字串(LCS,旋轉字串)

字串是程式設計中最重要的一類資料結構,能否對字串進行靈活處理是考察乙個求職者最基本的要求,而且字串在面試中佔的比重也很大,接下來就針對字串相關的演算法進行簡要的整理和歸納。字串相關問題包括最長公共子串 最長公共子串行 字串逆序等等。package com.xpn.string public clas...