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 consisting of the characters 'N', 'S', 'E', and 'W', where s[i] indicates movements in an infinite grid:
'N' : Move north by 1 unit.'S' : Move south by 1 unit.'E' : Move east by 1 unit.'W' : Move west by 1 unit.Initially, you are at the origin (0, 0). You can change at most k characters to any of the four directions.
Find the maximum Manhattan distance from the origin that can be achieved at any time while performing the movements in order.
The Manhattan Distance between two cells(xi, yi) and (xj, yj) is |xi - xj| + |yi - yj|.
Example 1:
Input: s = "NWSE", k = 1
Output: 3
Explanation:
Change s[2] from 'S' to 'N'. The string s becomes "NWNE".
| Movement | Position (x, y) | Manhattan Distance | Maximum |
|---|---|---|---|
| s[0] == 'N' | (0, 1) | 0 + 1 = 1 | 1 |
| s[1] == 'W' | (-1, 1) | 1 + 1 = 2 | 2 |
| s[2] == 'N' | (-1, 2) | 1 + 2 = 3 | 3 |
| s[3] == 'E' | (0, 2) | 0 + 2 = 2 | 3 |
The maximum Manhattan distance from the origin that can be achieved is 3. Hence, 3 is the output.
Example 2:
Input: s = "NSWWEW", k = 3
Output: 6
Explanation:
Change s[1] from 'S' to 'N', and s[4] from 'E' to 'W'. The string s becomes "NNWWWW".
The maximum Manhattan distance from the origin that can be achieved is 6. Hence, 6 is the output.
Constraints:
1 <= s.length <= 1050 <= k <= s.lengths consists of only 'N', 'S', 'E', and 'W'.Problem summary: You are given a string s consisting of the characters 'N', 'S', 'E', and 'W', where s[i] indicates movements in an infinite grid: 'N' : Move north by 1 unit. 'S' : Move south by 1 unit. 'E' : Move east by 1 unit. 'W' : Move west by 1 unit. Initially, you are at the origin (0, 0). You can change at most k characters to any of the four directions. Find the maximum Manhattan distance from the origin that can be achieved at any time while performing the movements in order. The Manhattan Distance between two cells (xi, yi) and (xj, yj) is |xi - xj| + |yi - yj|.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Hash Map · Math
"NWSE" 1
"NSWWEW" 3
as-far-from-land-as-possible)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3443: Maximum Manhattan Distance After K Changes
class Solution {
private char[] s;
private int k;
public int maxDistance(String s, int k) {
this.s = s.toCharArray();
this.k = k;
int a = calc('S', 'E');
int b = calc('S', 'W');
int c = calc('N', 'E');
int d = calc('N', 'W');
return Math.max(Math.max(a, b), Math.max(c, d));
}
private int calc(char a, char b) {
int ans = 0, mx = 0, cnt = 0;
for (char c : s) {
if (c == a || c == b) {
++mx;
} else if (cnt < k) {
++mx;
++cnt;
} else {
--mx;
}
ans = Math.max(ans, mx);
}
return ans;
}
}
// Accepted solution for LeetCode #3443: Maximum Manhattan Distance After K Changes
func maxDistance(s string, k int) int {
calc := func(a rune, b rune) int {
var ans, mx, cnt int
for _, c := range s {
if c == a || c == b {
mx++
} else if cnt < k {
mx++
cnt++
} else {
mx--
}
ans = max(ans, mx)
}
return ans
}
a := calc('S', 'E')
b := calc('S', 'W')
c := calc('N', 'E')
d := calc('N', 'W')
return max(a, b, c, d)
}
# Accepted solution for LeetCode #3443: Maximum Manhattan Distance After K Changes
class Solution:
def maxDistance(self, s: str, k: int) -> int:
def calc(a: str, b: str) -> int:
ans = mx = cnt = 0
for c in s:
if c == a or c == b:
mx += 1
elif cnt < k:
cnt += 1
mx += 1
else:
mx -= 1
ans = max(ans, mx)
return ans
a = calc("S", "E")
b = calc("S", "W")
c = calc("N", "E")
d = calc("N", "W")
return max(a, b, c, d)
// Accepted solution for LeetCode #3443: Maximum Manhattan Distance After K Changes
impl Solution {
pub fn max_distance(s: String, k: i32) -> i32 {
fn calc(s: &str, a: char, b: char, k: i32) -> i32 {
let mut ans = 0;
let mut mx = 0;
let mut cnt = 0;
for c in s.chars() {
if c == a || c == b {
mx += 1;
} else if cnt < k {
mx += 1;
cnt += 1;
} else {
mx -= 1;
}
ans = ans.max(mx);
}
ans
}
let a = calc(&s, 'S', 'E', k);
let b = calc(&s, 'S', 'W', k);
let c = calc(&s, 'N', 'E', k);
let d = calc(&s, 'N', 'W', k);
a.max(b).max(c).max(d)
}
}
// Accepted solution for LeetCode #3443: Maximum Manhattan Distance After K Changes
function maxDistance(s: string, k: number): number {
const calc = (a: string, b: string): number => {
let [ans, mx, cnt] = [0, 0, 0];
for (const c of s) {
if (c === a || c === b) {
++mx;
} else if (cnt < k) {
++mx;
++cnt;
} else {
--mx;
}
ans = Math.max(ans, mx);
}
return ans;
};
const a = calc('S', 'E');
const b = calc('S', 'W');
const c = calc('N', 'E');
const d = calc('N', 'W');
return Math.max(a, b, c, d);
}
Use this to step through a reusable interview workflow for this problem.
For each element, scan the rest of the array looking for a match. Two nested loops give n × (n−1)/2 comparisons = O(n²). No extra space since we only use loop indices.
One pass through the input, performing O(1) hash map lookups and insertions at each step. The hash map may store up to n entries in the worst case. This is the classic space-for-time tradeoff: O(n) extra memory eliminates an inner 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: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.