(一)基礎:字符串反轉
題目(Easy):344. 反轉字符串
題目描述:
編寫一個函數,其作用是將輸入的字符串反轉過來。輸入字符串以字符數組 char[]
的形式給出。
不要給另外的數組分配額外的空間,你必須原地修改輸入數組、使用 O(1) 的額外空間解決這一問題。
你可以假設數組中的所有字符都是 ASCII 碼表中的可打印字符。
示例 1:
輸入:["h","e","l","l","o"]
輸出:["o","l","l","e","h"]
解題思路:
本題是字符串反轉的最基本算法,要反轉一個字符串,可以采用首尾雙指針的方式,首尾互換后移動指針即可。

代碼實現:
public void reverseString(char[] s) {
int i=0,j=s.length-1;
while(i<j){
char temp=s[i];
s[i]=s[j];
s[j]=temp;
i++;
j--;
}
}
(二)反轉字符串II
題目(Easy):541. 反轉字符串 II
題目描述:
給定一個字符串和一個整數 k,你需要對從字符串開頭算起的每個 2k 個字符的前k個字符進行反轉。如果剩余少於 k 個字符,則將剩余的所有全部反轉。如果有小於 2k 但大於或等於 k 個字符,則反轉前 k 個字符,並將剩余的字符保持原樣。
示例:
輸入: s = "abcdefg", k = 2
輸出: "bacdfeg"
解題思路:
本題比較簡單,是字符串反轉的一個直接應用,可以直接看代碼實現。
代碼實現:
class Solution {
public String reverseStr(String s, int k) {
char[] strArr=s.toCharArray();
int len=strArr.length;
for(int begin=0;begin<len;begin+=(k*2)){
int i=begin,j=Math.min(begin+k-1,len-1); //注意j的判斷
reverse(strArr,i,j);
}
return new String(strArr);
}
//字符串反轉
public void reverse(char[] s,int begin,int end){
int i=begin,j=end;
while(i<j){
char temp=s[i];
s[i]=s[j];
s[j]=temp;
i++;
j--;
}
}
}
(三)反轉字符串中的單詞 III
題目(Easy):反轉字符串中的單詞 III
題目描述:
給定一個字符串,你需要反轉字符串中每個單詞的字符順序,同時仍保留空格和單詞的初始順序。
示例 1:
輸入: "Let's take LeetCode contest"
輸出: "s'teL ekat edoCteeL tsetnoc"
注意:在字符串中,每個單詞由單個空格分隔,並且字符串中不會有任何額外的空格。
解題思路:
同樣采用兩個指針,遇到空格,則反轉對應的單詞,依次判斷即可。
代碼實現:
class Solution {
public String reverseWords(String s) {
char[] strArr = s.toCharArray();
int begin=0;
for(int i=0;i<strArr.length;i++){
if(strArr[i]==' '){
reverse(strArr,begin,i-1);
begin=i+1;
}
}
reverse(strArr,begin,strArr.length-1);
return new String(strArr);
}
public void reverse(char[] s,int begin,int end){
int i=begin,j=end;
while(i<j){
char temp=s[i];
s[i]=s[j];
s[j]=temp;
i++;
j--;
}
}
}
(四)左旋轉字符串
題目(Easy):面試題58 - II. 左旋轉字符串、【劍指Offer】43、左旋轉字符串
題目描述:
字符串的左旋轉操作是把字符串前面的若干個字符轉移到字符串的尾部。請定義一個函數實現字符串左旋轉操作的功能。比如,輸入字符串"abcdefg"和數字2,該函數將返回左旋轉兩位得到的結果"cdefgab"。
示例 1:
輸入: s = "abcdefg", k = 2
輸出: "cdefgab"
示例 2:
輸入: s = "lrloseumgh", k = 6
輸出: "umghlrlose"
解題思路:
本題也是字符串反轉的衍生題目,具體思路可以見另一篇博文:【劍指Offer】43、左旋轉字符串
代碼實現:
class Solution {
public String reverseLeftWords(String s, int n) {
if(s==null || s.length()==0)
return s;
int len=s.length();
n=n%len;
char[] strArr=s.toCharArray();
reverse(strArr,0,n-1); //三次反轉
reverse(strArr,n,len-1);
reverse(strArr,0,len-1);
return new String(strArr);
}
//字符串反轉
public void reverse(char[] strArr,int begin, int end){
int i=begin,j=end;
while(i<j){
char temp=strArr[i];
strArr[i]=strArr[j];
strArr[j]=temp;
i++;
j--;
}
}
}
(五)反轉單詞序列
題目描述:
牛客最近來了一個新員工Fish,每天早晨總是會拿着一本英文雜志,寫些句子在本子上。同事Cat對Fish寫的內容頗感興趣,有一天他向Fish借來翻看,但卻讀不懂它的意思。例如,“student. a am I”。后來才意識到,這家伙原來把句子單詞的順序翻轉了,正確的句子應該是“I am a student.”。Cat對一一的翻轉這些單詞順序可不在行,你能幫助他么?
解題思路:
本題相對比較簡單,但是在面試中經常遇到,流傳甚廣。其主要思路也簡潔明了,主要分為以下兩步:
第一步:反轉整個序列中所有的字符,這時會發現不但反轉了單詞的順序,單詞中的字母順序也被反轉,因此需要第二步的調整。
第二步:以空格為分隔,依次反轉每個單詞,即讓每個單詞會到原來的正常順序。(這也就是第三題)
代碼實現:
public class Solution {
//先翻轉整個字符串,再逐一翻轉每個單詞
public String ReverseSentence(String str) {
if(str==null)
return null;
char[] strArr=str.toCharArray();
reverseStr(strArr,0,strArr.length-1); //翻轉整個字符串
int begin=0;
for(int i=0;i<strArr.length;i++){
if(strArr[i]==' '){
reverseStr(strArr,begin,i-1);
begin=i+1;
}
}
reverseStr(strArr,begin,strArr.length-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;
}
}
}
(六)反轉字符串中的元音字母
題目(Easy):345. 反轉字符串中的元音字母
題目描述:
編寫一個函數,以字符串作為輸入,反轉該字符串中的元音字母。
元音字母:a,e,i,o,u
示例 1:
輸入: "hello"
輸出: "holle"
示例 2:
輸入: "leetcode"
輸出: "leotcede"
解題思路:
使用前后雙指針,找到元音字母,然后交換即可。
代碼實現:
class Solution {
public String reverseVowels(String s) {
if(s==null || s.length()==0)
return s;
char[] strArr=s.toCharArray();
int i=0,j=s.length()-1;
while(i<j){
while(i<s.length() && !check(strArr[i]))
i++;
while(j>=0 && !check(strArr[j]))
j--;
if(i>=j)
break;
//i和j互換
char temp=strArr[i];
strArr[i++]=strArr[j];
strArr[j--]=temp;
}
return new String(strArr);
}
public boolean check(char c){
if(c=='a' || c=='e' || c=='i'||c=='o'||c=='u'||c=='A'||c=='E'||c=='I'||c=='O'||c=='U')
return true;
return false;
}
}
(七)僅僅反轉字母
題目(Easy):917. 僅僅反轉字母
題目描述:
給定一個字符串 S
,返回 “反轉后的” 字符串,其中不是字母的字符都保留在原地,而所有字母的位置發生反轉。
示例 1:
輸入:"ab-cd"
輸出:"dc-ba"
示例 2:
輸入:"a-bC-dEf-ghIj"
輸出:"j-Ih-gfE-dCba"
解題思路:
類似於反轉字符串中的元音字母,前后雙指針交換,只是判斷條件不同。
代碼實現:
class Solution {
public String reverseOnlyLetters(String S) {
if(S==null || S.length()==0)
return S;
char[] strArr=S.toCharArray();
int i=0,j=strArr.length-1;
while(i<j){
while(i<strArr.length && !check(strArr[i]))
i++;
while(j>=0 && !check(strArr[j]))
j--;
if(i>=j)
break;
//交換
char temp=strArr[i];
strArr[i++]=strArr[j];
strArr[j--]=temp;
}
return new String(strArr);
}
public boolean check(char c){
if(c>='a' && c<='z')
return true;
if(c>='A' && c<='Z')
return true;
return false;
}
}
總結:
本文總結了關於字符串反轉的七道題目,相對來說比較簡單,但是這是字符串類題目的基礎,特別是左旋轉字符串和反轉單詞序列兩題體現了字符串反轉的妙用。