###### tags: `LeetCode` `Duplicate` # 0316. Remove Duplicate Letters (Medium) 耗時:>60 分鐘 (看別人解答) ## 題目 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. ## 思路 1. 一開始考慮以循序判斷的方式解析字串,或是以substring的方式divide and conquer,但始終有考慮上的死角,雖然有想到unique(僅有一個的字母,不能被刪除),但沒有成功解題。 2. 別人解答的思路總結:在unique前的最小字母就是該子字串的解! 以pos為當前字母,循序找出較小的字母,並重新以他為字串起始點 若找到unique,則遞迴判斷子字串 舉例來說:cbacdacbc, d為unique,因此我們可以分解為S1:(~~cb~~a),S2:(cdacbc),S1中的a為最小字母,且於unique前,則a為S1的唯一解(**不會有比a小的字母無法被刪除**) * Time Complexity:O(n) * Space Complexity:O(n^2) * Worst Case:全部字母皆為unique, space= n + (n-1) + (n-2) + ... + 1 = O(n^2) ### 程式碼 參考別人的解答: ``` class Solution { public: string removeDuplicateLetters(string s) { int cnt[26] = {0}; int pos = 0; for (int i = 0; i < s.length(); ++i) cnt[s[i] - 'a']++; for (int i = 0; i < s.length(); ++i) { // find smaller head if (s[i] < s[pos]) pos = i; // find unique number if (--cnt[s[i] - 'a'] == 0) break; } if (s.length() - pos > 0) { string sub = s.substr(pos+1); string sub_2 = ""; for (int i = 0; i < sub.length(); ++i) if (sub[i] == s[pos]) sub[i] = '_'; else sub_2.push_back(sub[i]); return s[pos] + removeDuplicateLetters(sub_2); } else return ""; } }; ```