LintCode - 旋轉(zhuǎn)字符串(普通)

版權(quán)聲明:本文為博主原創(chuàng)文章评姨,未經(jīng)博主允許不得轉(zhuǎn)載萤晴。

難度:容易
要求:

給定一個(gè)字符串和一個(gè)偏移量,根據(jù)偏移量旋轉(zhuǎn)字符串(從左向右旋轉(zhuǎn))

樣例
對(duì)于字符串 "abcdefg".

offset=0 => "abcdefg"
offset=1 => "gabcdef"
offset=2 => "fgabcde"
offset=3 => "efgabcd"

思路

題目描述:
定義字符串的左旋轉(zhuǎn)操作:把字符串前面的若干個(gè)字符移動(dòng)到字符串的尾部嗦枢。
如把字符串a(chǎn)bcdef左旋轉(zhuǎn)2位得到字符串cdefab屯断。
請(qǐng)實(shí)現(xiàn)字符串左旋轉(zhuǎn)的函數(shù)殖演,要求對(duì)長(zhǎng)度為n的字符串操作的時(shí)間復(fù)雜度為O(n),空間復(fù)雜度為O(1)趴久。
編程之美上有這樣一個(gè)類似的問題彼棍,咱們先來看一下:
設(shè)計(jì)一個(gè)算法座硕,把一個(gè)含有N個(gè)元素的數(shù)組循環(huán)右移K位,要求時(shí)間復(fù)雜度為O(N)华匾,
且只允許使用兩個(gè)附加變量蜘拉。
分析:
我們先試驗(yàn)簡(jiǎn)單的辦法,可以每次將數(shù)組中的元素右移一位诸尽,循環(huán)K次。
abcd1234→4abcd123→34abcd12→234abcd1→1234abcd穿肄。
RightShift(int* arr, int N, int K)
{
while(K--)
{
int t = arr[N - 1];
for(int i = N - 1; i > 0; i --)
arr[i] = arr[i - 1];
arr[0] = t;
}
}
雖然這個(gè)算法可以實(shí)現(xiàn)數(shù)組的循環(huán)右移际看,但是算法復(fù)雜度為O(K * N)仲闽,不符合題目的要求,要繼續(xù)探索。
假如數(shù)組為abcd1234验庙,循環(huán)右移4位的話社牲,我們希望到達(dá)的狀態(tài)是1234abcd。
不妨設(shè)K是一個(gè)非負(fù)的整數(shù)违寿,當(dāng)K為負(fù)整數(shù)的時(shí)候熟空,右移K位,相當(dāng)于左移(-K)位菌瘪。
左移和右移在本質(zhì)上是一樣的阱当。
解法一:
大家開始可能會(huì)有這樣的潛在假設(shè),K<N录淡。事實(shí)上油坝,很多時(shí)候也的確是這樣的。但嚴(yán)格來說彬檀,我們不能用這樣的“慣性思維”來思考問題瞬女。
尤其在編程的時(shí)候,全面地考慮問題是很重要的坤学,K可能是一個(gè)遠(yuǎn)大于N的整數(shù)报慕,在這個(gè)時(shí)候,上面的解法是需要改進(jìn)的飞苇。
仔細(xì)觀察循環(huán)右移的特點(diǎn),不難發(fā)現(xiàn):每個(gè)元素右移N位后都會(huì)回到自己的位置上雨让。因此羽利,如果K > N刊懈,右移K-N之后的數(shù)組序列跟右移K位的結(jié)果是一樣的。
進(jìn)而可得出一條通用的規(guī)律:
右移K位之后的情形匾浪,跟右移K’= K % N位之后的情形一樣卷哩,如代碼清單2-34所示。
//代碼清單2-34
RightShift(int* arr, int N, int K)
{
K %= N;
while(K--)
{
int t = arr[N - 1];
for(int i = N - 1; i > 0; i --)
arr[i] = arr[i - 1];
arr[0] = t;
}
}
可見冷溶,增加考慮循環(huán)右移的特點(diǎn)之后尊浓,算法復(fù)雜度降為O(N^2),這跟K無關(guān)苗胀,與題目的要求又接近了一步瓦堵。但時(shí)間復(fù)雜度還不夠低,接下來讓我們繼續(xù)挖掘循環(huán)右移前后澜驮,數(shù)組之間的關(guān)聯(lián)惋鸥。

