403-青蛙过河

题目

403. 青蛙过河 - 力扣(LeetCode) (leetcode-cn.com)

思路

一个问题:利用青蛙能否到达第j个石子(j<i)的信息, 我们怎么判断青蛙是否能够到第i个石子呢?

i个石子和第j个石子之间的距离为gap = stones[i] - stones[j],因此,如果青蛙能够到达第j个石子,并且到达第j个石子时的跳跃长度为jump,在jump + 1 == gap || jump == gap || jump - 1 == gap时青蛙可以从第i个石子到第j个石子,而其他情况则不可以。为了判断能否到达第i个石子,我们搜索j < i的所有情况。

另外,根据每次跳跃的长度最多增加1的限制,青蛙跳跃到第j个石子时跳跃长度jump必定满足jump <= j(i从0开始)。因此,其下一跳最大长度为j + 1,因此在gap > j + 1时必定无法完成跳跃。

根据上述分析,我们需要记录青蛙到达第j个石子时所有可能的最后一跳的长度,这个长度将在判断后续石子能否到达时被查询使用 。为了提高查询效率,最后一跳的长度使用hash表来存放,这样我们就能快速判断该石子能否跳跃到后续间距为gap的石子。(即gap,gap+1gap - 1是否位于垓石子的hash表中)。

我们使二维数组dp[i][k]来保存到达第i个石子时最后一跳的所有长度,数组的第一维表示不同的石子,第二维作为hash表保存当前石子的所有可能的最后一跳长度,即dp[i][k]==true表示跳跃长度k在hash表中,dp[i][k]==false表示跳跃长度k不在hash表中。

根据上述分析可知最长跳跃长度<= stone.size()-1,因此hash表最大长度为stones.size(), 另外总共有stones.size()个石子,因此二维数组dp的长度为dp[stones.size()][stones.size()]

代码

class Solution {
public:
    bool canCross(vector<int>& stones) {
        int row_size = stones.size();
        bool *dp = new bool[row_size * row_size];

        for (int i=0; i<row_size * row_size; i++) {
            dp[i] = false;
        }
        dp[0 * row_size + 0] = true;
        
        for (int i=1; i<stones.size(); i++) {
            int p = 0;
            for(int j=i-1; j >= 0; j--) {
                int gap = stones[i] - stones[j];
                if (gap > (j + 1)) {
                    break;
                }
                dp[i * row_size + gap] = dp[j * row_size + gap - 1] || dp[j * row_size + gap] || dp[j * row_size + gap + 1];
            }
        }
        for (int i=1; i < row_size; i++) {
            if (dp[(row_size - 1) * row_size + i] == true) {
                return true;
            }
        }
        return false;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值