Mutating counts without cleanup
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.
Move from brute-force thinking to an efficient approach using hash map strategy.
You are given a string s.
We define the mirror of a letter in the English alphabet as its corresponding letter when the alphabet is reversed. For example, the mirror of 'a' is 'z', and the mirror of 'y' is 'b'.
Initially, all characters in the string s are unmarked.
You start with a score of 0, and you perform the following process on the string s:
i, find the closest unmarked index j such that j < i and s[j] is the mirror of s[i]. Then, mark both indices i and j, and add the value i - j to the total score.j exists for the index i, move on to the next index without making any changes.Return the total score at the end of the process.
Example 1:
Input: s = "aczzx"
Output: 5
Explanation:
i = 0. There is no index j that satisfies the conditions, so we skip.i = 1. There is no index j that satisfies the conditions, so we skip.i = 2. The closest index j that satisfies the conditions is j = 0, so we mark both indices 0 and 2, and then add 2 - 0 = 2 to the score.i = 3. There is no index j that satisfies the conditions, so we skip.i = 4. The closest index j that satisfies the conditions is j = 1, so we mark both indices 1 and 4, and then add 4 - 1 = 3 to the score.Example 2:
Input: s = "abcdef"
Output: 0
Explanation:
For each index i, there is no index j that satisfies the conditions.
Constraints:
1 <= s.length <= 105s consists only of lowercase English letters.Problem summary: You are given a string s. We define the mirror of a letter in the English alphabet as its corresponding letter when the alphabet is reversed. For example, the mirror of 'a' is 'z', and the mirror of 'y' is 'b'. Initially, all characters in the string s are unmarked. You start with a score of 0, and you perform the following process on the string s: Iterate through the string from left to right. At each index i, find the closest unmarked index j such that j < i and s[j] is the mirror of s[i]. Then, mark both indices i and j, and add the value i - j to the total score. If no such index j exists for the index i, move on to the next index without making any changes. Return the total score at the end of the process.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Hash Map · Stack
"aczzx"
"abcdef"
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3412: Find Mirror Score of a String
class Solution {
public long calculateScore(String s) {
Map<Character, List<Integer>> d = new HashMap<>(26);
int n = s.length();
long ans = 0;
for (int i = 0; i < n; ++i) {
char x = s.charAt(i);
char y = (char) ('a' + 'z' - x);
if (d.containsKey(y)) {
var ls = d.get(y);
int j = ls.remove(ls.size() - 1);
if (ls.isEmpty()) {
d.remove(y);
}
ans += i - j;
} else {
d.computeIfAbsent(x, k -> new ArrayList<>()).add(i);
}
}
return ans;
}
}
// Accepted solution for LeetCode #3412: Find Mirror Score of a String
func calculateScore(s string) (ans int64) {
d := make(map[rune][]int)
for i, x := range s {
y := 'a' + 'z' - x
if ls, ok := d[y]; ok {
j := ls[len(ls)-1]
d[y] = ls[:len(ls)-1]
if len(d[y]) == 0 {
delete(d, y)
}
ans += int64(i - j)
} else {
d[x] = append(d[x], i)
}
}
return
}
# Accepted solution for LeetCode #3412: Find Mirror Score of a String
class Solution:
def calculateScore(self, s: str) -> int:
d = defaultdict(list)
ans = 0
for i, x in enumerate(s):
y = chr(ord("a") + ord("z") - ord(x))
if d[y]:
j = d[y].pop()
ans += i - j
else:
d[x].append(i)
return ans
// Accepted solution for LeetCode #3412: Find Mirror Score of a String
// Rust example auto-generated from java reference.
// Replace the signature and local types with the exact LeetCode harness for this problem.
impl Solution {
pub fn rust_example() {
// Port the logic from the reference block below.
}
}
// Reference (java):
// // Accepted solution for LeetCode #3412: Find Mirror Score of a String
// class Solution {
// public long calculateScore(String s) {
// Map<Character, List<Integer>> d = new HashMap<>(26);
// int n = s.length();
// long ans = 0;
// for (int i = 0; i < n; ++i) {
// char x = s.charAt(i);
// char y = (char) ('a' + 'z' - x);
// if (d.containsKey(y)) {
// var ls = d.get(y);
// int j = ls.remove(ls.size() - 1);
// if (ls.isEmpty()) {
// d.remove(y);
// }
// ans += i - j;
// } else {
// d.computeIfAbsent(x, k -> new ArrayList<>()).add(i);
// }
// }
// return ans;
// }
// }
// Accepted solution for LeetCode #3412: Find Mirror Score of a String
function calculateScore(s: string): number {
const d: Map<string, number[]> = new Map();
const n = s.length;
let ans = 0;
for (let i = 0; i < n; i++) {
const x = s[i];
const y = String.fromCharCode('a'.charCodeAt(0) + 'z'.charCodeAt(0) - x.charCodeAt(0));
if (d.has(y)) {
const ls = d.get(y)!;
const j = ls.pop()!;
if (ls.length === 0) {
d.delete(y);
}
ans += i - j;
} else {
if (!d.has(x)) {
d.set(x, []);
}
d.get(x)!.push(i);
}
}
return ans;
}
Use this to step through a reusable interview workflow for this problem.
For each element, scan left (or right) to find the next greater/smaller element. The inner scan can visit up to n elements per outer iteration, giving O(n²) total comparisons. No extra space needed beyond loop variables.
Each element is pushed onto the stack at most once and popped at most once, giving 2n total operations = O(n). The stack itself holds at most n elements in the worst case. The key insight: amortized O(1) per element despite the inner while-loop.
Review these before coding to avoid predictable interview regressions.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.
Wrong move: Pushing without popping stale elements invalidates next-greater/next-smaller logic.
Usually fails on: Indices point to blocked elements and outputs shift.
Fix: Pop while invariant is violated before pushing current element.