当前位置: 首页 > 知识库问答 >
问题:

最小跳跃数组(自顶向下方法)

后星河
2023-03-14

问题陈述:给定一个长度为N的非负整数数组A,您最初位于数组的第一个索引处。数组中的每个元素表示该位置的最大跳跃长度。返回到达最后一个索引所需的最小跳转次数。

输入:A=[2,3,1,1,4]

产出:2

说明:达到指数4的最短途径是指数0-

以下是解决方案:

// M is the function that gives the required minimum jumps
// nums is the vector containing jumps (here I have used nums in place of array A).
// start denoting the starting index
// map(m) STL for memoization

int M(vector<int> &nums, int start, unordered_map<int, int>&m){

    if(start == nums.size()-1){return 0;} // if we reach the last index then return 0.

    if(start >= nums.size()){return INT_MAX;} // if we reach beyond last index then return some big value that can't be the answer.

    if(nums[start] == 0){return INT_MAX;} // if in mid we get jump value = 0 then we cannot expect the min jump so again return some big value.

    if(m[start] != 0){return m[start];} // if we already stored the value (calculated the answer) then return stored value 

    int ans = INT_MAX; // assuming initially answer to be some big value. 

    for(int i=1; i<=nums[start]; i++){ // jump can be made from 1 to maximum value of that element in array i.e. nums[start]

        ans = min(ans, 1+M(nums, start+i, m)); // answer is minimum of previously calculated answer and 1 + allowed path (start + i).

        m[start] = ans; // storing it in map.
    }

    return m[start]; // returning the stored value
}

我得到了上述解决方案的TLE。我无法在记忆后计算出解决方案的时间复杂度。有人能帮我估计一下上述解决方案的时间复杂度吗。

共有2个答案

方俊
2023-03-14

我不确定你的问题,但我想我有一个O(N)解决方案:

int M(const vector<int> &nums)
{
    int n_jumps = 0;
    int cur_pos = 0;
    int prev_pos = 0;
    int next_jump = 0;
    int max_value = 0;
    int value;
    int i;
    while (cur_pos + nums[cur_pos] < nums.size() - 1)
    {
        next_jump = 0;
        max_value = 0;
        i = cur_pos > 0 ? prev_pos + nums[prev_pos] + 1 : 1;
        for (; i <= cur_pos + nums[cur_pos]; ++i)
        {
            value = i + nums[i];
            if (value >= nums.size() - 1) return n_jumps + 2;
            if (max_value < value)
            {
                max_value = value;
                next_jump = i - cur_pos;
            }
        }
        prev_pos = cur_pos;
        cur_pos += next_jump;
        ++n_jumps;
    }
    return n_jumps + 1;
}

每次我们通过最大限度地增加本回合和下一回合的距离来选择跳跃幅度。最后一次跳转可以是允许的最大跳转,即我们所在元素的值。

请注意,当我们跳转到下一个元素时,我们不必检查从上一个位置(给出O(N))可以访问的元素。

可以证明,该算法利用数学归纳法求出了最小跳数。

秦宁
2023-03-14

我在O(nlogn)复杂性中有一个解决这个问题的方法(可能会有更好的方法)

使用延迟段树存储l,r索引的最小值。

在每个索引集上dp[i]=查询(i,i)然后更新(i1,dp[i]i,dp[i]1)

如果你感到困惑,请发表评论。我也将提供实现。

我知道可能会有更好的解决方案,因为这个问题似乎很经典,但这是我第一次想到的。

 类似资料:
  • 下面是寻找最小跳跃次数的算法谜题。发布了详细的问题声明和两个代码版本来解决这个问题。我做了测试,似乎两个版本都可以工作,我的第二个版本是版本一代码的优化版本,这使得我从开始,而不是持续增加,这可以通过不迭代所有的插槽来节省时间数组。 我的问题是,想知道我的第二个版本代码是否100%正确?如果有人发现任何逻辑问题,请指出。 问题陈述 给定一个非负整数数组,您最初位于数组的第一个索引处。 数组中的每个

  • 我有一个算法,它基于一个问题,你需要找到到达数组末端的最小跳跃次数。这个问题是在极客中为极客提出的,他们没有线性时间算法。在我的例子中,算法是线性时间的,但我的算法会在哪个测试用例中失败?。问题的链接 链接:-http://www.geeksforgeeks.org/minimum-number-of-jumps-to-reach-end-of-a-given-array/ 输入: arr[] =

  • 问题声明:给定数组:[1,0,1,0,1,1,1,1,1,0,1,1,1,0]输出:到达结束所需的最小步骤 条件: 0上的步骤是退出 我已经完成了不使用DP的情况下的使用,是否存在针对此问题的DP解决方案。 我的代码:

  • 我试图解决Leetcode上最长的回文子串。我知道这个问题的解决方案,比如围绕中心展开或动态编程自下而上的方法。出于纯粹的教育目的,我想以自上而下的递归方式解决这个问题。我试图找到类似于这里或这里描述的解决方案。(问题略有不同)。我有这个功能: 它接受搜索的字符串开始和结束位置。返回的元组是最长palindrom的开始和结束。我试图分成以下情况: 如果s[i]==s[j],则调查最长(s,i 1,

  • 假设您有一个网格,其中每个节点都包含一个权重,该权重表示获取该正方形的成本。 从二维数组左上角的(0,0)开始,然后到达(X-1,Y-1),其中X是列数,Y是右下角的行数。你可以向右走1平方米,也可以一次向下走1平方米。您还将获得一个整数“跳跃”数组,其中每个值$d_i$表示您可以在第i次跳跃时向右或向下跳过的方块数。跳转数组指定跳转的顺序,这意味着,例如,如果没有使用一个跳转,则不能跳转[2]。

  • 我正在调试以下问题并发布代码。不知道代码是否正确。我目前的疑问是,是否应该一直增加(在这一行--