Leetcode 316 去除重複字母

2022-07-30 12:18:14 字數 1935 閱讀 3871

題目

貪心方法

用乙個兩個陣列vectorcnt,vectorin_right_place;

string res:目前符合條件的字串,到**結束的時候,這個res才是正確的答案

cnt陣列用於記錄每個char未來會出現的次數,in_right_place陣列判斷這個char是否已經在正確的位置上

什麼叫做未來會出現呢?

我們拿樣例做為例子:

輸入: "bcabc"

我們先遍歷一遍所有字串記錄cnt

結果是cnt['a']=1,cnt['b']=2,cnt['c']=2,其他都為0

我們需要再遍歷一遍尋找結果

現在讀到第乙個字元b,未來會出現的'b'的次數就減去1(因為已經出現了一次了),所以未來b只會再出現(2-1)次,這就是未來出現的次數

in_right_place判斷正確位置比較好理解,我們每次讀到乙個未在正確位置上的字元,就可以將這個字元拿來和res比較字典序,

如果能發現存在乙個新字串使得字典序更小,則代替

如何判斷字典序更小呢?

通過這個:

while(cnt[res.back()]>0&&讀取的當前字元

/*就能說明存在乙個新序列使得字典序更小*/

in_right_place[res.back()]=false;

res.pop_back();

/*撤銷正確位置的標記並將其從結果字串彈出*/

}

還是回到樣例,假設當前讀取的字元為s[2],即'a',此時的res="bc"

=>『a』比'c'字典序優先且'c'未來還會出現(即cnt['c']>0),說明存在'a'在'c'前面的搭配,所以彈出'c'並撤銷'c'是正確位置的標記即in_right_place['c']=false;此時res="b"

=>『a』比'b'字典序優先且'b'未來還會出現(即cnt['b']>0),說明存在'a'在'b'前面的搭配,所以彈出'b'並撤銷'b'是正確位置的標記即in_right_place['b']=false;此時res=""

這一題的貪心在於,每次遍歷會考慮後面的情況將res改變。具體實現**如下:

c++實現**如下:

class

solution

string res=""

;

/*返回的字串初始化為空

*/for(char

c:s)

else

res+=c;

in_right_place[c]=true

;

/*此時c在「當前的」正確位置*/}

}return

res;

}};

也可以不用vector而用陣列記錄

class

solution , visited[256] = ;

string res = ""

;

for (auto a : s) m[a]++;

for(auto a : s)

res +=a;

visited[a] = 1

; }

return

res;

}};

leetcode316 去除重複字母

給你乙個字串 s 請你去除字串中重複的字母,使得每個字母只出現一次。需保證 返回結果的字典序最小 要求不能打亂其他字元的相對位置 首先記錄每個元素出現的最後位置。然後建立乙個棧和乙個集合。若當前字元已經在集合 現過了,則跳過該字元 反之,如果棧頂元素大於當前字元,且棧頂元素的最後出現位置在當前位置之...

leetCode 316 去除重複字母

給你乙個字串 s 請你去除字串中重複的字母,使得每個字母只出現一次。需保證 返回結果的字典序最小 要求不能打亂其他字元的相對位置 注意 該題與 1081 相同 示例 1 輸入 s bcabc 輸出 abc 示例 2 輸入 s cbacdcbc 輸出 acdb 先要明白如果在乙個字串中刪去乙個字元需要...

Leetcode 316 去除重複字母

很典型的一道單調棧題目class solution char stack newchar 26 棧頂指標 int top 1 for int i 0 i n i 退棧 如果棧非空 並且 棧的頭元素大於目前元素 並且 棧的頭元素剩餘個數不為0 進行退棧操作 while top 0 stack top ...