编程题:数组中出现超数组长度一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路
最平平无奇的方法是map(数值,出现次数)一一遍历统计。
然而超过一半这个是否有什么特殊之处呢?如果有一个数值A出现超数组长度的一半,那么数组中必定有超过一半的位置是A,剩下不到一半的位置不是A。
/*数组中出现超数组长度一半的数字*/ //平平无奇循规蹈矩的方法,计数,可广泛使用,不限制于长度超一半 public int MoreThanHalfNum_Solution(int [] array) { Map<Integer,Integer> map = new HashMap<>(); 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); } // System.out.println(map); if(map.get(array[i])>array.length/2){ return array[i]; } if(map.keySet().size()-1>array.length/2){ return 0; } } return 0; } /*别人的第一的代码(深度探索了规律): 若是某个数字出现的次数大于一半,那么数组中必然有一处该数字出现的次数>其他数字出现的次数 * 譬如{1,2,3,1,1,1,5,6,\7\},一开始一个1,对2,3会被替代,但是若要存在超一半的数字,我后面必须补两个1,补了三个1之后,1的长度为4,那么数组长度不得超过8, * 后面最多再补2两不同的数组才不会超过8,但同时无法覆盖1 * */ public int MoreThanHalfNum_Solution2(int [] array) { if (array.length == 0) { return 0; } int temp = array[0]; int count = 1; for (int i = 1; i < array.length; i++) { if (array[i] == temp) { count++; } else { count--; } if (count == 0) { temp = array[i]; count = 1; } } count = 0; for (int i = 0; i < array.length; i++) { if (array[i] == temp) { count++; } } return count > array.length / 2 ? temp : 0; }
当你深入了解,你就会发现世界如此广袤,而你对世界的了解则是如此浅薄,请永远保持谦卑的态度。