本文为剑指 offer 系列第二十九篇。
主要知识点为数组,找出数组中出现次数超过一半的数字,两种方式解决这个问题。map计数和两军对决。
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
解题思路
思路1
找个map来存储每个字符出现的次数,然后遍历一遍map找到次数大于一半的数字即可。
思路2
可以想象成战场厮杀,要找的数字为红方,其他为蓝方,红蓝双方士兵实力相等,一换一。由于要找的数字出现次数超过一半,所以厮杀结束之后剩下的必然是我们要找的数字。
回到本题目中来,我们按照数组顺序来依次上场,保存当前场上的序号和次数,若下一个字符和当前场上字符一致,则出现次数+1,若不一致,则-1,若次数减为0,则场上的人由下一次人来替换,出现次数变为1.等到所有的数据都遍历结束,则剩下的就是可能是结果的数据,然后计算该数据在整个数组中出现的次数,判断是否符合出现次数超过一般的条件,若符合,返回target,否则返回0。
以a = {1,2,3,2,2,2,5,4,2}为例。
- 索引为0时。保存target = 1,time = 1;
- 索引为1时,由于a[1]!= target, 所以原来target出现的次数要减1,保存target = 1, time = 0;
- 索引为2时,由于time = 0,所以更新target = 3,time = 1;
- 索引为3时,a[3] = 2与target不一致,所以更新target = 3,time = 0;
- 索引为4时,target = 2,time = 1;
- 索引为5时,target = 2,time = 2;
- 索引为6时,target = 2,time = 1;
- 索引为7时,target = 2,time = 0;
- 索引为8时,target = 2,time = 1;
所以2是一个可能的解,然后在数组中计算target 2出现次数为5,超过数组长度的一半,所以返回target2.
解题代码
思路1代码
1 | class Solution { |
时间复杂度为O(n),空间复杂度为O(n)
思路2代码
1 | class Solution { |
时间复杂度为O(n),空间复杂度为O(1)
以上,本题结束!