解法二:
假設(shè)原數(shù)組序列為abcd1234,要求變換成的數(shù)組序列為1234abcd亭畜,即循環(huán)右移了4位迎卤。比較之后,不難看出劲藐,其中有兩段的順序是不變的:1234和abcd,可把這兩段看成兩個(gè)整體兄渺。右移K位的過程就是把數(shù)組的兩部分交換一下汰现。
變換的過程通過以下步驟完成:
逆序排列abcd:abcd1234 → dcba1234;
逆序排列1234:dcba1234 → dcba4321口叙;
全部逆序:dcba4321 → 1234abcd嗅战。
偽代碼可以參考清單2-35。
//代碼清單2-35
Reverse(int* arr, int b, int e)
{
for(; b < e; b++, e--)
{
int temp = arr[e];
arr[e] = arr[b];
arr[b] = temp;
}
}
RightShift(int* arr, int N, int k)
{
K %= N;
Reverse(arr, 0, N – K - 1);
Reverse(arr, N - K, N - 1);
Reverse(arr, 0, N - 1);
}
這樣疟呐,我們就可以在線性時(shí)間內(nèi)實(shí)現(xiàn)右移操作了萨醒。

  public class Solution {
    /**
     * @param str: an array of char
     * @param offset: an integer
     * @return: nothing
     */
    public void rotateString(char[] str, int offset) {
        if(str == null || str.length == 0){
            return;
        }
        
        int len = str.length;
        offset = offset % len;
        reverse(str, 0, len - offset - 1);
        reverse(str, len - offset, len - 1);
        reverse(str, 0, len - 1);
    }
    
    private void reverse(char[] str,int start,int end){
        for( ;start < end; start++,end--){
            char tmp = str[start];
            str[start] = str[end];
            str[end] = tmp;
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末富纸,一起剝皮案震驚了整個(gè)濱河市旨椒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涣仿,老刑警劉巖示惊,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件米罚,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡录择,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門讼渊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來尊剔,“玉大人,你說我怎么就攤上這事挨稿∨冢” “怎么了叶组?”我有些...
    開封第一講書人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵拯田,是天一觀的道長(zhǎng)历造。 經(jīng)常有香客問我,道長(zhǎng)船庇,這世上最難降的妖魔是什么吭产? 我笑而不...
    開封第一講書人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮鸭轮,結(jié)果婚禮上臣淤,老公的妹妹穿的比我還像新娘。我一直安慰自己窃爷,他們只是感情好邑蒋,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開白布按厘。 她就那樣靜靜地躺著医吊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪逮京。 梳的紋絲不亂的頭發(fā)上卿堂,一...
    開封第一講書人閱讀 52,268評(píng)論 1 309
  • 那天,我揣著相機(jī)與錄音懒棉,去河邊找鬼草描。 笑死,一個(gè)胖子當(dāng)著我的面吹牛策严,可吹牛的內(nèi)容都是我干的穗慕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼妻导,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼揍诽!你這毒婦竟也來了诀蓉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤暑脆,失蹤者是張志新(化名)和其女友劉穎渠啤,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體添吗,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沥曹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碟联。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妓美。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鲤孵,靈堂內(nèi)的尸體忽然破棺而出壶栋,到底是詐尸還是另有隱情,我是刑警寧澤普监,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布贵试,位于F島的核電站,受9級(jí)特大地震影響凯正,放射性物質(zhì)發(fā)生泄漏毙玻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一廊散、第九天 我趴在偏房一處隱蔽的房頂上張望桑滩。 院中可真熱鬧,春花似錦允睹、人聲如沸运准。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)胁澳。三九已至,卻和暖如春贯涎,著一層夾襖步出監(jiān)牢的瞬間听哭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工塘雳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留陆盘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓败明,卻偏偏與公主長(zhǎng)得像隘马,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子妻顶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容