leetcode 403. Frog Jump DP

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/luke2834/article/details/79478990

题意

  • 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();
    }
};

猜你喜欢

转载自blog.csdn.net/luke2834/article/details/79478990