BFS.
坑:
-b
往回跳的点,依然可以试图利用+a
走一次。因为通过+a
走到的点既能前跳又能后跳,不用再遍历了;而通过-b
走到的点只能前跳,所以可能的情况下还是要通过+a
走一次探索一下后跳的可能性。由于坐标一定是非负的,这里我用负数来表示某坐标是通过后跳走到的,这样就和前跳分开记录visited了。a的情况下。在a>b的情况下容易证明最远走x+b就可以了。而a的时候的尝试上限一直不知道怎么算……leetcode题解里通用的threshold是6000,也不知道咋来的。
虽然有大佬给了证明,但是他证明出来的阈值是 max ( max ( F ) + a + b , x + b ) \max(\max(F)+a+b,x+b) max(max(F)+a+b,x+b),但是最后算具体阈值的时候套用的F
,a
,b
的上限值去算的threshold,按 max ( F ) + a + b \max(F)+a+b max(F)+a+b的上限去算的,所以是6000。
但是,比如说121步的那个testcase:
[162,118,178,152,167,100,40,74,199,186,26,73,200,127,30,124,193,84,184,36,103,149,153,9,54,154,133,95,45,198,79,157,64,122,59,71,48,177,82,35,14,176,16,108,111,6,168,31,134,164,136,72,98]
29
98
80
我自己把path打出来看过:
[80, 51, -22, 120, -91, 189, -160, 258, -229, 327, -298, 396, -367, 465, -436, 534, -505, 603, -574, 672, -643, 741, -712, 810, -781, 879, -850, 948, -919, 1017, -988, 1086, -1057, 1155, -1126, 1224, -1195, 1293, -1264, 1362, -1333, 1431, -1402, 1500, -1471, 1569, -1540, 1638, -1609, 1707, -1678, 1776, -1747, 1845, -1816, 1914, 1885, 1856, 1827, 1798, 1769, 1740, 1711, 1682, 1653, 1624, 1595, 1566, 1537, 1508, 1479, 1450, 1421, 1392, 1363, 1334, 1305, 1276, 1247, 1218, 1189, 1160, 1131, 1102, 1073, 1044, 1015, 986, 957, 928, 899, 870, 841, 812, 783, 754, 725, 696, 667, 638, 609, 580, 551, 522, 493, 464, 435, 406, 377, 348, 319, 290, 261, 232, 203, 174, 145, 116, 87, 58, 29]
最大值到达1914,而按他公式的算法阈值仅有327。所以这一番推导其实对特定testcase是不成立的,感觉只是用上限刚好算对了阈值而已……
class Solution:
def minimumJumps(self, forbidden: List[int], a: int, b: int, x: int) -> int:
forbid = set(forbidden)
f = max(forbid)
for v in forbidden:
forbid.add(-v)
q1 = deque()
q1.append(0) # -i means jumped from i+b
step = 0
forbid.add(0)
while q1:
# print(step, q1)
q2 = deque()
for v in q1:
i = abs(v)
if i == x:
return step
if i+a < 6000 and i+a not in forbid:
q2.append(i+a)
forbid.add(i+a)
if v > 0 and i-b >= 0 and b-i not in forbid:
q2.append(-i+b)
forbid.add(b-i)
q1 = q2
step += 1
return -1