【劍指Offer】43、左旋轉字符串
阿新 • • 發佈:2019-05-12
實現 不難 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、左旋轉字符串