题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字,eg,{1,2,3,2,2,2,5,4,2},输出为2
分析:如果该数组是排序的,则所求数字肯定位于数组中间
思路:可对数组进行排序,判断中间的数出现的次数;可以用HashMap来实现,容易想到,代码也比较简单
剑指offer:1.类似快排,先在数组中选择随机一个数字,然后调整数组中数字的顺序,使得比选中的数字小的都排在它的左边,大的都在右边,如果这个选中的数字刚好下标是n/2,则这个数字就是数组的中位数,如果大于n/2,则中位数在它的左边,如果小于n/2,中位数位于右边;2.数组特点,遍历数组时保存两个值,一个是数字,一个是次数,当遍历下一个数字的时候,如果下一个数字和我们之前保存的数字相同则次数加一,不同则次数减一,如果次数为零则保存下一个数字,由于要找的数字出现的次数比其他所有数字出现的次数还要多,那么要找的数字肯定是最后一次把次数设为1时对应的数字
import java.util.*;
public class wr29ArrayMoreHalf {
// 先排序,然后进行判断,若存在满足要求的数,数组中位数一定是该数
public static int moreThanHalfNum(int []array){
if(array==null || array.length==0){
return 0;
}
Arrays.sort(array);
int count=0;
int result=array[array.length/2];
for(int i=0;i<array.length;i++){
if(array[i]==result){
count++;
}
}
if(count>array.length/2){
return result;
}
else{
return 0;
}
}
// 利用HashMap思想
public static int moreThanHalfNum2(int []array){
if(array==null || array.length==0){
return 0;
}
HashMap<Integer,Integer> hashmap=new HashMap<>();
for(int i=0;i<array.length;i++){
int count=0;
if(!hashmap.containsKey(array[i])){
hashmap.put(array[i], 1);
}else{
count=hashmap.get(array[i])+1;
hashmap.put(array[i], count);
}
if(count>array.length/2){
return array[i];
}
}
return 0;
}
// 遍历数组时保存两个值,一个是数组中的数字,一个是次数
public static int moreThanHalfNum3(int []array){
if(array==null || array.length==0){
return 0;
}
int len=array.length;
int times=1;
int res=array[0];
// 遍历下一个数字时,若与之前保存的数字相同,则次数加1,否则次数减1
for(int i=1;i<len;i++){
if(times==0){// 若次数为0,则保存下一个数字,并将次数置为1
res=array[i];
times=1;
}
else if(array[i]==res){
times++;
}
else{
times--;
}
}
// 遍历结束,所保存的数字即为所求,再判断它是否符合条件
times=0;
for(int num:array){
if(num==res){
times++;
}
}
if(times>len/2){
return res;
}
else{
return 0;
}
}
// 剑指offer快排思路,参考牛客上大神代码
public static int solution(int []array){
if(array==null || array.length==0){
return 0;
}
int length=array.length;
int middle=length>>1;
int start=0;
int end=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];
if(!checkMoreThanHalf(array,result)){
result=0;
}
return result;
}
public static int partition(int []array,int left,int right){
int result=array[left];
if(left>right){
return -1;
}
while(left<right){
while(left<right && array[right]>=result){
right--;
}
array[left]=array[right];
while(left<right && array[left]<result){
left++;
}
array[right]=array[left];
}
array[left]=result;
return left;
}
public static boolean checkMoreThanHalf(int []array,int number){
int times=0;
for(int i=0;i<array.length;i++){
if(array[i]==number){
times++;
}
}
boolean flag=false;
if(times>array.length/2){
flag=true;
}
return flag;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int []array={1,2,3,2,2,2,5,4,2};
System.out.println(moreThanHalfNum(array));
System.out.println(moreThanHalfNum2(array));
System.out.println(moreThanHalfNum3(array));
System.out.println(solution(array));
}
}