Topics
User sends messages one after the other to other users. Output the recipients in the order of chats with them, from latest to oldest.
Input:
4
alex
ivan
roman
ivan
Output:
ivan
roman
alex
Explanation: In the first test case user first writes to friend by name “alex”, and the list looks as follows: [alex]
Then user writes to friend by name “ivan” and the list looks as follows: [ivan, alex]
. User writes the third message to friend by name “roman” and the list looks as follows: [roman, ivan, alex]
. Finally, user writes the fourth message to “ivan” again, so the order of chats changes as follows: [ivan, roman, alex]
Idea
The problem asks for the order of chats from latest to oldest, eliminating duplicate entries for the same recipient. We can iterate through the input messages (stored in vector/stack) in reverse. Using an unordered_set
called seen
, we track the names already encountered. If a name hasn’t been seen before, we output it and add it to the seen
set. This ensures that only the most recent chat with each user is printed, effectively giving us the desired chat order.
Time Complexity:
Space Complexity:
Code
// Approach 1 (Using stack)
void solve() {
int n;
cin >> n;
stack<string> st;
unordered_set<string> seen;
string s;
while (n--) {
cin >> s;
st.push(s);
}
while (!st.empty()) {
if (seen.count(st.top()) == 0) {
cout << st.top() << '\n';
seen.insert(st.top());
}
st.pop();
}
}
// Approach 2 (Using vector)
void solve() {
int n;
cin >> n;
vector<string> messages(n);
for (string &s : messages) {
cin >> s;
}
unordered_set<string> seen;
for (int i = n - 1; i >= 0; --i) {
// If insertion succeeds, it's a new name
if (seen.insert(messages[i]).second) {
cout << messages[i] << endl;
}
}
}