From 4cf62a9abdb1ae67b9a83b97d3922a4a7b1c4d9e Mon Sep 17 00:00:00 2001 From: RajSpeed <116724067+RajSpeed@users.noreply.github.com> Date: Wed, 26 Oct 2022 22:13:41 +0530 Subject: [PATCH 1/2] Create 316_Remove_Duplicate_Letters.cpp --- C++/316_Remove_Duplicate_Letters.cpp | 50 ++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 C++/316_Remove_Duplicate_Letters.cpp diff --git a/C++/316_Remove_Duplicate_Letters.cpp b/C++/316_Remove_Duplicate_Letters.cpp new file mode 100644 index 0000000..5466c57 --- /dev/null +++ b/C++/316_Remove_Duplicate_Letters.cpp @@ -0,0 +1,50 @@ +// Name: Rajesh Sharma +// Date: 26/10/2022 + +/* +Given a string s, return the lexicographically smallest subsequence of s that contains all the distinct characters of s exactly once. +*/ + +// This question is the same as 1081: https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/ +// That is language variation. + +/* +Approach: As the question suggests, We can greedily pick the characters which affect the answer +and can be picked in future where they may be coming after lower lexicographical characters. + +Time Complexity: O(n) +Space Complexity: O(n) +*/ + +class Solution { + public: + string smallestSubsequence(string s) { + vector < bool > vis(26, false); // visited array to mark if char already added to answer + vector < int > lastOccurance(26, 1e5); // last occurance of each character is stored in this, useful to check if we can ignore this char now and pick it later + for (int i = 0; i < s.length(); i++) lastOccurance[s[i] - 'a'] = i; + stack < char > st; // stack to access previous character + for (int i = 0; i < s.length(); i++) { + char c = s[i]; + if (vis[c - 'a']) continue; + if (st.size() == 0) { // stack size is zero + st.push(c); + vis[c - 'a'] = true; + continue; + } + + while (st.size() && st.top() > c && lastOccurance[st.top() - 'a'] > i) { // while our previous character is > us and can be ignored right now, we pop it from the stack + vis[st.top() - 'a'] = false; + st.pop(); + } + st.push(c); + vis[c - 'a'] = true; + } + string ans = ""; + while (st.size()) { //fill stack chars in the answer string, note they will have to be reversed. + ans.push_back(st.top()); + st.pop(); + } + reverse(ans.begin(), ans.end()); // reversing + return ans; + } +}; From 5ebcc77283f13d3f000c24d5553032a56f287904 Mon Sep 17 00:00:00 2001 From: RajSpeed <116724067+RajSpeed@users.noreply.github.com> Date: Wed, 26 Oct 2022 22:17:55 +0530 Subject: [PATCH 2/2] Update 316_Remove_Duplicate_Letters.cpp --- C++/316_Remove_Duplicate_Letters.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/C++/316_Remove_Duplicate_Letters.cpp b/C++/316_Remove_Duplicate_Letters.cpp index 5466c57..b433b15 100644 --- a/C++/316_Remove_Duplicate_Letters.cpp +++ b/C++/316_Remove_Duplicate_Letters.cpp @@ -2,7 +2,8 @@ // Date: 26/10/2022 /* -Given a string s, return the lexicographically smallest subsequence of s that contains all the distinct characters of s exactly once. +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 */ // This question is the same as 1081: https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/