1871. 跳跃游戏 VII

跳跃游戏 IV —— 区间跳跃判断能否到达终点

题目描述

给定一个下标从 0 开始的二进制字符串 s 和两个整数 minJumpmaxJump。初始位置在下标 0,且 s[0] 一定是 '0'

你可以从当前位置 i 跳跃到位置 j,满足以下条件:

  • 跳跃距离符合:i + minJump <= j <= min(i + maxJump, s.length - 1)
  • s[j] == '0',即目标位置必须是 '0'

请判断是否存在一条跳跃路径,可以从位置 0 跳到位置 s.length - 1


解题分析

这个问题的核心是判断是否存在一条合法的跳跃路径,跳跃的范围是一个闭区间 [minJump, maxJump],每次跳跃只能跳到值为 '0' 的位置。问题本质上是图的遍历问题:

  • 节点:字符串中的每个位置。
  • 边:从位置 i[i+minJump, i+maxJump] 范围内满足 s[j] == '0' 的节点。

直接思路

  • 使用 BFSDFS 遍历:
    • 从 0 开始,遍历所有符合跳跃条件的节点。
    • 记录已访问节点,避免重复搜索。
  • 但是直接枚举区间 [i + minJump, i + maxJump] 每次都遍历可能导致时间复杂度过高。

解题方法

方法一:直接 BFS/DFS(不推荐)

简单的 BFS/DFS 遍历,时间复杂度可能是 O(n * (maxJump - minJump)),当 maxJump - minJump 较大时会超时。

方法二:BFS + 区间优化(推荐)

核心思路:

  • 使用 BFS 队列保存可以跳到的节点。
  • 用一个变量 max_reach 记录当前遍历过的最远位置。
  • 每次从 i 出发,遍历区间 [max(i + minJump, max_reach + 1), min(i + maxJump, n - 1)],避免重复访问。
  • 只有区间中 s[j] == '0' 的位置才入队。
  • 一旦到达末尾 n-1 返回 True

这种方法避免了大量区间的重复遍历,大幅降低了时间复杂度。


代码实现

from collections import deque

class Solution:
    def canReach(self, s: str, minJump: int, maxJump: int) -> bool:
        n = len(s)
        # 如果起点或终点不是 '0',直接返回 False
        if s[0] != '0' or s[-1] != '0':
            return False

        queue = deque([0])
        max_reach = 0  # 记录已访问过的最远位置

        while queue:
            i = queue.popleft()
            # 新的区间开始位置,不重复访问
            start = max(i + minJump, max_reach + 1)
            # 新区间结束位置
            end = min(i + maxJump, n - 1)

            for j in range(start, end + 1):
                if s[j] == '0':
                    if j == n - 1:
                        return True
                    queue.append(j)

            # 更新最远访问位置,防止重复遍历
            max_reach = max(max_reach, end)

        return False

复杂度分析

  • 时间复杂度:
    由于每个位置最多被访问一次,且每次只遍历“新增”的区间,整体复杂度约为 O(n),其中 n 是字符串长度。
  • 空间复杂度:
    队列和额外标记空间最多存储 O(n) 个元素。

示例说明

以示例字符串:

s = "011010"
minJump = 2
maxJump = 3
  • 初始位置:0(s[0] == '0'
  • 可以跳跃的区间是 [i + 2, i + 3]

遍历过程:

  1. 从位置 0 出发,可跳到位置 2 或 3:
    • s[2] == '1',跳过
    • s[3] == '0',加入队列
  2. 从位置 3 出发,跳跃范围 [5, 6],但字符串长度是 6,最大是位置 5:
    • s[5] == '0',加入队列,且位置 5 是末尾
  3. 因此可以成功跳到末尾,返回 True

总结

  • 该问题用 BFS 搜索跳跃路径,关键是优化跳跃区间避免重复遍历。
  • 通过记录 max_reach,只遍历未访问过的新区间,实现了高效搜索。
  • 代码简洁且执行效率高,适合处理大规模输入。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值