สมมติว่าเรามีสตริงที่ประกอบด้วยตัวพิมพ์เล็กเท่านั้น เราต้องลบตัวอักษรที่ซ้ำกันทั้งหมดเพื่อให้ตัวอักษรทั้งหมดเกิดขึ้นเพียงครั้งเดียว และเราต้องแสดงผลในลำดับพจนานุกรมที่เล็กที่สุด ดังนั้นหากอินพุตเป็นเหมือน “abccb” ผลลัพธ์จะเป็น “abc”
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
ans :=หนึ่งสตริงว่าง
-
กำหนดหนึ่งสแต็ก st
-
กำหนดอาร์เรย์ onStack ขนาด 26
-
กำหนดหนึ่งแผนที่ m
-
n :=ขนาดของ s
-
สำหรับการเริ่มต้น i :=0 เมื่อฉัน
-
เพิ่ม m[s[i]] ขึ้น 1
-
-
สำหรับการเริ่มต้น i :=0 เมื่อฉัน
-
กำหนดอาร์เรย์ x =s ขนาด i
-
ลด m[x] โดย 1
-
ถ้า onStack[x - 'a'] ไม่ใช่ศูนย์ ดังนั้น
-
ข้ามไปยังการวนซ้ำถัดไป ละเว้นส่วนต่อไปนี้
-
-
ในขณะที่ st ไม่ว่างเปล่าและ x
-
onStack[top of st - 'a'] :=false
-
ลบรายการออกจาก st
-
-
ใส่ x ลงใน st
-
onStack[x - 'a'] :=จริง
-
-
ในขณะที่ (st ว่างเปล่า) เป็นเท็จ ทำ -
-
x :=องค์ประกอบด้านบนของ st
-
ลบรายการออกจาก st
-
ans =ans + x
-
-
ย้อนกลับรอบอาร์เรย์
-
กลับมาอีกครั้ง
ตัวอย่าง
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v){
cout << "[";
for(int i = 0; i<v.size(); i++){
cout << v[i] << ", ";
}
cout << "]"<<endl;
}
class Solution {
public:
string removeDuplicateLetters(string s) {
string ans = "";
stack <char> st;
vector <int> onStack(26);
map <char, int> m;
int n = s.size();
for(int i = 0; i < n; i++){
m[s[i]]++;
}
for(int i = 0; i < n; i++){
char x = s[i];
m[x]--;
if(onStack[x - 'a'])continue;
while(!st.empty() && x < st.top() && m[st.top()]){
onStack[st.top() - 'a'] = false;
st.pop();
}
st.push(x);
onStack[x - 'a'] = true;
}
while(!st.empty()){
char x = st.top();
st.pop();
ans += x;
}
reverse(ans.begin(), ans.end());
return ans;
}
};
main(){
Solution ob;
cout << (ob.removeDuplicateLetters("abccb"));
} อินพุต
“abccb”
ผลลัพธ์
“abc”