2025-08-12:K次修改后的最大曼哈顿距离。用go语言,给出一个只包含字符 ‘N‘、‘S‘、‘E‘、‘W‘ 的字符串 s,

举报
福大大架构师每日一题 发表于 2025/08/12 08:29:44 2025/08/12
【摘要】 2025-08-12:K次修改后的最大曼哈顿距离。用go语言,给出一个只包含字符 ‘N’、‘S’、‘E’、‘W’ 的字符串 s,每个字符表示在无界方格上向某个方向移动一步。起点为原点 (0,0)。你可以最多改变 s 中的 k 个字符,每个被改的字符可以变为四个方向中的任意一个。按修改后的顺序依次执行这些步子,考虑整个移动过程中的任意时刻(即任意一步之后),求能够达到的离原点的最大曼哈顿距离(...

2025-08-12:K次修改后的最大曼哈顿距离。用go语言,给出一个只包含字符 ‘N’、‘S’、‘E’、‘W’ 的字符串 s,每个字符表示在无界方格上向某个方向移动一步。起点为原点 (0,0)。你可以最多改变 s 中的 k 个字符,每个被改的字符可以变为四个方向中的任意一个。按修改后的顺序依次执行这些步子,考虑整个移动过程中的任意时刻(即任意一步之后),求能够达到的离原点的最大曼哈顿距离(横坐标差的绝对值与纵坐标差的绝对值之和)。请返回这个最大可能值。

1 <= s.length <= 100000。

0 <= k <= s.length。

s 仅由 ‘N’、‘S’、‘E’ 和 ‘W’ 。

输入:s = “NSWWEW”, k = 3。

输出:6。

解释:

将 s[1] 从 ‘S’ 改为 ‘N’ ,将 s[4] 从 ‘E’ 改为 ‘W’ 。字符串 s 变为 “NNWWWW” 。

执行移动操作过程中,距离原点的最大曼哈顿距离是 6 。

题目来自力扣3443。

解决过程

以下描述算法的整体思路和步骤,不涉及具体代码实现。算法的核心思想是:在原始移动序列的基础上,通过计算每个位置(即每步之后)的原始曼哈顿距离,并考虑最多 k 次修改所能带来的最大增益(每次修改最多可使曼哈顿距离增加 2),从而得到每个位置可能达到的最大距离上界。最终,取所有位置中的最大值作为答案。

大体步骤

  1. 初始化变量

    • 设置当前位置坐标 (x, y) 为原点 (0, 0),表示起始位置。
    • 初始化 max_distance 为 0,用于记录整个过程中可能的最大曼哈顿距离。
  2. 遍历移动序列

    • 对于字符串 s 中的每个字符(按顺序处理),执行以下操作:
      • 更新当前位置:根据当前字符(未修改的方向)更新坐标:
        • 如果字符是 ‘N’,则 y 增加 1(向北移动)。
        • 如果字符是 ‘S’,则 y 减少 1(向南移动)。
        • 如果字符是 ‘E’,则 x 增加 1(向东移动)。
        • 如果字符是 ‘W’,则 x 减少 1(向西移动)。
        • 这一步得到的是原始序列下的当前位置 (x, y)
      • 计算原始曼哈顿距离:计算当前位置的原始曼哈顿距离,即 dist = |x| + |y|。这表示在未修改序列时,该步后的距离。
      • 计算当前可能的最大距离:考虑最多 k 次修改的影响:
        • 每个修改最多可以使曼哈顿距离增加 2(例如,在适当位置将向原点方向移动改为远离原点方向)。
        • 因此,修改后该位置可能的最大距离上界是 dist + 2 * k
        • 同时,由于已经执行了 step_count 步(当前是第 i+1 步,其中 i 是当前字符索引,从 0 开始),曼哈顿距离不可能超过步数(因为每步最多增加距离 1)。
        • 因此,该位置的最大距离候选值为 min(dist + 2 * k, step_count),其中 step_count = i + 1(因为索引 i 对应第 i+1 步)。
      • 更新全局最大距离:将候选值与当前 max_distance 比较,取较大者更新 max_distance
  3. 返回结果

    • 遍历所有字符后,max_distance 即为所求的最大曼哈顿距离。

关键点解释

  • 为什么考虑原始位置?:算法使用原始序列的当前位置作为基准,因为修改后的位置虽可能不同,但曼哈顿距离的差值最多为 2 * k(每次修改最多带来 2 的增益)。因此,dist + 2 * k 是修改后距离的上界。
  • 为什么与步数取最小值?:曼哈顿距离不可能超过已执行的步数(因为每步最多使 |x| 或 |y| 增加 1)。因此,候选值受 step_count 限制。
  • 为什么在每一步后计算?:最大距离可能出现在任意一步之后(不一定是最后一步)。通过遍历每个位置,算法覆盖了所有可能的时间点。
  • 正确性保证:在最优修改策略下,这个上界是可达到的(例如,通过将修改用于在关键位置将移动方向改为远离原点)。例如,在 s = "NSWWEW", k = 3 中,算法在最后一步计算原始距离为 2,候选值 min(2 + 6, 6) = 6,与最优修改结果一致。

复杂度分析

  • 时间复杂度:O(n),其中 n 是字符串 s 的长度。算法只需遍历字符串一次,每次操作(更新坐标、计算距离、比较等)都是常数时间 O(1)。
  • 额外空间复杂度:O(1)。算法仅使用固定数量的额外变量(如 xymax_distance、循环索引等),不依赖于输入大小。

该算法高效且简洁,适用于约束条件(n ≤ 100,000)。

Go完整代码如下:

package main

import (
	"fmt"
)

func maxDistance(s string, k int) int {
	latitude, longitude, ans := 0, 0, 0
	n := len(s)
	for i := 0; i < n; i++ {
		switch s[i] {
		case 'N':
			latitude++
		case 'S':
			latitude--
		case 'E':
			longitude++
		case 'W':
			longitude--
		}
		ans = max(ans, min(abs(latitude)+abs(longitude)+k*2, i+1))
	}
	return ans
}

func abs(x int) int {
	if x < 0 {
		return -x
	}
	return x
}

func main() {
	s := "NSWWEW"
	k := 3
	result := maxDistance(s, k)
	fmt.Println(result)
}

在这里插入图片描述

Python完整代码如下:

# -*-coding:utf-8-*-

def max_distance(s: str, k: int) -> int:
    latitude = 0
    longitude = 0
    ans = 0

    for i, ch in enumerate(s):
        if ch == 'N':
            latitude += 1
        elif ch == 'S':
            latitude -= 1
        elif ch == 'E':
            longitude += 1
        elif ch == 'W':
            longitude -= 1

        current = abs(latitude) + abs(longitude) + k * 2
        # 距离不可能超过已走的步数 i+1
        candidate = min(current, i + 1)
        ans = max(ans, candidate)

    return ans

if __name__ == "__main__":
    s = "NSWWEW"
    k = 3
    result = max_distance(s, k)
    print(result)

在这里插入图片描述

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。