来源:牛客网
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。 思路:一个数字出现次数超过了一半,可以证明,若每次从数组中取出两个不同的数,剩下的数组中,该数字依旧超过了一半。 因此设计如下算法: 定义一个栈,遍历数组a[] 若栈空,将a[i]入栈; 若不空,比较top元素与a[i], 若相等,a[i]入栈,i++; 若不等,top元素出栈,i++; 最后栈里剩下都是同一个元素,且是超过一半的数字。 其实不用栈可以,代码如下:1 public static int MoreThanHalfNum_Solution(int [] array) {
2 int candidate=0, times=0;
3 for(int i=0; i<array.length; ++i){
4 if(0==times) {
5 candidate=array[i];
6 times++;
7 } else{
8 if(candidate==array[i]) times++;
9 else times--;
10 }
11 }
12
13 return candidate;
14 }
然而提交的时候却并没有AC,原因是漏了一个条件:若不存在则返回0。
测试用例:
[1,2,3,2,4,2,5,2,3]
对应输出应该为:
0
你的输出为:
3
因此需要加一个函数判断数组中是否存在出现次数超过一半的数字: 最终完整代码如下,数组遍历了两次,复杂度O(2n). 加了一行检测输入数组是否空。1 public class Solution {
2 public int MoreThanHalfNum_Solution(int [] array) {
3 if(array==null) return 0;
4 int candidate=0, times=0;
5 for(int i=0; i<array.length; ++i){
6 if(0==times) {
7 candidate=array[i];
8 times++;
9 } else{
10 if(candidate==array[i]) times++;
11 else times--;
12 }
13 }
14 if(checkIfExits(array, candidate)) return candidate;
15 else return 0;
16 }
17
18 public boolean checkIfExits(int[] a, int c){
19 int times=0;
20 for(int i=0; i<a.length; ++i){
21 if(c==a[i]) times++;
22 }
23 if(times>a.length/2) return true;
24 else return false;
25 }
26 }