每天堅持刷題!!!
leetcode 403 青蛙過河
題目描述:
一隻青蛙想要過河。 假定河流被等分爲 x 個單元格,並且在每一個單元格內都有可能放有一石子(也有可能沒有)。 青蛙可以跳上石頭,但是不可以跳入水中。
給定石子的位置列表(用單元格序號升序表示), 請判定青蛙能否成功過河(即能否在最後一步跳至最後一個石子上)。 開始時, 青蛙默認已站在第一個石子上,並可以假定它第一步只能跳躍一個單位(即只能從單元格1跳至單元格2)。
如果青蛙上一步跳躍了 k 個單位,那麼它接下來的跳躍距離只能選擇爲 k - 1、k 或 k + 1個單位。 另請注意,青蛙只能向前方(終點的方向)跳躍。
石子的數量 ≥ 2 且 < 1100;
每一個石子的位置序號都是一個非負整數,且其 < 231;
第一個石子的位置永遠是0。
題目分析:
- 這道題咋一看起來似乎無從下手,因爲每一個石頭到達的方法可能有多種,每一種方法下一步可以到達的石頭又不一樣,但是我們可以通過對每一個石頭記錄其從上一部到達時的跳過的步數,然後看最後終點的石頭是否有到達的可能。
- 總結起來,就是搞一個hash表,每一個石頭位置爲key,value爲一個set,記錄可以到達這個位置的石頭要跳過的上一步的步數,然後通過遍歷每一個石頭的set來得到可能到達的下一個石頭的位置。
- 舉例而言,假設石頭爲【0,1,2,3】, 那麼得到的這個hash表爲:{0:set(0), 1:set(1), 2:set(1), 3:set(1,2)}
class Solution(object):
def canCross(self, stones):
"""
:type stones: List[int]
:rtype: bool
"""
if not stones:
return False
candidates = {stones[i]: set() for i in xrange(len(stones))}
candidates[0].add(0)
for i in xrange(len(stones)):
if not candidates[stones[i]]:
continue
for j in candidates[stones[i]]:
temp = [j+1]
if j - 1> 0: # 只能往終點跳
temp.append(j-1)
if j > 0: # 只能往終點跳
temp.append(j)
for tt in temp:
if tt + stones[i] in candidates:
candidates[tt+stones[i]].add(tt)
return True if candidates[stones[-1]] else False