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

思路:

1、HashMap中存储个元素次数,之后排序,统计出最大的

2、中位数思想,快排一到两次,判断中间的数字是否为目标值

3、利用数组特性,逐个遍历,相同的次数加1,不同的减1,count为负数时,重置数据

代码:

package com.datastructure.array;

/**
 * 找出数组中出现次数超过一半的数字 
 */
public class NumberOverHalf {

	/**
	 * 快排思想
	 * 
	 * 
	 */
	public static int getNumberByPartition(int[] arr) {
		int len = arr.length;
		
		int mid = getMiddle(arr, 0, len-1);
		
		while (mid != len/2) {
			if (mid < len/2) {
				mid = getMiddle(arr, mid + 1, len-1);
			} else {
				mid = getMiddle(arr, 0, mid);
			}
		}
		
		int num = arr[mid];
		
		// 判断数据的出现次数 是否真正超过一半
		int numCount = 0;
		for (int i = 0; i< len; i++) {
			if (arr[i] == num) {
				numCount++;
			}
		}
		
		// 无出现次数大于一半的数
		if (numCount < len/2) {
			return -1;
		}
		
		return num;
	}
	
	private static int getMiddle(int arr[], int low, int high) {
		int base = arr[low];
		while (low < high) {
			while ( low < high && base <= arr[high]) {
				high--;
			}
			arr[low] = arr[high];
			
			while ( low < high && base >= arr[low]) {
				low++;
			}
			arr[high] = arr[low];
		}
		// 基准值左侧小于基准值,右侧大于基准值
		arr[low] = base;
		return low;
	}
	
	/**
	 * 数组中该数字出现次数超过一半,
	 * 若遍历数组,记录该元素,遇到相同的就次数加1,不同的减一,为负数时,更换元素,
	 * 则最后一个必然是出现次数超过一半的数字 
	 * 
	 * 
	 */
	public static int getNumberOverHalf(int[] arr) {
		if (arr == null || arr.length <= 0) {
			return -1;
		}
		int len = arr.length;
		int curNum = arr[0];
		int count = 1;
		for (int i=1; i<len; i++) {
			// 相同则增加count
			if (arr[i] == curNum) {
				count++;
			} else {
				// 不同则减少
				if (count > 0) {
					count --;
				// 出现负值情况则重置数据
				} else {
					curNum = arr[i];
					count = 1;
				}
			}
		}
		
		// 判断数据的出现次数 是否真正超过一半
		int numCount = 0;
		for (int i = 0; i< len; i++) {
			if (arr[i] == curNum) {
				numCount++;
			}
		}
		
		// 无出现次数大于一半的数
		if (numCount < len/2) {
			return -1;
		}
		
		return curNum;
	} 
	
	public static void main(String[] args) {
		int[] arr1 = new int[]{1,4,3,4,4,4,5,6,4,4,4,1};
		System.out.println(getNumberByPartition(arr1));

		
		int[] arr2 = new int[]{1,4,3,1,5,6,4,4};
		System.out.println(getNumberByPartition(arr2));
		
		
		int[] arr3 = new int[]{1,4,3,4,4,4,5,6,4,4,4,1};
		System.out.println(getNumberOverHalf(arr3));

		
		int[] arr4 = new int[]{1,4,3,1,5,6,4,4};
		System.out.println(getNumberOverHalf(arr4));
	}

}

参考:

数组中出现次数超过一半的数字:https://blog.csdn.net/derrantcm/article/details/46736859

猜你喜欢

转载自blog.csdn.net/zangdaiyang1991/article/details/88619938