求顶点v的度算法c语言,来见识一下贪心算法:Jump Game

有的同学会觉得的这个问题不好解决,原因就在于给定一个位置,假设这个位置上的数字是6,也就是说从这个位置开始,你可以选择跳一步、也可以是两部、三步、四步、五步或者六步,有这么多可能性你该跳多少步呢?

c9890742f94cb70bf05ed279ece103d2.png

顺着这个思路走下去的话,那么你只能把每一种可能性都试一遍了,还是以上图为例,从该位置开始有6种可能性,那么我们依次遍历每一个种可能的选择,各种遍历方式的组合数是非常巨大的,因此这种思路不可行。

正着走不通,那么让我们反向思考一下。

这个问题的反向思考是基于这样的一种观察,也就是,如果数组中有某个位置无法到达,那么我们就无法跳到最后一个节点,这是显而易见的,因为如果能跳到最后一个节点的话,那么我们必然要经过数组中的所有节点。换句话说就是如果我们能跳到最后一个节点的话,那么我们必然能跳到数组中任意一个节点。

有了这样的分析实际上就非常简单了,我们之前在很多个算法题目中都说过,有时解决一个通用的问题比解决一个具体的问题思考起来要简单,在这里具体的那个问题就是判断是否能跳到最后一个节点,而通用的那个问题就是能否跳到数组中任意一个节点,在这里我们就来思考在给定条件下能否跳到数组中任意一个节点,如果可以的话那么我们的函数应该返回true,否则返回false。

我们还是从最简单的情况一步一步来分析。

对于数组[2,3,1,1,4],首先我们会被放到2这个位置,接下来我们判断能否跳到3?

那么从2能否跳到3呢?答案很简单,当然是可以的,为什么呢?因为从2跳到3只需要一步,而第一个位置我们最远可以跳两步,因此我们可以跳到3:

df937f849ce53e55cf484e460690d4b9.png

这样我们来到了数组中的第二个数,也就是3,接下来就比较有意思了。

此时我们的任务就是判断从节点3能否跳到节点1,那么可以跳到吗?

答案是显而易见的,当然可以跳到,为什么呢?因为在当前位置上我们可以最多跳3步,而从3跳到1只需要一步,那么如果当前位置上的数不是3而是0呢?

2b808595f26c30279745e0cb1ddf7a8d.png

那么我们还能跳到1吗?答案是可以的,因为虽然我们不能从0跳到1,但是可以从2直接跳到1,从这两种情况下你能得到什么启示?

以上两种情况给我的启示就是,能否跳到当前位置取决于当前位置之前的所有位置上的步数,有的同学会说这不是废话吗,是的,这是一句废话,这句废话会引导我们进一步思考,那就是这到底是怎么的取决呢?

让我们再次回到数组[2,3,1,1,4]的例子,从2可以跳到1,从3也可以跳到1,但是2最多可以跳到1,超出0步,而3最多可以跳到4,超过了1这个位置两步,如图所示:

f45baed3606b086cb2020840d0c3930c.png

那么这张图告诉我们什么呢?是什么样的条件决定了能不能跳到当前位置呢?

如果我们能够保证从在此位置之前任意一个位置(前提是我们可以从数组开头跳到这些位置)起跳能跳到或跳过当前位置,那么我们就可以确定可以从数组开头跳到当前位置。

因此我们需要记下在该位置之前的所有位置起跳能超过当前位置的最大步数,只要这个最大步数经过每一个位置时都大于0,那么我们就能确定一定可以从开头跳到最后。而这本质上就是贪心算法,贪心算法的思想是我们总是在当前就做出最好的选择,而不是从整体上加以考虑。

上述结论比较拗口,举个例子你就明白啦,我们还是以[2,3,1,1,4]为例来说明。

最开始我们在位置2上,此时我们可以认为从位置2起跳可以超过当前位置2步,因此最大步数是2,我们将这个最大步数记为max_step,也就是能超过当前位置的最大步数,我们的任务就是要保证在每个位置max_step都要大于0,这样我们就一定能到达最后,如图所示:

2b7508227b58904b9a45bef703332b31.png

接下来是位置3,此时我们需要将max_step减1,此时max_step为1是大于0的,因为我们向前走了一步。我们可以选出从3开始起跳,从而能超过3这个位置3步,也可以选择使用max_step的起跳位置,也就是2,因此这个最大步数就是max_step = max(3, max_step-1),这时max_step就是3。

bf8472d962d8d3d1b384b05ff2354da6.png

接下来是位置1,同样将max_step减1,此时max_step为2是大于0的,在这里我们可以选择从1这个位置起跳,也可以选择使用max_step的起跳位置,也就是位置3,这样我们又得到了能新的max_step,即max_step = max(1, max_step-1)。

4c491ee7113f5d16a8a64bd1e83ac825.png

重复上述过程直到数组最后,如果中途发现max_step已经等于0了,那么说明我们无法从数组开头跳到最后。

基于上述分析,代码就很简单了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值