一日一算法题,贪心算法(腾讯真题)

年中真的挺多人参加面试的,最近又收集到了不少算法相关的面试题。不过我觉得国内的算法面试题相对于国外的,还是有点差距吧。今天我们来看一看腾讯一道题目。

原题:

给你一个数n,有3种操作:

1.这个数加1

2.这个数减1

3.如果这个数是2的倍数,那么这个数除以2

问给你一个数n,问最少经过多少步,可以把这个数变成1

思考:

这个题目,与之前我们分析过的 《一天一算法题,将复杂问题进行分解!》那个优先用除法的子问题有点相似。唯一不同的是,这个题目同时可以用加减法。

那么多了这么一个点有什么不同呢?

举个栗子15,如果我们只用减法跟除法,那么这个题目的答案是:

15 - 1 = 14

14 / 2 = 7

7 - 1 = 6

6 / 2 = 3

3 - 1 = 2

2 / 2 = 1

总共需要6次操作

但是如果使用了加减法,就不需要这么多了。

15 + 1 = 16

16 / 2 = 8

8 / 2 = 4

4 / 2 = 2

2 / 2 = 1

这个只需要5次

是不是使用加法的策略更优呢?好像也不是,我们很容易就能举出反例,例如9.使用减除最少,需要4次。也就是有的数需要优先用加法,有的需要优先考虑减法。

想到这里,很多人其实就萌逼了,到底要使用加法还是减法呢?我们需要来看到问题的本质。

既然是除以2,那么非常大的可能是跟二进制有关系!我们如果用二进制来表示这个题目,那么这个题目可以等价于一个k位的二进制数,把它变成1.

我们来看一看三种操作,我们先看看除法!

一日一算法题,贪心算法(腾讯真题)除以2其实就是把末位0干掉!

这里我们隆重的迎接我们今天的主角,贪心算法。其实叫做贪心策略更加合适,贪心其实更像是一种思想。

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。

既然要把变成有且仅有一个1,除2可以立马少掉1位,根据贪心思想,我们尽可能的使用/2操作。

在贪心策略的指引下,我们如果末位是0,就立马干掉!

接下来我们来看看,减1操作。

一日一算法题,贪心算法(腾讯真题)我们发现,-1操作只有2种可能,第一种不但没有增加0的个数,反而减少了,只有0才能够进行除以2.而第二种方法可以增加一个0.根据贪心的策略,我们选择了更优的第二种,只有当末位为1的时候,才考虑进行减1.

我们来看看+1的操作:

一日一算法题,贪心算法(腾讯真题)如 果最后一位是0,不但没有增加0的个数反而适得其反。这个我们不用。我们再看看第二种情况,虽然可以增加0的个数,但却把所有的增加了1位。如果进行这个 操作,我们需要进行多2个步骤。1是加1,2是需要多除一次。(本来除3次,现在变成4次了)。但是,我们减少了3次-1的次数。于是我们得出一个结论, 如果末尾有超过连续3个1,那么我们可以选择+1.

总结:

至此,我们把这个题目的策略整理出来了。

我们有如下的策略

1. 如果末尾是0,那么直接除以2.

2.如果末尾是1,并且末尾连续1的个数小于3,那么优先选择剪发,然后开始除法。

3.如果末尾超过连续3个1,那么先使用加法,再使用除法。

4,我们把n转成2进制,然后从低位开始,按上面的策略操作。

老规矩,如果是面试真题,不提供源代码。

贪 心算法,其实我觉得叫思想更为正确,现在国内的很多贪心的面试题,其实都要求你得到正确解。这点我觉得跟国外的面试差距很大 ,谷歌的贪心题目,经常是没有完美的贪心方案,但是,面试官会让你举出你使用的贪心策略的反例。这个更能考验面试者的思维,同时这种情况现实中更多。

原创不易,欢迎大家关注我的头条号,也可以关注我的微信公众号(ddpcyh),后续会提供算法学习资料,一起来学习算法吧。

个人资料
hadoop迷
等级:6
文章:30篇
访问:2.2w
排名: 13
推荐圈子
上一篇: 谷歌的二分面试题(一日一算法题)
下一篇: Giraph-Eclipse安装-源码调试
猜你感兴趣的圈子:
每日一算法
标签: 贪心、除法、除以、末位、末尾、面试题
隐藏