《剑指offer29——数组中出现次数超过一半的数字》

题目描述:

 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

例如:

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

解法一:

思路解析:

        如果数组排序,则出现次数超过数组长度一半的数字一定会出现在数组的中间位置,因此利用快速排序一趟归位一个元素的思想,我们只需要找到数组中间的那个数,并且判断它的出现次数是否满足就可以了。

public class Solution {
        /**
	 * 《《数组中出现次数超过一半的数字-——解法一》》
	 * @param array
	 */
	public static int MoreThanHalfNum_Solution(int [] array) {
		
		//判断边界条件
		if(array == null || array.length<=0)
			return 0;
		//根据快速排序一趟归位一个元素的思想,确定数组的中间元素
		int midOfNum = getMiddleNumOfArray(array,0,array.length-1,array.length/2);
		//获取中间元素的出现次数是否超过一半
		boolean isMoreThanHalf = checkMoreThanHalf(midOfNum,array);
		if(isMoreThanHalf)
			return midOfNum;
		else
			return 0;
        }
	/**
	 * 获取数组排序后的中位数
	 * @param array 数组
	 * @param start 数组开始下标
	 * @param end 数组结束下标
	 * @param middle 中间坐标
	 */
	public static int getMiddleNumOfArray(int[] array,int start,int end,int middle){
		
		int i=start,j=end;
		if(start<end){
			int temp = array[start];
			while(i!=j){
				while(i<j && array[j]>=temp)
					j--;
				array[i]=array[j];
				while(i<j && array[i]<=temp)
					i++;
				array[j]=array[i];
			}
			array[i]=temp;
		}
		//判断i是否为数组中位数
		if(i==middle)
			return array[i];
		else if(i<middle){
			return getMiddleNumOfArray(array, i+1, end, middle);
		}else{
			return getMiddleNumOfArray(array, start, i-1, middle);
		}
	}
	/**
	 * 判断该数字是否在数组中出现的次数超过一半
	 * @return
	 */
	public static boolean checkMoreThanHalf(int middleOfNum,int[] array){
		int count=0;
		for(int i=0;i<array.length;i++){
			if(array[i]==middleOfNum)
				count++;
		}
		if(count > array.length/2)
			return true;
		else
			return false;
	}
} 

解法二:

思路解析:

        在遍历数组的时候保存两个值:一个是数组中的一个数字,一个是次数。当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1;如果不相同,则次数减1;如果次数为0,则需要将下一个数字保存,并把次数设为1.则最终保存的数字即为所求

public class Solution {
       /**
	 * 《《数组中出现次数超过一半的数字-——解法二》》
	 * @param array
	 */
	public static int MoreThanHalfNum_Solution(int [] array){
		//判断边界条件
		if(array == null || array.length<=0)
			return 0;
		// 结果保存在result,次数设为0
		int result=array[0],count=1;
		for(int i=0;i<array.length-1;i++){
			if(array[i+1] == array[i]){
				count++;
			}else if(count>0){
				count--;
			}else {
				result=array[i+1];
			}
		}
		//判断是否符合要求
		boolean isMoreThanHalf = checkMoreThanHalf(result,array);
		if(isMoreThanHalf)
			return result;
		else
			return 0;
	}
       /**
	 * 判断该数字是否在数组中出现的次数超过一半
	 * @return
	 */
	public static boolean checkMoreThanHalf(int middleOfNum,int[] array){
		int count=0;
		for(int i=0;i<array.length;i++){
			if(array[i]==middleOfNum)
				count++;
		}
		if(count > array.length/2)
			return true;
		else
			return false;
	}
}
 

猜你喜欢

转载自blog.csdn.net/lanyu_01/article/details/80008937