数组中出现次数超过一半的数字

剑指 offer

题目描述

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

思路1:

如果出现一个数字出现的次数超过数组长度的一半那么这个数是数组的中位数,使用利用快排,找到数组中的中位数,先选取一个中枢点,一次排序后查看中枢点的位置如果比 array.length/2 大即 中位数在中枢点的左边,中枢点的右边就不用再排序了,如果比 array.length/2 小即 中位数在中枢点的右边,中枢点的左边就不用在排序了,如果相等再循环变量检查这个数是否超过数组长度的一半。

public class Solution {
 public int MoreThanHalfNum_Solution(int [] array) {
    int middle=array.length>>1;
    int start=0;
    int end=array.length-1;
    int index=partition(array,start,end);
    while(index!=middle){
        if(index > middle){
            end=index-1;

        }else if(index < middle){javascript:void(0);
            start=index+1;
        }
        index= partition(array,start,end);
    }
    int result=array[index];
    if(check(array,result)){
        return result;
    }
    return 0;
}

public boolean check(int[] data,int result){
    int time=0;
    for(int i=0;i<data.length;i++){
        if(data[i]==result){
            time++;
        }
    }
    if(time*2<=data.length){
        return false;
    }
    return true;
}
//选择中枢值
public int middle3(int[] data, int left, int right) {
    int center = (left + right) / 2;
    if (data[left] > data[right]) {
        swap(data, left, right);
    }
    if (data[center] < data[left]) {
        swap(data, center, left);
    }
    if (data[center] > data[right]) {
        swap(data, center, right);
    }
    swap(data,center,right-1);
    return data[right-1];
}

public int partition(int[] data,int left,int right){
	//相等就不用换了  注意
    if(left==right){
        return  left;
    }
    int middleValue=middle3(data,left,right);
    int low=left,high=right;
    while(true){
        while(data[++low]<=middleValue && low<high){
        }
        while(data[--high]>=middleValue && high >low){
        }
        if(low<high){
            swap(data,low,high);
        }else{
            break;
        }
    }
    swap(data,low,right-1);
    return  low;
}

public void swap(int[] data, int indexA, int indexB) {
    if (data == null || data.length <= 0 || indexA < 0 || indexA >= data.length || indexB < 0 || indexB >= data.length) {
        return;
    }
    int temp = data[indexA];
    data[indexA] = data[indexB];
    data[indexB] = temp;
}

}

思路2:

先标记数组中的第一个数字,记下出现次数为 1,遍历数组 如果出现相同的数字次数加 1,如果不相同次数减 1,如果减到次数为 0 的时候,将标记值换成数组中刚出现的数组,出现次数加 1,最后遍历完后再检查标记的数出现的次数是否超过数组长度的一半。

public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
    if(array==null || array.length==0){
        return 0;
    }
    int result = array[0];
    int time = 1;
    for(int i=1;i<array.length;i++){
        if(result==array[i]){
            time++;
        }else{
            time--;
        }
        if(time==0){
            result = array[i];
            time = 1;
        }
    }
    if(check(array,result)){
        return result;
    }
    return 0;
}

public boolean check(int [] array,int result){
    int time=0;
    for(int i=0;i<array.length;i++){
        if(array[i]==result){
            time++;
        }
    }
    if(time*2<= array.length){
        return false;
    }
    return true;
}
}
posted @ 2018-07-31 13:44  罗贱人  阅读(197)  评论(0编辑  收藏  举报