题目:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2;
思路:
方法一:
将数组排序,取中位数,查看其出现次数。若大于数组长度的一半则输出.由于需要排序,因此时间复杂度为O(nlogn)
方法二:
遍历数字的时候保存两个值,一个是数字的值,另一个是其出现的次数。当我们遍历到一个数字的时候,如果他跟我们之前保存的数字一致,则次数加一,否则次数减一。当次数为0时,保存下一个数字并把次数设为一,由于我们要找的数字占所有次数一半还要多,所以肯定是最后留下的值。当遍历完成时,遍历原数组数一下该数出现的次数,若大于数组大小一半即为要求数字。该方法时间复杂度为O(n)
方法三:
一次快排partition我们随机选择一个数字,大于这个数字的在这个数字右边,小于这个数字的在这个数字左边。最后返回该数字序号index,若index小于n/2,则继续在数组右边查找。若大于,则在左边找。当index等于数组长度一半时,返回对应数字即可。该方法时间复杂度同样为O(n)。
import java.lang.reflect.Array;
import java.util.Arrays;
public class Solution {
//方法一:
// 将数组排序,取中位数,查看其出现次数
public static int MoreThanHalfNumber(int[] array)
{
if (array.length==0||array==null)
return -1;
Arrays.sort(array);
int middle = array.length/2;
int count = 0;
for (int i = 0; i <array.length ; i++) {
if (array[i]==middle)
count++;
}
if (count>array.length/2)
return middle;
else return -1;
}
// 方法二:
// 遍历数字的时候保存两个值,一个是数字的值,另一个是其出现的次数
// 当我们遍历到一个数字的时候,如果他跟我们之前保存的数字一致,则次数加一,否则次数减一。
// 当次数为0时,保存下一个数字并把次数设为一,由于我们要找的数字占所有次数一半还要多,所以可定是最后留下的值。
// 当遍历完成时,遍历原数组数一下该数出现的次数,若大于数组大小一半即为要求数字
public static int MoreThanHalf(int[] array)
{
if (array.length==0||array==null)
return -1;
if (array.length==2)
{
if (array[0]==array[1])
return array[0];
else return -1;
}
int num = array[0];
int count =1;
for (int i = 1; i <array.length ; i++) {
if (array[i]==num)
count++;
if (array[i]!=num)
count--;
if (count==0){
if (i==array.length-1)
return -1;
else {
num = array[i+1];
count++;
}
}
}
for (int i = 0; i <array.length ; i++) {
if (array[i]==num)
count++;
}
if (count>array.length/2)
return num;
else return -1;
}
// 方法三:一次快排patition
// 我们随机选择一个数字,大于这个数字的在这个数字右边,小于这个数字的在这个数字左边。最后返回该数字序号index,
// 若index小于n/2,则继续在数组右边查找
// 若大于,则在左边找
public static int MoreThanHalfNum(int[] array)
{
if (array==null||array.length==0)
return -1;
if (array.length==2)
{
if (array[0]==array[1])
return array[0];
else return -1;
}
partitionArr(array,0,array.length-1);
return array[array.length/2];
}
public static void partitionArr(int[] array,int left,int right)
{
int index = partition(array,left,right);
if (index==array.length/2)
return ;
else
if (index<array.length/2)
partitionArr(array,index+1,right);
else
partitionArr(array,left,index-1);
}
public static int partition(int[] array,int left,int right)
{
int p=left, small = left-1, big = right,pivot = array[right];
while (p<big)
{
if (array[p]<=pivot)
swap(array,++small,p++);
else swap(array,--big,p);
}
swap(array,p,right);
return p;
}
public static void swap(int[] array,int i,int j)
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}