1. 程式人生 > >【劍指Offer】43、左旋轉字符串

【劍指Offer】43、左旋轉字符串

實現 不難 return arr 語言 旋轉 三次 掃描 反轉

??題目描述:

??匯編語言中有一種移位指令叫做循環左移(ROL),現在有個簡單的任務,就是用字符串模擬這個指令的運算結果。對於一個給定的字符序列S,請你把其循環左移K位後的序列輸出。例如,字符序列S=”abcXYZdef”,要求輸出循環左移3位後的結果,即“XYZdefabc”。是不是很簡單?OK,搞定它!

??解題思路:

??對於本題,從最直觀的角度我們首先可以想到暴力解法:每次移動一位,移動k次為止。對於每一次移動,其實就是將字符串第一個字符放到字符串末尾,而為了實現這一目標,需要將字符串其他位置的元素依次前移,因此,暴力解法時間復雜度為O(n^2)。

??還是那句話:最容易想到的解法往往不是最優的。

??進一步考慮,字符串左移k位,就相當於將字符串分為兩部分,第一部分是前k位,另一部分是剩余的其他位,然後將這兩部分交換順序即可得到最後結果。因此,我們可以得到以下的三次反轉算法

??將字符串分為兩部分,即前k個字符和剩余的其他字符,然後分別對這兩部分進行反轉,然後再對整個字符串進行一次反轉,這樣得到的結果就是我們想要的循環左移之後的字符串。事實上,這並不難理解,前後兩部分各自經歷了兩次反轉,因此每一部分的順序並沒有改變,只是將前後兩部分進行了交換。對字符串進行一次反轉,需要一次掃描,因此次算法時間復雜度為O(n)。

??舉例:

??輸入字符串"abcdefg"和數字2,該函數將返回左旋轉2位得到的結果"cdefgab";

??第一步:翻轉字符串“ab”,得到"ba";

??第二步:翻轉字符串"cdefg",得到"gfedc";

??第三步:翻轉字符串"bagfedc",得到"cdefgab";

??編程實現(Java):

    //方法一,依次左移,每次移動一位
    public String LeftRotateString(String str,int n) {
        char[] strArr=str.toCharArray();
        int len=strArr.length;
        if(len<=0)
            return str;
        n=n%len;
        for(int i=0;i<n;i++){  //只控制循環次數
            char c=strArr[0];
            for(int j=0;j<len-1;j++) //拿出第一個,後面依次前移,復雜度O(n^2)
                strArr[j]=strArr[j+1];
            strArr[len-1]=c;
        }
        return new String(strArr);
    }

    //方法二:三次反轉
    public String LeftRotateString(String str,int n) {
        char[] strArr=str.toCharArray();
        int len=strArr.length;
        if(len<=0)
            return str;
        n=n%len;
        reverseStr(strArr,0,n-1);
        reverseStr(strArr,n,len-1);
        reverseStr(strArr,0,len-1);
        return new String(strArr);
    }
    public void reverseStr(char[] array,int begin,int end){  //反轉字符串,前後指針
        for(;begin<end;begin++,end--){
            char c=array[begin];
            array[begin]=array[end];
            array[end]=c;
        }
    }

【劍指Offer】43、左旋轉字符串