Make The String Great
Problem
Given a string s, repeatedly remove any pair of adjacent characters where one is the lowercase form and the other is the uppercase form of the same letter, until no such pair remains. Return the resulting string.
s = "leEeetcode""leetcode"def make_good(s):
st = []
for c in s:
if st and abs(ord(st[-1]) - ord(c)) == 32:
st.pop()
else:
st.append(c)
return ''.join(st)
function makeGood(s) {
const st = [];
for (const c of s) {
if (st.length && Math.abs(st[st.length - 1].charCodeAt(0) - c.charCodeAt(0)) === 32) {
st.pop();
} else st.push(c);
}
return st.join('');
}
class Solution {
public String makeGood(String s) {
StringBuilder st = new StringBuilder();
for (char c : s.toCharArray()) {
int n = st.length();
if (n > 0 && Math.abs(st.charAt(n - 1) - c) == 32) st.deleteCharAt(n - 1);
else st.append(c);
}
return st.toString();
}
}
string makeGood(string s) {
string st;
for (char c : s) {
if (!st.empty() && abs(st.back() - c) == 32) st.pop_back();
else st.push_back(c);
}
return st;
}
Explanation
We must repeatedly delete adjacent "bad" pairs — the same letter in opposite case, like aA or Ee. A stack handles all the cascading removals in a single pass, because removing a pair can expose a new pair right underneath.
We push characters one at a time. Before pushing the current character c, we check the top of the stack. If the top and c are a case pair, we pop the top instead of pushing — they cancel out. Otherwise we push c.
The case-pair test uses ASCII: a lowercase letter and its uppercase form differ by exactly 32, so abs(top - c) == 32 means they are the same letter in different case.
Example: "leEeetcode". We push l, e; then E arrives and cancels the e on top; the next e arrives with l on top (no match) so it is pushed, and the rest pushes cleanly — leaving "leetcode".
Each character is pushed or popped once, so the whole reduction is linear, and the leftover stack joined together is the answer.