题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
解题思路
1,第一种,超过一半的数必然出现在递增数组中间,先排序,然后统计中间值次数
2,第二种,遍历每一个数出现的次数,放到map里,然后用次数和len/2比较
3,第三种,利用数组的特性,超过一半的数出现的总次数比其它所有数出现总次数还多,这样我们在遍历数组的时候第一个值为result,次数为1,遇到相同的次数加1,遇到不同的减1,次数为0时,重复上述过程,最后得出的数即是持有股份最多的,不一定超过一半,然后我们在遍历统计它出现的次数,超过一半就是。
代码实现
/** * */ package 数组; import java.util.Arrays; import java.util.HashMap; /** * <p> * Title:MoreThanHalfNum * </p> * <p> * Description: * </p> * * @author 田茂林 * @data 2017年8月25日 下午5:13:34 */ public class MoreThanHalfNum { // ===========================================================排序取中间值,时间复杂度nlogn public static int moreThanHalfNumSort(int[] array) { if (array == null || array.length < 1) { return -1; } int len = array.length; Arrays.sort(array); int num = array[len / 2]; int count = 0; for (int i = 0; i < array.length; i++) { if (array[i] == num) { count++; } } if (count * 2 > len) { return num; } else { return 0; } } // ============================================================存放到hashmap里,时间复杂度为O(n),空间复杂度为O(n) public static int moreThanHalfNum(int[] array) { if (array == null || array.length < 1) { return -1; } HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); // 给数组中所有数字标记出现次数 for (int i = 0; i < array.length; i++) { if (map.containsKey(array[i])) { map.put(array[i], map.get(array[i]) + 1); } else { map.put(array[i], 1); } } int len = array.length; for (int i = 0; i < map.size(); i++) { if (map.get(array[i]) > len / 2) { return array[i]; } } return 0; } // ============================================================根据数组特点,时间复杂度O(n) public static int moreThanHalfNumSuper(int[] array) { if (array == null || array.length < 1) { return -1; } int len = array.length; int count = 1; int result = array[0]; for (int i = 1; i < array.length; i++) { if (count == 0) { result = array[i]; count = 1; } if (result == array[i]) { count++; } else { count--; } } // 最后持有count值的result可能就是超过一半的({ 1, 2, 3, 2, 2, 2, 5, 4, 2 // },也有可能小于一半{1,2,2,3,4},但其是唯一候选人,股份最大的) // 遍历次数,如果次数超过一半,则说明是 count = 0; for (int i = 0; i < array.length; i++) { if (array[i] == result) { count++; } } if (count * 2 > len) { return result; } else { return 0; } } public static void main(String[] args) { int[] array = { 1, 2, 3, 2, 2, 2, 5, 4, 2 }; System.out.println(moreThanHalfNum(array)); System.out.println(moreThanHalfNumSort(array)); } }