LeetCode.1047-重復刪除字符串中的所有相鄰重復項


這是小川的第389次更新,第419篇原創

01 看題和准備

今天介紹的是LeetCode算法題中Easy級別的第251題(順位題號是1047)。給定一個小寫字母的字符串S,重復刪除兩個相鄰且相等的字母。

我們在S上反復刪除,直到我們再也無法刪除。

在完成所有此類重復刪除后返回最后一個字符串。保證答案是獨一無二的。

例如:

輸入:"abbaca"
輸出:"ca"
說明:在"abbaca"中我們可以刪除"bb",因為字母相鄰且相等,這是唯一可能的移動。這一舉動的結果是字符串是"aaca",其中只有"aa"是可能的,所以最后的字符串是"ca"。

注意

  • 1 <= S.length <= 20000

  • S僅由英文小寫字母組成。

02 第一種解法

題目的意思是依次比較S中相鄰的兩個字母,如果相同,就刪除掉,組成一個新的字符串,繼續剛才的操作,直到最后S中沒有相鄰的重復的字母。

思路:定義一個布爾類型變量flag,控制上一次遍歷S中的字母時,是否存在相鄰的重復字母。使用兩層循環,外層控制是否可以繼續刪除,內層遍歷S中相鄰的字母,如果相同就刪掉,這里采取截取字符串的方式來生成新的字符串,同時將flag改為true,以便繼續外層循環。

public String removeDuplicates(String S) {
    boolean flag = true;
    while (flag) {
        flag = false;
        int n = S.length()-1;
        for (int i=0; i<n; i++) {
            if (S.charAt(i) == S.charAt(i+1)) {
                S = S.substring(0, i)+
                        S.substring(i+2, S.length());
                flag = true;
                break;
            }
        }
    }
    return S;
}

03 第二種解法

我們還可以借助來實現,借助其后進先出的特性。

思路:遍歷S中的字母,如果當前字母和棧頂的字母相等,就將棧頂的字母移除,如果不相等,就壓入棧頂,直到遍歷完所有字母。最后將棧中的字母拼接到StringBuilder中去,轉為字符串時,要反轉,因為最先出棧的字母是S中較后面的。

public String removeDuplicates2(String S) {
    Stack<Character> stack = new Stack<Character>();
    int n = S.length();
    for (int i=0; i<n; i++) {
        if (!stack.isEmpty() && S.charAt(i) == stack.peek()) {
            stack.pop();
        } else {
            stack.push(S.charAt(i));
        }
    }
    StringBuilder sb = new StringBuilder();
    while (!stack.isEmpty()) {
        sb.append(stack.pop());
    }
    return sb.reverse().toString();
}

04 第三種解法

同樣借助棧的思路,但是我們可以不使用棧,通過StringBuilder來完成類似棧的操作。

思路:創建一個StringBuilder對象,遍歷S中的字母,如果當前字母和StringBuilder中的最后一個字母相等,就將StringBuilder中的最后一個字母刪除,否則就繼續往后拼接。

public String removeDuplicates3(String S) {
    StringBuilder sb = new StringBuilder();
    int n = S.length();
    for (int i=0; i<n; i++) {
        int size = sb.length();
        if (size > 0 && sb.charAt(size-1) == S.charAt(i)) {
            sb.deleteCharAt(size-1);
        } else {
            sb.append(S.charAt(i));
        }
    }
    return sb.toString();
}

05 第四種解法

同樣借助棧的思路,我們還可以利用char數組來實現。

思路:創建一個長度和S相等的char數組,遍歷S中的字母,如果當前字母和char數組中的最后一個字母相等,就將索引前移,下次再往char數組中添加元素時,就會根據新的索引重新賦值,起到移除重復字母的效果。

public String removeDuplicates4(String S) {
    int n = S.length(), index = 0;
    char[] arr = new char[n];
    for (int i=0; i<n; i++) {
        if (index > 0 && arr[index-1] == S.charAt(i)) {
            index--;
        } else {
            arr[index++] = S.charAt(i);
        }
    }
    return new String(arr, 0, index);
}

06 小結

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

以上就是全部內容,如果大家有什么好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支持!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM