leetcode-1871. Jump Game VII

Description

You are given a 0-indexed binary string s and two integers minJump and maxJump. In the beginning, you are standing at index 0, which is equal to ‘0’. You can move from index i to index j if the following conditions are fulfilled:

i + minJump <= j <= min(i + maxJump, s.length - 1), and
s[j] == '0'.
Return true if you can reach index s.length - 1 in s, or false otherwise.

Example 1:

Input: s = "011010", minJump = 2, maxJump = 3
Output: true
Explanation:
In the first step, move from index 0 to index 3. 
In the second step, move from index 3 to index 5.

Example 2:

Input: s = "01101110", minJump = 2, maxJump = 3
Output: false

Constraints:

2 <= s.length <= 10^5
s[i] is either '0' or '1'.
s[0] == '0'
1 <= minJump <= maxJump < s.length

Solution

double-side queue

Use a double-side queue to keep track of where we could jump, and enumerate the nums. When the index is at the left of jump interval, we continue. When the index is at the right of the current jump interval, we pop the jump interval to use a more behind interval. When the index falls into the jump interval, if nums[index] == 0, we add a jump interval to the queue.
If the queue is empty, we are running out of choices, so return False.

Time complexity: o ( n ) o(n) o(n)
Space complexity: o ( n ) o(n) o(n)

Heap

Use a heap to keep track of all the possible interval we could visit. If the current index is larger than the current smallest range, pop the range. If the current index falls between the current smallest range, we’ll see if we could update the range heap. That is, if the ch equals to 0, we would update the heap. If the current index is smaller than the current range, we keep going and do nothing.
In this way, the heap actually denotes all the blocks we could go. So we would return False if the heap is empty, and return True if and only if the last ch is 0 and it falls between the top of the heap.

In the worst scenario, the heap would grow to the height of n, so the search and pop time complexity would be o ( log ⁡ n ) o(\log n) o(logn), thus the whole time complexity is: o ( n log ⁡ n ) o(n \log n) o(nlogn)
Space complexity: o ( log ⁡ n ) o(\log n) o(logn)

Sliding Window + DP

We use dp[i] to denote whether we could reach i or not. Then the transform equation will be:
d p [ i ] = any ( d p [ i − m a x J u m p : i − m i n J u m p ] ) dp[i] = \text{any}(dp[i - maxJump: i - minJump]) dp[i]=any(dp[imaxJump:iminJump])
We use pre_sum to record the sum of dp[i - maxJump: i - minJump], when i increases, all we need to do is minus the left and add the right.
Time complexity: o ( n ) o(n) o(n)
Space complexity: o ( n ) o(n) o(n)

Code

double-side queue

class Solution:
    def canReach(self, s: str, minJump: int, maxJump: int) -> bool:
        queue = collections.deque([(minJump, maxJump)])
        index = 1
        while index < len(s):
            if queue:
                if index < queue[0][0]:
                    index += 1
                elif index > queue[0][1]:
                    queue.popleft()
                else:
                    if s[index] == '0':
                        if index == len(s) - 1:
                            return True
                        queue.append((index + minJump, index + maxJump))
                    index += 1
            else:
                return False
        return False

Heap

class Solution:
    def canReach(self, s: str, minJump: int, maxJump: int) -> bool:
        import heapq
        jump_range = []
        heapq.heappush(jump_range, (minJump, maxJump))
        for i, ch in enumerate(s):
            while jump_range and i > jump_range[0][1]:
                heapq.heappop(jump_range)
            if not jump_range:
                return False
            if jump_range[0][0] <= i <= jump_range[0][1] and ch == '0':
                heapq.heappush(jump_range, (minJump + i, maxJump + i))
        return True if ch == '0' and jump_range and jump_range[0][0] <= i <= jump_range[0][1] else False

dp + pre_sum

class Solution:
    def canReach(self, s: str, minJump: int, maxJump: int) -> bool:
        dp = [True] + [False] * (len(s) - 1)
        pre_sum = 0
        for i in range(minJump, len(s)):
            pre_sum = pre_sum + (dp[i - minJump]) - (dp[i - maxJump - 1] if i - maxJump - 1 >= 0 else 0)
            dp[i] = pre_sum > 0 and s[i] == '0'
        return dp[-1]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值