Leetcode1654. Minimum number of jumps to get home (medium, BFS)

content

1. Problem description

2. Problem solving analysis

2.1 The search is bounded

case1: a >= b

case2: a < b

2.2 Prevent infinite loops

3. Code implementation

4. Proof of case2


1. Problem description

A home with a flea is at the position on the number  x line. Please help it get from its location  0 to its home.

The rules for flea jumping are as follows:

  • It can  jump forward  exactly  a a position (ie jump right).
  • It can  jump back  exactly  b a number of positions (ie, to the left).
  • It cannot   skip backwards  consecutive2  times.
  • It cannot jump to any  forbidden position in the array.

A flea can jump forward  beyond  its home position, but it  cannot jump to negative integer  positions.

Give you an array  forbidden of integers where  forbidden[i] fleas cannot jump, give you integers  ab and  x , please return the minimum number of jumps a flea has to make to get home. If there is no feasible solution that happens to arrive  x , please return  -1 .

Example 1:

Input: forbidden = [14,4,18,1,15], a = 3, b = 15, x = 9
 Output: 3
 Explanation: skip forward 3 times (0 -> 3 -> 6 -> 9), The fleas have arrived home.

Example 2:

Input: forbidden = [8,3,16,6,12,20], a = 15, b = 13, x = 11
 Output: -1

Example 3:

Input: forbidden = [1,6,2,14,5,17,4], a = 16, b = 9, x = 7
 Output: 2
 Explanation: skip forward once (0 -> 16), then back One jump (16 -> 7) and the fleas are home.

hint:

  • 1 <= forbidden.length <= 1000
  • 1 <= a, b, forbidden[i] <= 2000
  • 0 <= x <= 2000
  • forbidden All locations are different from each other.
  • Location is  x not  forbidden in.

Source: LeetCode
Link: https://leetcode-cn.com/problems/minimum-jumps-to-reach-home The
copyright belongs to LeetCode.com. For commercial reprints, please contact the official authorization, and for non-commercial reprints, please indicate the source.

2. Problem solving analysis

        Since it is to find the minimum number of steps, it is naturally the site of breadth-first search.

        When choosing the next action (neighbor or child), the following constraints need to be considered:

  • (1) The target position cannot be negative, but the positive direction is not limited
  • (2) You cannot jump backward twice in a row (ie, jump to the left)
  • (3) Cannot jump to the position contained in forbidden
  • (4) Do not have to visit the same location repeatedly

        From the above condition (2), during the search process, the last jumping direction of the flea must be memorized, which can be stored in the stack together with the position information.

        Since forbidden needs to be queried frequently, and all positions in forbidden are different, it can be converted into a collection type to facilitate query.

2.1 The search is bounded

        It should be noted that since the forward jump is not limited, the flea can theoretically jump all the way. So we need to add a constraint, which should be that when the flea jumps forward far enough, the flea will definitely not be able to go home. This is used as a condition to break out of the loop.

        But what is this condition? The topic is not clearly given, and a reasonable constraint must be deduced according to the conditions of the topic. According to the relative size of a and b, there are two cases to consider.

case1: a >= b

        Due to the condition of "can't jump back twice in a row", it is ensured that every backward jump is accompanied by at least one forward jump.

        If the flea has jumped beyond x+b, it can then jump back up to b, so it will never get home.

case2: a < b

        It can be shown that the right bound of the search when a < b is  max(f_{max}+a+b,x). where fmax represents the maximum forbidden value.

        See the appendix below for proof.

        Combining case1 and case2 can get the right boundary of the search max(f_{max}+a+b,x+b).

2.2 Prevent infinite loops

        In the usual graph search, it is necessary to add the visited nodes to this visited to avoid repeated visits.

        This is also required in this question. Reuse forbidden, and add the visited points to forbidden. This avoids maintaining another visited, which can save memory.

        However, one of the main points of this question is that the moved position only needs to be added to the visited set when moving to the right; but the moved position does not need to be added to the visited set when moving to the left. In other words, you don't have to go where you have gone forward, and you can go where you have gone backward (but haven't been there yet).

        This insight is based on other solutions. But I don't quite understand it yet. I will come back and add it when I understand how to explain it. 

3. Code implementation

from typing import List
from collections import deque

class Solution:
    def minimumJumps(self, forbidden: List[int], a: int, b: int, x: int) -> int:
        # Assumption: 0:forward jump, 1: backward jump
        pos_max = max(max(forbidden)+a+b, x+b)
        forbidden_s = set(forbidden)
        q = deque([(-1,0,0)]) # (prev_operation,position,layer)
        forbidden_s.add(0)
        while len(q) > 0:
            op,pos,layer = q.popleft()
            # print(op,pos,layer)
            
            if pos == x:
                return layer
            newpos = pos+a
            if newpos not in forbidden_s and newpos <= pos_max:
                q.append((0,newpos,layer+1))
                forbidden_s.add(newpos)
            newpos = pos-b
            if op!=1 and newpos>=0 and newpos not in forbidden_s:
                q.append((1,newpos,layer+1))
                # forbidden_s.add(newpos)
            
        return -1
    
if __name__ == "__main__":
    
    sln = Solution()
    
    forbidden = [14,4,18,1,15]
    a = 3
    b = 15
    x = 9
    print(sln.minimumJumps(forbidden, a, b, x))
    
    forbidden = [8,3,16,6,12,20]
    a = 15
    b = 13
    x = 11
    print(sln.minimumJumps(forbidden, a, b, x))

        Execution time: 64 ms, beat 82.32% of users in all Python3 commits

        Memory consumption: 15.3 MB, beating 91.92% of users across all Python3 commits

        

4. Proof of case2

         The following proof is from the Likou Forum (very hard core... I don't understand it too much, so I will excerpt it and leave it to be digested later).

Author: newhar
Link: https://leetcode-cn.com/problems/minimum-jumps-to-reach-home/solution/dao-jia-de-zui-shao-tiao-yue-ci-shu-zui-duan -lu-zh/
Source: The copyright of LeetCode
belongs to the author. For commercial reprints, please contact the author for authorization, and for non-commercial reprints, please indicate the source.

        Subsequent proofs need to consider some details, but it is very simple after understanding: if the optimal path is out of bounds, you can adjust the order of the jumps before and after to make it out of bounds. (Imagine a long rope, the start and end points are fixed, think it is too long, so fold it up and put it)

        

 

        Back to the main directory: Leetcode daily problem-solving notes (dynamic update...) 

    

Guess you like

Origin blog.csdn.net/chenxy_bwave/article/details/124245359