1. 程式人生 > 其它 >LeetCode-316-mid-去除重複數字(單調棧)

LeetCode-316-mid-去除重複數字(單調棧)

技術標籤:algorithmleetcode資料結構演算法leetcode

關鍵字:“單調棧”

文章目錄

題目描述

給你一個字串 s ,請你去除字串中重複的字母,使得每個字母只出現一次。需保證 返回結果的字典序最小(要求不能打亂其他字元的相對位置)

LeetCode-316-mid-去除重複字母

分析

題目要求:

  1. 去重且每個字母出現一次:則返回結果的長度固定
  2. 返回結果的排列保持原有相對位置
  3. 返回結果的字典序最小

設s中每個字母出現次數為 [ c a , c b , . . . , c z ] [c_a, c_b,..., c_z]

[ca,cb,...,cz],則滿足條件1和2的排列順序總共有: c a × c b × . . . × c z c_a\times c_b \times ... \times c_z ca×cb×...×cz 種,由於輸入規模較大,暴力列舉的方法不可行。

解題思路

條件2和儘量字典序的條件3:-> 單調棧(有相對位置+一定順序)

目前還沒有理清之間的關係。單調棧的性質和與這道題的聯絡。

目標是條件3:儘量把字典序小的字元(‘a’,‘b’,‘c’,…,‘z’)排在前邊。所以可以儘量按照字典序升序的單調棧來排列。如果遇到原打算刪除的字元在剩餘字串中不存在,則保留該字元。


設已有字串pre,當前字元c,剩餘字串post。

如果c沒有出現在pre中,則將c放入pre中(並將pre中最鄰近結尾且大於c的在post中仍然存在的字元刪除)// 這裡是c字元所在位置要儘可能放在滿足其字典序的位置,操作後所能形成的字典序更小。要求可刪除的字元要在post字串中出現,這樣才能在剩餘字串中將該刪除的字元附在最終形成的字串的末尾。

如果c已經出現在pre中,則檢視下一字元。(如果將pre中的c去掉,則使得字典序變大)


演算法

INPUT: s
OUTPUT: ans
INIT:
visit[26], count[26]
for c in s :
	count[c-'a'] ++
//迴圈不變數:visit, count, stack stack for c in s : // 現有stack中沒有c if visit[c] == false : while !stack.empty() && stack.top() > c && count[stack.top()-'a'] > 0 ) visit[ stack.top() ] = false stack.pop() stack.push( c ) visit[c-'a'] = true count[c-'a'] -- ans = string(stack) return ans

資料結構

記錄訪問資訊:陣列、vector

模擬單調棧:string、stack

複雜度分析

空間複雜度 O ( n ) O(n) O(n)

時間複雜度 O ( n ) O(n) O(n),不考慮stack.pop()

程式碼實現


class Solution {
public:
    string removeDuplicateLetters(string s) {

        vector<int> visit(26), count(26) ;
        for ( char c : s ){
            ++ count[c-'a'] ;
        }

        string stk = "" ;
        for ( char c : s ){
            if ( visit[c-'a'] == 0 ){
                while ( !stk.empty() && stk.back() > c && count[stk.back()-'a'] > 0 ){
                    visit[ stk.back()-'a' ] = 0 ;
                    stk.pop_back() ;
                }
                stk.push_back( c ) ;
                visit[c-'a'] = 1 ;
            }
            -- count[c-'a'] ;

        }
        return stk ;
    }
};

  • 使用vector或陣列來儲存對字元資訊的訪問,時間複雜度更低
  • 單調棧訪問中,每個元素至少入棧一次

相關問題


PS.

  1. 相比較於其他已有的leetcode刷題筆記,我希望能夠提供相關的解題分析和部分相關問題的連結,使得大家能獲得一個較好的分析與相關問題的比較。

  2. 偶爾會進行類似題目的總結工作,有需要的讀者可以對這份工作進行關注。

  3. 如果你發現有相關的錯誤或者表述不當不清晰的地方,請進行評論,我會盡快進行核對勘正。