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

来源:互联网 发布:描述性数据分析 编辑:程序博客网 时间:2024/06/01 08:17

题目

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

解题

方法一:快排思想
数组中某个元素出现次数超过数组长度的一半,则数组排序后这个数一定是中位数
但是当不存在这样的数时候就不是中位数了。
用快排的思想解决
只需要找到中间位置的那个数就好了
更进一步的说就是找到中间位置的下标
利用快排每次对数组进行划分,当划分位置在中间位置时候,停止划分
下面对中间位置的这个数检测出现次数就好了

public class Solution {    public int MoreThanHalfNum_Solution(int [] array) {        if(array == null || array.length == 0)            return 0;        int left = 0;        int right = array.length - 1;        int middle = (right+1)/2;        int index = partition(array,left,right);        while(middle != index){            if(index >middle){                right = index-1;                index = partition(array,left,right);            }else{                left = index+1;                index = partition(array,left,right);            }        }        int number = array[middle];         if(check(array,number,middle)){             return number;         }else             return 0;    }    public boolean check(int[] array,int val,int middle){        int count = 0;        int i = middle;        int j = i+1;        while(i>=0 && array[i] == val){            i--;            count++;        }        while(j<array.length && array[j] == val){            j++;            count++;        }        return count*2>=array.length;    }    // 划分位置    public int partition(int [] A,int low ,int high){        int x = A[high];        int i = low - 1;        for( int j = low;j<= high - 1;j++){            if( A[j] <= x){                i = i + 1;                swap(A,i,j);            }        }        i = i + 1;        swap(A,i,high);        return i;    }    public void swap(int[] array,int i,int j){        int tmp = array[i];        array[i] = array[j];        array[j] = tmp;    }}   

方法二:找到出现最多的数

遍历数组保存两个值:一个是数字中的一个数,一个是次数。当遍历到下一个数的时候,如果下一个数和之前保存的数相同,则次数加一;如果下一个数与之前保存的数不同,则次数减1.如果次数为0,保存下一个数,并设置次数为1.
由于我们找到的数字出现的次数比其他所有出现的次数之和还要多,那么要找到的数字肯定是最后一次把次数设置为1对应的数字。

public class Solution {    public int MoreThanHalfNum_Solution(int [] A) {        if(A == null || A.length == 0)            return 0;        int num = A[0];        int times = 1;        for(int i = 1;i< A.length ;i++){            if(A[i] == num){ // 相等次数 + 1                times++;            }else{ // 不相等                if( times>0){ // 次数 -1                     times--;                }else{                    num = A[i]; // 更新比较数 和 次数                    times = 1;                }            }        }        times = 0;        for(int i = 0;i<A.length;i++){            if(A[i] == num)                times++;        }        if(times> A.length/2)            return num;        return 0;    }}

方法三:HashMap
统计次数

import java.util.*;public class Solution {    public int MoreThanHalfNum_Solution(int [] A) {        if(A == null || A.length == 0)            return 0;        if(A.length ==1)            return A[0];        HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();        for(int i = 0;i<A.length;i++){            if(map.containsKey(A[i])){                map.put(A[i],map.get(A[i]) +1);                if(map.get(A[i]) > A.length/2)                    return A[i];            }else{                map.put(A[i],1);            }        }        return 0;    }}
0 0
原创粉丝点击