【问题标题】:I am solving a problem with recursion but I got an Tle error on my last test case,how can I optimize my code?我正在解决递归问题,但在上一个测试用例中出现 Tle 错误,如何优化我的代码?
【发布时间】:2020-11-24 16:23:57
【问题描述】:

这是我的问题:

给定一个非负整数数组,您最初位于数组的第一个索引处。

数组中的每个元素代表您在该位置的最大跳跃长度。

确定您是否能够到达最后一个索引。

这是我的代码:

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int index=nums.size()-1;
        bool ans=dfs(nums,0);
        return ans;
    }
    bool dfs(vector<int>&nums,int start)
    {
        if(start>=0 && start<nums.size())
        {
            if(start == nums.size()-1)
            {
                return true;
            }
            if(nums[start] == 0)
            {
                return false;
            }
            else if(start>=nums.size())
            {
                return false;
            }
            for(int i=1;i<=nums[start];i++)
            {
                bool check = dfs(nums,start+i);
                if(check == true)
                {
                    return true;
                }
            }
        }
        return false;
    }
};

但是我在最后一个测试用例上得到了 tle: 这是最后一个测试用例

如何优化我的代码?请帮忙

谢谢。

【问题讨论】:

  • Tea Lost Exception?请不要使用只有使用在线编程竞赛的人才能理解的首字母缩略词。还请提供minimal reproducible example 完整代码、输入和预期输出
  • 经验法则:Time Limit Exceeded errors 通常意味着您使用的是慢速算法或实现,并且您应该使用更快的算法。

标签: c++ recursion vector


【解决方案1】:

边界本质上是N &lt;= 10^5,这意味着您必须为此提出O(n*log(n)) 解决方案。如果你记忆它,你的 DFS 可以微不足道地减少到O(N^2),但它在当前的非记忆状态下要慢得多。这背后的想法是您可以使用像 Fenwick 树(也称为二进制索引树或 BIT)这样的数据结构来存储位置是否可以到达末尾。然后,您可以获取O(log(n)) 中的范围之和,并更新O(log(n)) 中的元素。然后,您可以定义输入数组为nums,包含索引是否可能为poss的数组,以及poss[x]ij的总和(包括j但不包括i) 为sum(poss, i, j)。您可以通过以下公式计算poss

poss[n - 1] = 1
poss[i] = max(1, sum(poss, i, min(i + nums[i], n - 1)))

【讨论】:

  • 您能否提供有关 BIT 的资源?这对我很有帮助..谢谢。
【解决方案2】:

我可能误解了一些东西,但这似乎很容易通过对数组进行一次迭代来解决(从头到尾)。

  • 如果你知道索引i可以到达末尾,你发现索引c可以到达索引i,那么索引c也可以到达末尾。

  • 如果您可以跳到n 步骤,在索引c 并且知道i &lt;= c + n,那么您可以到达索引i

  • 如果索引i和索引j可以到达末尾,而i &lt; j,那么到达i就足够了。

bool CanReachEnd(std::vector<int> const & jumps)
{
    assert(jumps.size() > 0);
    std::size_t current = jumps.size() - 1;
    std::size_t lowest_can_reach_end = current;
    while (true)
    {
        assert(jumps[current] >= 0); // "non negative", unsigned would be better!
        if (current + jumps[current] >= lowest_can_reach_end)
        {
            lowest_can_reach_end = current;
        }
        if (current == 0) break;
        current -= 1;
    }
    assert(current == 0);
    return (lowest_can_reach_end == 0);
}

(Demo)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-26
    • 2019-08-30
    • 1970-01-01
    • 2021-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-11
    相关资源
    最近更新 更多