LeetCode.917-只反轉字母(Reverse Only Letters)

這是悅樂書的第353次更新,第378篇原創

java

01 看題和準備

今天介紹的是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

02 第一種解法

使用雙指針基礎

定義兩個指針ij,一個從前日後,一個從後往前,只有兩個指針所在元素都是字母時才交換位置,若是其中一個不是字母,就向前前進一步繼續判斷,若是兩個指針所在元素都不是字母就同時向前移動。

此解法的時間複雜度是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);
}


03 第二種解法

在雙指針的基礎上作了下變更,使用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();
}


04 第三種解法

利用棧,藉助其先進後出的特性。

先將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();
}


05 小結

算法專題目前已連續日更超過六個月,算法題文章221+篇,公衆號對話框回覆【數據結構與算法】、【算法】、【數據結構】中的任一關鍵詞,獲取系列文章合集。

以上就是所有內容,若是你們有什麼好的解法思路、建議或者其餘問題,能夠下方留言交流,點贊、留言、轉發就是對我最大的回報和支持!

相關文章
相關標籤/搜索