LeetCode 403. 青蛙過河(動態規劃)

青蛙過河

一隻青蛙想要過河。 假定河流被等分爲 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個石子之間的間距太大,沒有可選的方案供青蛙跳躍過去。

思路

動態規劃。dp[i][s]=true表示從某個位置跳s步到達第i個位置是可行的。

代碼

class Solution {
    public boolean canCross(int[] stones) {
        int i = 0, j = 0, n = stones.length, step = 0;
        boolean[][] dp = new boolean[1100][1100];
        dp[0][1] = true;
        for (i=1; i<n; ++i) {
            for (j=0; j<i; ++j) {
                step = stones[i] - stones[j];
                if (step >= n) {
                    continue;
                }
                if (dp[j][step]) {
                    dp[i][step] = true;
                    dp[i][step - 1] = true;
                    dp[i][step + 1] = true;
                }
            }
        }
        for (i=0; i<n; ++i) {
            if (dp[n-1][i]) {
                return true;
            }
        }
        return false;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章