思路:
数组中有一个数字出现的次数超过数组长度的一半,也就是说它出现的次数比其他所有数字出现次数的和还要多。
因此我们可以考虑在遍历数组的时候保存两个值: 一个是数组中的一个数字, 一个是次数。当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1:如果下一个数字和我们之前保存的数字,不同,则次数减1 。如果减1之后,此时次数为零,我们需要保存下一个数字,并把次数设为1 。由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么要找的数字肯定是最后一次次数设置为1的对应的数字。
java具体实现:
/**
* 找出数组中出现次数超过一半的数字
* 算法实现思想,定义两个变量num,count,分别记录数字遍历中的数字,和计数器变量。
* 将第一个元素取出来赋值给num,count初始值为1,然后遍历数组,依次和前面的num比较,
* 如果相同,则count加1,如果不同则count减1,如果减去之后,count为0,则将当前数组赋值给num 然后count重置为1
*
*
*/
public class GetOffer {
public static void main(String[] args) {
int arr1[] = { 1, 2, 3, 2, 2, 2, 5, 4, 2 };
int result1 = getNum(arr1);
System.out.println(result1);
int arr2[] = { 2, 2, 2, 2, 2, 1, 3, 4, 5 };
int result2 = getNum(arr2);
System.out.println(result2);
}
private static int getNum(int[] arr) {
// 健壮性
if (arr == null && arr.length < 1) {
return -1;
}
int num = arr[0];
int count = 1;
// 遍历比较
for (int i = 1; i < arr.length; i++) {
if (num == arr[i]) {
++count;
} else {
count--;
if (count == 0) {
num = arr[i];
count = 1;
}
}
}
// 判断num是不是目标数字
count = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == num) {
count++;
}
}
if (count >= arr.length / 2) {
return num;
}
return -1;
}
}