316 去除重複字母

2022-05-08 22:24:13 字數 1438 閱讀 6655

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

示例 1:

輸入: 「bcabc」

輸出: 「abc」

示例 2:

輸入: 「cbacdcbc」

輸出: 「acdb」

自己不會,看的別人思路,構造乙個棧,遍歷字串,開乙個陣列做字典記錄當前已有的字母。首先若當前字母已記錄則continue。若當前字母大於棧頂字母則放入,否則若在當前字母後面的子串中還有棧頂字母的話則pop,這裡就是貪心。因為假如當前棧裡是d,f,g,當前字母為a,即字串中第乙個a就是當前這個a,故目前的最優解就是包含這個a(因為題目要求所有存在的字母必須出現一次)。而題目又要求字典序最小,想象乙個單詞中有字母a,顯然這個a越靠前越好,abcd和bacd、bcad、bcda顯然abcd字典序最小是吧。所以我們就盡量把a往棧底移動,但要滿足pop掉的棧頂字母在後面還存在副本,不然不滿足題目的所有字母出現一次的要求了。另外這裡有些同學可能會考慮之前棧是bcd,當前字母是a,a後面的子串比如是dcb,即當前棧的字典序(bcd)比當前字母後面的子串對應的序列(dcb)小的情況。但事實是能pop掉的棧頂,元素都比當前元素小,故最終字典序是一定更小的(即一定是更優解)。模擬1、2、3三個數字怎麼排列最大,顯然213<312。雖然12比21小,但只要我把3移到最前面,整個數字還是更大,不知道這麼說能不能說明白。

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

//19/10/4

class

solution

;for

(int i =

0; i < s.

size()

;++i)

int visited[26]

=;for(

int i=

0;isize()

;++i)

if(sta.

empty()

or c>sta.

top())

else

sta.

push

(c);

} visited[c -

'a']=1

;}string res ="";

while

(!sta.

empty()

)reverse

(res.

begin()

, res.

end())

;return res;}}

;int

main()

316 去除重複字母

給定乙個僅包含小寫字母的字串,去除字串中重複的字母,使得每個字母只出現一次。需保證返回結果的字典序最小 要求不能打亂其他字元的相對位置 示例 1 輸入 bcabc 輸出 abc 示例 2 輸入 cbacdcbc 輸出 acdb 我的 超時 class solution string removedu...

316 去除重複字母

給定乙個僅包含小寫字母的字串,去除字串中重複的字母,使得每個字母只出現一次。需保證返回結果的字典序最小 要求不能打亂其他字元的相對位置 示例 1 輸入 bcabc 輸出 abc 示例 2 輸入 cbacdcbc 輸出 acdb 分析 這道題就是,第一去重複,第二就是選擇最小的字串。去重複倒是不難,主...

316 去除重複字母

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