题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
解题思路—基于题目特点:如果数组中有一个数字出现的次数超过数组长度的一半,那么数组排序后中间的数就一定是这个数字。 所以数组可以先进行快排,取中间的数,然后确认中间数在数组中第一次出现的位置start,若数组[start+(array.length-1)/2]的值与中间数相等,即可说明中间数个数大于数组长度的一半。但是,代码中使用了快排,所以时间复杂度为O(nlogn),不太推荐!
解题思路—哈希表:推荐使用哈希表! 希表中表头为数组中出现过的数字,存储的值为数字出现过的次数,然后判断次数有没有大于数组长度一半即可。
剑指Offer中的解法:
解题思路—基于快排思想:这是基于快速排序的进阶版!与基于题目特点的核心想法一样,但是复杂度更低。只需要找到序列中最中间的数即可,不需要所有数字都进行排序。
解题思路—基于数组特点:如果有符合条件的数字,则它出现的次数比其他所有数字出现的次数和还要多。 在遍历数组时保存两个值:一是数组中一个数字,一是次数。遍历下一个数字时,若它与之前保存的数字相同,则次数加1,否则次数减1;若次数为0,则保存下一个数字,并将次数置为1。遍历结束后,所保存的数字即为所求。
Java解题—基于题目特点
import java.util.Arrays;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array.length==0 || array==null)
return 0;
Arrays.sort(array);
int num = array[(array.length-1)/2];
int start = 0;
while(array[start]!=num)
start++;
if(array[start+(array.length-1)/2]==num)
return num;
else
return 0;
}
}
Java解题—哈希表
import java.util.HashMap;
public class Solution {
public int MoreThanHalfNum_Solution(int[] array) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < array.length; i++) {
if (map.get(array[i]) == null)
map.put(array[i], 0);
map.put(array[i], map.get(array[i]) + 1);
if (map.get(array[i]) > array.length / 2) {
return (array[i]);
}
}
return 0;
}
}
Java解题—基于快排思想
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array.length<=0)
return 0;
int start = 0;
int length = array.length;
int end = length-1;
int middle = length>>1;
int index = Partition(array,start,end);
while(index!=middle)
if(index>middle){
end = index-1;
index = Partition(array,start,end);
}
else{
start = index+1;
index = Partition(array,start,end);
}
int result = array[middle];
int times = 0;
for(int i=0;i<length;i++)
if(array[i] == result)
times++;
if(times*2<=length)
return 0;
else
return result;
}
public int Partition(int[] array,int start,int end){
int flag = (array[start]+array[end])/2;
while(start<end){
while(array[end]>flag && start<end)
end--;
swap(array,start,end);
while(array[start]<=flag && start<end)
start++;
swap(array,start,end);
}
return start;
}
public void swap(int[] array,int num1,int num2){
int temp =array[num1];
array[num1] =array[num2];
array[num2] =temp;
}
}
Java解题—基于数组特点
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array.length<=0)
return 0;
int result = array[0];
int times = 1;
for(int i=1;i<array.length;i++){
if(times==0){
result = array[i];
times =1;
}else if(array[i]==result)
times++;
else
times--;
}
int time = 0;
for(int i=0;i<array.length;++i){
if(array[i] == result)
time++;
}
if(time*2<=array.length){
System.out.println(time);
return 0;
}else
return result;
}
}