【问题标题】:Is he being greedy?他贪心吗?
【发布时间】:2018-04-20 13:03:44
【问题描述】:

我正在解决来自LeetCode.com的问题:

给定一个非负整数数组,您最初位于数组的第一个索引处。 数组中的每个元素代表您在该位置的最大跳跃长度。 确定您是否能够到达最后一个索引。 例如: A = [2,3,1,1,4],返回真。 A = [3,2,1,0,4],返回 false。

投票最多的解决方案之一 (here) 表示以下是使用贪婪方法:

bool canJump(int A[], int n) {
    int last=n-1,i,j;
    for(i=n-2;i>=0;i--){
        if(i+A[i]>=last)last=i;
    }
    return last<=0;
}

我有两个问题:

  1. 为此使用贪心算法背后的直觉是什么?
  2. 上述解决方案如何算一个贪心算法?

我认为这可以通过动态编程来解决。我知道可以通过 DP 解决的问题可以通过贪心方法来解决,但是这个特定的问题背后的直觉是什么让贪心方法更有意义?

这个SO question在某种程度上突出了这种差异。我知道这可能会更多,但如果可能的话,有人可以在这种情况下回答这个问题吗?我将不胜感激。

谢谢。

编辑:我认为我感到困惑的原因之一是输入[3,3,1,0,4]。根据贪心范式,当i=0 时,我们不会为了贪婪地达到输出而跳出3 (A[0]) 的大小吗?但这样做实际上是不正确的。

【问题讨论】:

  • 链接解决方案中的前几句话完全解释了您所要求的一切。到底是什么让你绊倒了?
  • “贪婪”通常是指始终使用当前状态的第一个可用移动并且从不回溯的算法。
  • 我猜你在谈论(这个)[discuss.leetcode.com/topic/3443/…特别是。可能是语法? :) 我发现很难听懂他说的话。
  • @IgorTandetnik,哇,这是一个非常有用的技巧。我从来没有这样想过。回想起来,这对我来说似乎很明显。
  • 我不同意这是一个贪心算法。这个问题是一个决策问题,这只是对问题空间进行线性搜索。您可以尝试使用贪心算法来解决相关问题“返回从索引0 到N 的移动序列,如果不存在则返回”

标签: c++ algorithm dynamic-programming greedy


【解决方案1】:

根据维基百科:

贪心算法是一种算法范式,它遵循问题求解启发式,在每个阶段做出局部最优选择,希望找到全局最优。

在这里,我想提请您注意关键短语,每个阶段的局部最优选择,它使算法范式变得贪婪。


Q1. What is the intuition behind using a greedy algorithm for this?

由于在这个问题中,我们只关心是否有可能到达数组的最后一个索引,我们可以使用贪心算法。贪心算法会在每一步都选择最优选择(最大跳跃),最后检查最大索引是否能到达终点。

说,如果我们需要找出每个索引到达终点的跳转大小或者需要优化到达终点的跳转次数,那么直接使用贪心算法就达不到我们的目的了。

Q2. How is the above solution a greedy algorithm?

上述代码中的if 条件-if(i+A[i]&gt;=last)last=i; 使算法变得贪婪,因为我们会尽可能地进行最大跳转 (i+A[i]&gt;=last)。

here 提供的分析可能会对您有所帮助。


编辑

让我们谈谈你提到的输入 - [3,3,1,0,4]。

  • 当i=0 时,算法检查我们可以从i=0 达到的最大索引是多少。
  • 然后我们将移动到下一个索引并检查从i=1 可以达到的最大索引是多少。由于我们移动到i=1,因此可以保证我们可以从索引 0 到索引 1(与跳转大小无关)。

请注意,在这个问题中,我们不关心是否应该在i=0 进行大小为 3 的跳跃,尽管我们知道这无助于我们到达终点。我们关心的是我们是否可以通过跳跃到达终点或超越终点索引。

【讨论】:

  • 假设输入是:[3,3,1,0,4]。您的陈述不是“贪婪算法将选择最佳选择(采取最大跳跃)并最终查看我们是否可以到达终点。”你的陈述不掩盖输入吗?因为,假设我们从左边开始,当i=0时,我们需要采取最大跳跃(3),这其实是不对的?根据我的理解,我们只需要跳转1然后继续。
  • 您是绝对正确的,但您需要换一种方式思考,因为我们并不是试图在每一步中找到确切的跳跃大小。贪心算法会看到,i=0 时选择 3 会将我们带到i=1。然后我们将继续检查我们是否可以达到或超过结束指数。您可以查看我附加到我的答案的链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-16
  • 1970-01-01
  • 2023-04-02
  • 2020-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多