LeetCode 403.青蛙过河

LeetCode 403.青蛙过河

题目

在这里插入图片描述

解题思路

image.png

这道题第一眼看上去就能想到要用递归,因此可以先写出递归的实现代码,但别提交因为递归的时间复杂度很高,此题又是困难题,因此暴力递归肯定时间超时。所以为了保证我们的通过率,还应再次基础上进行记忆化搜索来优化算法。
递归第一步先考虑怎么出来,此题结束递归的条件为判断当前位置经过{k-1,k,k+1}步能不能刚好到达最后一颗石子,即stones[i] + (k-1 || k || k+1) == stones[stones.lenth - 1];
第二步考虑怎么进行递归,当我们通过k步来到第stones[i]块石头的位置,考虑能否经过{k-1,k,k+1}步刚好到达有石头的地方,如果有再继续遍历。

之后优化。
首先我们需要知道我们要保存的东西是什么。应该是当我来到第i块石头要向前走m步的时候我想知道先前的递归是不是已经有过这样子的先例如果有,那么直接根据之前的结果返回上一层,不需要继续往下递归,从而节省时间。

比起动态规划,递归+记忆化搜索是一种比较好想到的算法,唯一的缺点就是代码量可能比较长.

代码

//递归+记忆化搜索(Myself)
class Solution {
    int[][] dp;
    public boolean canCross(int[] stones) {
        dp = new int[stones.length][stones.length];
        return path(stones, 1, 0);
    }
    public boolean path(int[] stones, int k, int count) {
        int n = stones.length;
        boolean flag = false;
        if(dp[count][k] > 0) {
            return true;
        }else if(dp[count][k] < 0) {
            return false;
        }
        if(stones[count] + k == stones[n - 1]) {
            return true;
        }
        if((stones[count] + k) >= stones[count + 1]) {
            for (int i = count + 1; i < n; i++){
                if((stones[count] + k) == stones[i]) {
                    flag = path(stones, k-1, i);
                    dp[i][k-1] = flag == false ? -1 : 1;
                    if (flag){
                        break;
                    }
                    flag = path(stones, k, i);
                    dp[i][k] = flag == false ? -1 : 1;
                    if (flag){
                        break;
                    }
                    flag = path(stones, k+1, i);
                    dp[i][k+1] = flag == false ? -1 : 1;
                    break;
                }
            } 
        }  
        return flag;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值