題目
一隻青蛙想要過河。 假定河流被等分爲 x 個單元格,並且在每一個單元格內都有可能放有一石子(也有可能沒有)。 青蛙可以跳上石頭,但是不可以跳入水中。
給定石子的位置列表(用單元格序號升序表示), 請判定青蛙能否成功過河(即能否在最後一步跳至最後一個石子上)。 開始時, 青蛙默認已站在第一個石子上,並可以假定它第一步只能跳躍一個單位(即只能從單元格1跳至單元格2)。
如果青蛙上一步跳躍了 k 個單位,那麼它接下來的跳躍距離只能選擇爲 k - 1、k 或 k + 1個單位。 另請注意,青蛙只能向前方(終點的方向)跳躍。
請注意:
石子的數量 ≥ 2 且 < 1100;
每一個石子的位置序號都是一個非負整數,且其 < 231;
第一個石子的位置永遠是0。
示例 1:
[0,1,3,5,6,8,12,17]
總共有8個石子。
第一個石子處於序號爲0的單元格的位置, 第二個石子處於序號爲1的單元格的位置,
第三個石子在序號爲3的單元格的位置, 以此定義整個數組...
最後一個石子處於序號爲17的單元格的位置。
返回 true。即青蛙可以成功過河,按照如下方案跳躍:
跳1個單位到第2塊石子, 然後跳2個單位到第3塊石子, 接着
跳2個單位到第4塊石子, 然後跳3個單位到第6塊石子,
跳4個單位到第7塊石子, 最後,跳5個單位到第8個石子(即最後一塊石子)。
示例 2:
[0,1,2,3,4,8,9,11]
返回 false。青蛙沒有辦法過河。
這是因爲第5和第6個石子之間的間距太大,沒有可選的方案供青蛙跳躍過去。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/frog-jump
解法
class Solution {
public boolean canCross(int[] stones) {
if(stones[1]>1){//第一跳只能跳一格,如果stones[1]不爲1,肯定爲false
return false;
}
Set<Integer> set = new HashSet<>();
for(int i = 0; i < stones.length; i++){
if(i>3 && stones[i] >= 2*stones[i-1]){//如果下一個石頭位置序號爲當前序號的兩倍,肯定不符合
return false;
}
set.add(stones[i]);
}
return check(stones[stones.length-1], set, 1,1);
}
private boolean check(int last, Set<Integer> set, int index,int step){
if(index == last){
return true;
}
if(set.contains(index + step + 1)){
if(check(last, set, index + step + 1, step + 1)){
return true;
}
}
if(set.contains(index + step)){
if(check(last, set, index + step, step)){
return true;
}
}
if(step-1>0){
if(set.contains(index + step - 1)){
if(check(last, set, index + step - 1, step - 1)){
return true;
}
}
}
return false;
}
}