​LeetCode刷题实战403: 青蛙过河

Java
342
0
0
2022-11-10

算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !

今天和大家聊的问题叫做 青蛙过河,我们先来看题面:

https://leetcode-cn.com/problems/frog-jump/

A frog is crossing a river. The river is divided into some number of units, and at each unit, there may or may not exist a stone. The frog can jump on a stone, but it must not jump into the water.

Given a list of stones' positions (in units) in sorted ascending order, determine if the frog can cross the river by landing on the last stone. Initially, the frog is on the first stone and assumes the first jump must be 1 unit.

If the frog's last jump was k units, its next jump must be either k - 1, k, or k + 1 units. The frog can only jump in the forward direction.

一只青蛙想要过河。 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有)。 青蛙可以跳上石子,但是不可以跳入水中。

给你石子的位置列表 stones(用单元格序号 升序 表示), 请判定青蛙能否成功过河(即能否在最后一步跳至最后一块石子上)。

开始时, 青蛙默认已站在第一块石子上,并可以假定它第一步只能跳跃一个单位(即只能从单元格 1 跳至单元格 2 )。

如果青蛙上一步跳跃了 k 个单位,那么它接下来的跳跃距离只能选择为 k - 1、k 或 k + 1 个单位。 另请注意,青蛙只能向前方(终点的方向)跳跃。

示例

示例 1:

输入:stones = [0,1,3,5,6,8,12,17]

输出:true

解释:青蛙可以成功过河,按照如下方案跳跃:跳 1 个单位到第 2 块石子, 然后跳 2 个单位到第 3 块石子, 接着 跳 2 个单位到第 4 块石子, 然后跳 3 个单位到第 6 块石子, 跳 4 个单位到第 7 块石子, 最后,跳 5 个单位到第 8 个石子(即最后一块石子)。

示例 2:

输入:stones = [0,1,2,3,4,8,9,11]

输出:false

解释:这是因为第 5 和第 6 个石子之间的间距太大,没有可选的方案供青蛙跳跃过去。

解题

思路(动态规划):

对于位置 i 处,①考虑前面的位置能否跳到此处 ②如果可以,存储它下次能跳跃的三个位置

对于①:前面任意位置 j (0~i-1),与位置 i 处的距离 diff ,判断位置 j是否有能力跳 diff

即**dp[j][diff]**是否为true

对于②:如果能跳到位置 i 处,那么存储它能跳的位置:

dp[i][diff-1]=true; dp[i][diff]=true;

dp[i][diff+1]=true;

class Solution {
public:
    bool canCross(vector<int>& stones) {
        int n=stones.size();
        vector<vector<bool>>dp(n,vector<bool>(n+1,false));
        dp[0][1]=true;
        for(int i=1;i<n;i++){
            bool flag=false;
            //因为要到达i,与石头j的距离,必须要小于i,不然不可能跳到i处 
            for(int j=i-1;j>=0;j--){
                int diff=stones[i]-stones[j];
                if(diff>i){
                    break;
                }
                if(dp[j][diff]){
                    dp[i][diff-1]=true;
                    dp[i][diff]=true;
                    dp[i][diff+1]=true;
                    flag=true;
                }
            }
            if(i==n-1&&flag){
                return true;
            }
        }
        return false;
    }
};

好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力 。