剑指offer_029
剑指offer系列:x寻找数组中出现次数超过一半的数
剑指offer 029题
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
HashMap的方式
利用空间复杂度O(n)的HashMap作为辅助空间
|
|
在用这种方法实现的时候,设计到了python dictionary的一些特点了,在这道题的背景下,我们期望找出HashMap这个dict中value最大项所对应的key值,这里我用了一个for循环来解决,这似乎不够pythonic,是否有更加方便的方式呢?其实问题可以重新定义一下,python的dict数据类型按照value值的大小进行排序.这里用到了python的内建函数sorted,下面举例子来说明一下:
|
|
{'a': 3, 'c': 2, 'b': 1}
|
|
[('b', 1), ('c', 2), ('a', 3)]
|
|
[('a', 3), ('c', 2), ('b', 1)]
同理,如果按照key进行排序的话可以写作,reverse这个参数决定是顺序还是逆序,同时需要注意的是,sorted会生成一个新的dict,而原始的example_dict中的顺序没有被改变.
|
|
[('a', 3), ('b', 1), ('c', 2)]
数组特点查找
剑指上的第二种解法,定义了两个变量num和count,从头在数组中选取一个数,令其为num,并置count为1,开始遍历数组,如果遇到的新项与num相等则count+1,否则count-1,若count已经是0的情况下,则num换为当前的数,count重新置为0.直到遍历完成,若count此时大于0,则num即为所求结果.但是在这里需要进一步检查,是否num是在数据中超过一半,因此还需要再进行一次遍历(这里还应该有一次遍历能够解决的方案么?),代码如下
|
|
细心读代码的同学应该能够看到这里也用了一个python的trick在之前的博客当中也有提到的enumerate,因为我们令num为numbers[0],此时再进行遍历的时候我们期望从numbers[1]开始向后遍历,如果采用range的形式也未尝不可,可以写作for iteration in range(1, len(numbers)-1),然后通过numbers[iteration]来取值.显然相比于上面的实现方式要显得繁琐,代码的可阅读性也不够好.因此当你想要从某个index遍历list的时候不要忘记enumerate这个实现方式.
参考链接: