leetcode 403. Frog Jump DP

题意

  • n个石头排成一行,i-th石头所在位置是pos(i),假如青蛙目前在i-th石头上,且它是从前面石头跳了k单位长度过来的,则它接下来可以跳k + 1, k - 1, k单位长度远,初始在0位置,且只能跳1单位长度,问它能否跳到最后一个石头。(n < 1100)

思路

  • 这个题我们最简单的dp思路,就是dp(i, k)表示在第i个石头上,且从上一个石头跳k单位长度过来,是否可行。但是由于k每次可以加1,它最大可以到O(n^2),复杂度过高
  • 我们可以进一步简化dp,其实第i个石头必然是从前i-1个石头上跳过来的,上一个定了,k也就定了,所以k的范围可以被缩小到O(n),状态定义就是dp(i, j)表示在第i个石头上,且从第j个石头跳过来,是否可行
  • 进一步,考虑dp(i, j)有效的可能不多,所以用一个hash set存储可行的方案,当然这步我也不确定是否可以加速,因为没有本质上降低复杂度,且hash set插入时开新内存空间可能慢一些。

实现

class Solution {
public:
    bool canCross(vector<int>& stones) {
        int n = stones.size();
        unordered_map<int, int> mapp;
        vector<unordered_set<int>> dp(n);
        for (int i = 0; i < n; i++){
            mapp[stones[i]] = i;
        }
        dp[0].insert(1);
        for (int i = 0; i < n; i++){
            for (auto it : dp[i]){
                int d = it + stones[i];
                if (mapp.find(d) != mapp.end()){
                    for (int j = 1; it + j > 0 && j >= -1; j--){
                        dp[mapp[d]].insert(it + j);
                    }
                }
            }
        }
        return dp[n-1].size();
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值