版权声明:本博客可任意转载,不用通知 https://blog.csdn.net/hbkzhu13579/article/details/83934374
链接
牛客: 数组中出现次数超过一半的数字
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路
这个题目的方法很多种,暴力就不讲了,效率比较低。时间复杂度是O(N^2)
1、第一种也是比较容易想到的有建立一个哈希表,记录每个结点出现的次数,再找看是否有超过一半的数字,时间复杂度是O(n),不过需要耗费一定的空间,空间复杂度是O(n)。
2、第二种是进行排序,因为一旦一个数字在数组中长度超过一半,说明排序过后的中位数一定是这个数字,我们只要排好序,然后再计算中位数出现的次数是否超过一半,时间复杂度是0(nlogn) ,但是不需要空间。
3、第三种我们可以尝试找一种时间复杂度O(n) 而又不怎么花空间复杂度的算法,实现很巧妙。这个算法的思想是什么呢?参考数组中出现次数超过一半的数字这篇文章中指出的:
思想是:如果一个数出现的次数超过数组一半的长度,那么就是说出现的次数比其他所有数字出现的次数还要多。因此我们可以考虑保存2个值,一个是数组中的一个数,一个是数的次数。当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1,如果不同则次数减1。如果次数为0了这保存当前遍历到的数,并把次数设为1。遍历完整个数组之后,返回当前保存的数字,即是我们要找的数字。
代码
import java.util.Arrays;
public class Solution {
public int MoreThanHalfNum_Solution(int[] array) {
int length = array.length;
if (length == 0)
return 0;
int result = array[0];
int times = 1;
for (int i = 1; i < length; i++) {
if (times == 0) {
result = array[i];
times = 1;
}
if (result == array[i]) {
times++;
} else {
times--;
}
}
int count = 0;
for (int i = 0; i < length; i++) {
if (array[i] == result) {
count++;
}
}
if (2 * count <= length) {
result = 0;
}
return result;
}
}