LeetCode C++ 316. Remove Duplicate Letters【Stack/Greedy/String】中等
Given a string s
, remove duplicate letters so that every letter appears once and only once. You must make sure your result is the smallest in lexicographical order among all possible results.
Example 1:
Input: s = "bcabc"
Output: "abc"
Example 2:
Input: s = "cbacdcbc"
Output: "acdb"
Constraints:
1 <= s.length <= 10^4
s
consists of lowercase English letters.
題意:給出一個字串 s
,去除字串中重複的字母,使得每個字母只出現一次。需保證 返回結果的字典序最小(要求不能打亂其他字元的相對位置)。
解法 貪心+棧
本題的做法有一點麻煩,因為題目要我們完成的任務比較多:
- 去重:保留每種字元各一個;
- 最小字典序:這些字元構成的字串其字典序最小;
- 保持順序:保留的字元之間的順序不變。
因此不是一個單調棧就能夠解決的事,儘管和單調棧的思路有一點相似——單調上升的字元序列,其字典序最小。在程式中,我們將要維護的這個棧不完全是單調的,比如說 "bac"
,當我們遍歷到下標 2
時,棧中含有 ba
,這不是單調上升的。
最終的做法是:遇到一個已經出現的字元,就跳過;遇到一個新字元,如果小於棧頂元素,並且在字串(新字元的)後面還有同樣的棧頂字元,就不斷彈出棧頂字元,之後入棧新字元。比如 ""bcabc"
,遍歷到下標 2
時,就要彈出前面的 b, c
字元,然後入棧 a
字元。
實際程式碼如下:
class Solution {
public:
string removeDuplicateLetters(string s) {
vector<char> st;
int n = s.size();
bool vis[26] = {false};
for (int i = 0; i < n; ++i) {
if (vis[s[i] - 'a']) continue; //棧中已經含有這一字元
//遇到一個新字元,如果小於棧頂,並且新字元後面還有和棧頂一樣的,就彈出棧頂字元
while (!st.empty() && st.back() > s[i] && s.find(st.back(), i) != string::npos) {
vis[st.back() - 'a'] = false;
st.pop_back();
}
vis[s[i] - 'a'] = true;
st.push_back(s[i]);
}
string ans;
for (const char &c : st) ans += c;
return ans;
}
};
提交後的結果如下:
執行用時:4 ms, 在所有 C++ 提交中擊敗了74.17% 的使用者
記憶體消耗:6.5 MB, 在所有 C++ 提交中擊敗了96.64% 的使用者
相關文章
- LeetCode-Remove Duplicate LettersLeetCodeREM
- [LintCode/LeetCode] Remove Duplicate LettersLeetCodeREM
- Remove Duplicate Letters 刪除重複元素REM
- LeetCode C++ 50. Pow(x, n)【Recursion】中等LeetCodeC++
- LeetCode C++ 56. Merge Intervals【排序/陣列】中等LeetCodeC++排序陣列
- LeetCode C++ 33. Search in Rotated Sorted Array【二分】中等LeetCodeC++
- leetcode Remove ElementLeetCodeREM
- js解leetcode(32)-中等JSLeetCode
- LeetCode練習-中等卷LeetCode
- LeetCode C++ 1302. Deepest Leaves Sum【Tree/BFS/DFS】中等LeetCodeC++
- LeetCode C++ 376. Wiggle Subsequence【Dynamic Programming】中等LeetCodeC++
- [Leetcode]316.去除重複字母LeetCode
- C++ STL stackC++
- LeetCode Min StackLeetCode
- LeetCode 1209. Remove All Adjacent Duplicates in String II 有坑LeetCodeREM
- [leetcode]remove-elementLeetCodeREM
- Leetcode-Remove ElementLeetCodeREM
- Remove Element leetcode javaREMLeetCodeJava
- leetcode 316.去除重複字母 JavaLeetCodeJava
- LeetCode C++ 387. First Unique Character in a String【String/Hash Table】簡單LeetCodeC++
- LeetCode C++ 劍指 Offer 64. 求1+2+…+n【Bit Manipulation】中等LeetCodeC++
- Leetcode-Min StackLeetCode
- [LeetCode] Find the Duplicate NumberLeetCode
- c++的remove函式C++REM函式
- leetcode-27. Remove ElementLeetCodeREM
- Leetcode 27 Remove-ElementLeetCodeREM
- leetcode27_Remove ElementLeetCodeREM
- [LeetCode] Remove Element 移除元素LeetCodeREM
- C++搜尋與回溯演算法之LETTERS(字母)C++演算法
- C++ STL stack容器——棧C++
- LeetCode 316. 去除重複字母 java題解LeetCodeJava
- LeetCode-Find the Duplicate NumberLeetCode
- JAVA-LeetCode中等29兩數相除JavaLeetCode
- C++ remove erase 用法淺析C++REM
- ACM Greedy MouseACM
- LeetCode-Remove Invalid ParenthesesLeetCodeREM
- Leetcode Remove Duplicates from Sorted ListLeetCodeREM
- leetcode Remove Duplicates from Sorted ArrayLeetCodeREM