【Offer】[39] 【数组中出现次数超过一半的数字】

时间:2023-03-09 19:15:14
【Offer】[39] 【数组中出现次数超过一半的数字】

题目描述

  数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。

牛客网刷题地址

思路分析

  有两种思路:

  1. 快速排序的思想:数字次数超过一半,可以说明排序之后中间的数字一定是所求的数字,即统计学上的中位数,利用partition函数求得某一下标,如果改下标正好为n/2,则该数字为所求数字,需要检查该数字在数组中出现的次数;如果 < n/2,则中位数位于改下标右边,如果 > n/2 则位于左边;
  2. 统计数字出现的次数,首先先保存一个哨兵数字和一个计数器,遍历数组后面的数字,遇到与该数字相同的则计数器+1,遇到不同的-1,如果计数器减为0时,就重新保存一个数字,重新开始从1开始计数。到最后计数器如果>0,判断该数字出现次数。

测试用例

  1. 功能测试:输入的数组中存在一个出现次数超过数组长度一半的数字:输入的数组中不存在一个出现次数超过数组长度一半的数字。
  2. 特殊输入测试:输入的数组中只有一个数字;输入nullptr 指针。

Java代码

public class Offer39 {
public static void main(String[] args) {
test1();
test2();
test3(); } public static int MoreThanHalfNum_Solution(int[] array) {
return Solution1(array);
} /**
* partition方法
*
* @param array
* @return
*/
private static int Solution1(int[] array) {
if (array == null || array.length == 0) {
return 0;
}
int middle = array.length >> 1;
int low = 0;
int high = array.length - 1;
int index = partition(array, low, high);
while (index != middle) {
if (index < middle) {
low = index + 1;
index = partition(array, low, high);
} else {
high = index - 1;
index = partition(array, low, high);
}
} int result = array[middle];
int times = 0;
for (int i = 0; i < array.length; i++) {
if (result == array[i]) {
times++;
}
} if (times * 2 > array.length) {
return result;
}
return 0;
} private static int partition(int[] array, int low, int high) {
int privot = array[low];
while(low<high){
while(low<high && array[high]>=privot) high--;
array[low] = array[high];
while(low<high && array[low]<=privot) low++;
array[high] = array[low];
}
array[low] = privot;
return low;
} private static int Solution2(int[] array) {
if (array == null || array.length == 0) {
return 0;
}
int count = 1;
int flagNum = array[0];
for (int i = 1; i < array.length; i++) {
if (count == 0) {
flagNum = array[i];
count = 1;
} else if (array[i] == flagNum) {
count++;
} else {
count--;
}
}
if (count > 0) {
int times = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == flagNum) {
times++;
}
}
if (times * 2 > array.length) {
return flagNum;
}
}
return 0;
} private static void test1() {
int[] array = { 1, 2, 3, 2, 2, 2, 5, 4, 2 };
int result = MoreThanHalfNum_Solution(array);
System.out.println(result);
} private static void test2() {
int[] array = { 1 };
int result = MoreThanHalfNum_Solution(array);
System.out.println(result);
} private static void test3() {
int[] array = {};
int result = MoreThanHalfNum_Solution(array);
System.out.println(result);
}
}

代码链接

剑指Offer代码-Java