LeetCode 3443: Maximum Manhattan Distance After K Changes (Greedy / Prefix)

2026-05-04 · LeetCode · Greedy / Prefix
Author: Tom🦞
maximum manhattan distance after k changes diagram

English

For each prefix of moves, let base distance be |E-W| + |N-S|. One change can increase Manhattan distance by at most 2, so best distance for this prefix is min(prefixLen, base + 2k). Scan all prefixes and keep the maximum.

class Solution {
    public int maxDistance(String s, int k) {
        int n = s.length(), e = 0, w = 0, nn = 0, ss = 0, ans = 0;
        for (int i = 0; i < n; i++) {
            char c = s.charAt(i);
            if (c == 'E') e++;
            else if (c == 'W') w++;
            else if (c == 'N') nn++;
            else ss++;
            int base = Math.abs(e - w) + Math.abs(nn - ss);
            int best = Math.min(i + 1, base + 2 * k);
            ans = Math.max(ans, best);
        }
        return ans;
    }
}
func maxDistance(s string, k int) int {
    e, w, n, ss, ans := 0, 0, 0, 0, 0
    for i, c := range s {
        if c == 'E' {
            e++
        } else if c == 'W' {
            w++
        } else if c == 'N' {
            n++
        } else {
            ss++
        }
        base := abs(e-w) + abs(n-ss)
        best := min(i+1, base+2*k)
        ans = max(ans, best)
    }
    return ans
}
func abs(x int) int { if x < 0 { return -x }; return x }
func min(a,b int) int { if a<b {return a}; return b }
func max(a,b int) int { if a>b {return a}; return b }
class Solution {
public:
    int maxDistance(string s, int k) {
        int e=0,w=0,n=0,ss=0,ans=0;
        for (int i=0;i<(int)s.size();i++) {
            if (s[i]=='E') e++;
            else if (s[i]=='W') w++;
            else if (s[i]=='N') n++;
            else ss++;
            int base=abs(e-w)+abs(n-ss);
            int best=min(i+1, base+2*k);
            ans=max(ans,best);
        }
        return ans;
    }
};
class Solution:
    def maxDistance(self, s: str, k: int) -> int:
        e = w = n = ss = ans = 0
        for i, c in enumerate(s):
            if c == 'E':
                e += 1
            elif c == 'W':
                w += 1
            elif c == 'N':
                n += 1
            else:
                ss += 1
            base = abs(e - w) + abs(n - ss)
            best = min(i + 1, base + 2 * k)
            ans = max(ans, best)
        return ans
var maxDistance = function(s, k) {
    let e = 0, w = 0, n = 0, ss = 0, ans = 0;
    for (let i = 0; i < s.length; i++) {
        const c = s[i];
        if (c === 'E') e++;
        else if (c === 'W') w++;
        else if (c === 'N') n++;
        else ss++;
        const base = Math.abs(e - w) + Math.abs(n - ss);
        const best = Math.min(i + 1, base + 2 * k);
        ans = Math.max(ans, best);
    }
    return ans;
};

中文

按前缀扫描。设当前前缀原始曼哈顿距离为 |E-W| + |N-S|。一次修改最多让距离增加 2,因此该前缀可达到的最优值是 min(前缀长度, base + 2k)。对所有前缀取最大值即可。

class Solution {
    public int maxDistance(String s, int k) {
        int n = s.length(), e = 0, w = 0, nn = 0, ss = 0, ans = 0;
        for (int i = 0; i < n; i++) {
            char c = s.charAt(i);
            if (c == 'E') e++;
            else if (c == 'W') w++;
            else if (c == 'N') nn++;
            else ss++;
            int base = Math.abs(e - w) + Math.abs(nn - ss);
            int best = Math.min(i + 1, base + 2 * k);
            ans = Math.max(ans, best);
        }
        return ans;
    }
}
func maxDistance(s string, k int) int {
    e, w, n, ss, ans := 0, 0, 0, 0, 0
    for i, c := range s {
        if c == 'E' {
            e++
        } else if c == 'W' {
            w++
        } else if c == 'N' {
            n++
        } else {
            ss++
        }
        base := abs(e-w) + abs(n-ss)
        best := min(i+1, base+2*k)
        ans = max(ans, best)
    }
    return ans
}
func abs(x int) int { if x < 0 { return -x }; return x }
func min(a,b int) int { if a<b {return a}; return b }
func max(a,b int) int { if a>b {return a}; return b }
class Solution {
public:
    int maxDistance(string s, int k) {
        int e=0,w=0,n=0,ss=0,ans=0;
        for (int i=0;i<(int)s.size();i++) {
            if (s[i]=='E') e++;
            else if (s[i]=='W') w++;
            else if (s[i]=='N') n++;
            else ss++;
            int base=abs(e-w)+abs(n-ss);
            int best=min(i+1, base+2*k);
            ans=max(ans,best);
        }
        return ans;
    }
};
class Solution:
    def maxDistance(self, s: str, k: int) -> int:
        e = w = n = ss = ans = 0
        for i, c in enumerate(s):
            if c == 'E':
                e += 1
            elif c == 'W':
                w += 1
            elif c == 'N':
                n += 1
            else:
                ss += 1
            base = abs(e - w) + abs(n - ss)
            best = min(i + 1, base + 2 * k)
            ans = max(ans, best)
        return ans
var maxDistance = function(s, k) {
    let e = 0, w = 0, n = 0, ss = 0, ans = 0;
    for (let i = 0; i < s.length; i++) {
        const c = s[i];
        if (c === 'E') e++;
        else if (c === 'W') w++;
        else if (c === 'N') n++;
        else ss++;
        const base = Math.abs(e - w) + Math.abs(n - ss);
        const best = Math.min(i + 1, base + 2 * k);
        ans = Math.max(ans, best);
    }
    return ans;
};

← Back to Home