這是悅樂書的第353次更新,第378篇原創
java
今天介紹的是LeetCode
算法題中Easy
級別的第215
題(順位題號是917
)。給定一個字符串S
,返回「反向」字符串,其中全部非字母的字符都保留在同一位置,而且全部字母都反轉其位置。例如:算法
輸入:「ab-cd」
輸出:「dc-ba」數據結構
輸入:「a-bC-dEf-ghIj」
輸出:「j-Ih-gfE-dCba」app
輸入:「Test1ng-Leet = code-Q!」
輸出:「Qedo1ct-eeLg = ntse-T!」ui
注意:指針
S.length <= 100code
33 <= S[i].ASCIIcode <= 122字符串
S不包含\
或「
class
使用雙指針。基礎
定義兩個指針i
和j
,一個從前日後,一個從後往前,只有兩個指針所在元素都是字母時才交換位置,若是其中一個不是字母,就向前前進一步繼續判斷,若是兩個指針所在元素都不是字母就同時向前移動。
此解法的時間複雜度是O(N)
,空間複雜度是O(N)
。
public String reverseOnlyLetters(String S) { int i = 0, j = S.length()-1; char[] arr = S.toCharArray(); while (i < j) { char c = arr[i]; char c2 = arr[j]; if (Character.isLetter(c) && Character.isLetter(c2)) { arr[i] = c2; arr[j] = c; i++; j--; } else if (!Character.isLetter(c) && Character.isLetter(c2)) { i++; } else if (Character.isLetter(c) && !Character.isLetter(c2)) { j--; } else if (!Character.isLetter(c) && !Character.isLetter(c2)) { i++; j--; } } return new String(arr); }
在雙指針的基礎上作了下變更,使用StringBuilder
來拼接新的字符,可是雙指針的思路沒變。
此解法的時間複雜度是O(N)
,空間複雜度是O(N)
。
public String reverseOnlyLetters2(String S) { int j = S.length()-1, n = S.length(); StringBuilder sb = new StringBuilder(); for (int i=0; i<n; i++) { if (Character.isLetter(S.charAt(i))) { while (j>=0 && !Character.isLetter(S.charAt(j))) { j--; } sb.append(S.charAt(j--)); } else { sb.append(S.charAt(i)); } } return sb.toString(); }
利用棧,藉助其先進後出的特性。
先將S
中的字母所有入棧,而後再遍歷S中的字符,若是是字母,就從棧頂取一位元素出來拼接,不是字母,就直接拼接當前元素。
此解法的時間複雜度是O(N)
,空間複雜度是O(N)
。
public String reverseOnlyLetters3(String S) { Stack<Character> stack = new Stack<Character>(); char[] arr = S.toCharArray(); for (char c : arr) { if (Character.isLetter(c)) { stack.push(c); } } StringBuilder sb = new StringBuilder(); for (char c : arr) { if (Character.isLetter(c)) { sb.append(stack.pop()); } else { sb.append(c); } } return sb.toString(); }
算法專題目前已連續日更超過六個月,算法題文章221+篇,公衆號對話框回覆【數據結構與算法】、【算法】、【數據結構】中的任一關鍵詞,獲取系列文章合集。
以上就是所有內容,若是你們有什麼好的解法思路、建議或者其餘問題,能夠下方留言交流,點贊、留言、轉發就是對我最大的回報和支持!