剑指offer--数组中出现次数超过一半的数字
/** * 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 * 例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。 * 由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。 * 如果不存在则输出0。 */ package javabasic.nowcoder; import java.util.Arrays; import java.util.HashMap; import java.util.Map; /** 思路一: 数组排序后,如果符合条件的数存在,则一定是数组中间那个数。(比如:1,2,2,2,3;或2,2,2,3,4;或2,3,4,4,4等等) 这种方法虽然容易理解,但由于涉及到快排sort,其时间复杂度为O(NlogN)并非最优; 思路二: 采用阵地攻守的思想: 第一个数字作为第一个士兵,守阵地;count = 1; 遇到相同元素,count++; 遇到不相同元素,即为敌人,同归于尽,count--;当遇到count为0的情况,又以新的i值作为守阵地的士兵,继续下去,到最后还留在阵地上的士兵,有可能是主元素。 再加一次循环,记录这个士兵的个数看是否大于数组一般即可。 思路三: 利用map存值,找出存在最多的数字,若大于长度一半,返回此数,否则返回0 */ public class Main33 { public int MoreThanHalfNum_SolutionI(int [] array) { if(array==null||array.length==0) { return 0; } if(array.length==1) { return array[0]; } Arrays.sort(array); int count=0; for(int i=0;i<array.length;i++){ if(array[i]==array[array.length/2]) { count++; } } if(count*2>array.length) { return array[array.length/2]; } return 0; } public int MoreThanHalfNum_SolutionII(int [] array) { if(array==null||array.length==0) { return 0; } if(array.length==1) { return array[0]; } int res = array[0]; int count=1; for(int i=0;i<array.length;i++){ if(res==array[i]) { count++; }else{ count--; } if(count==0) { res = array[i]; count=1; } } int time=0; for(int i=0;i<array.length;i++) { if(array[i] == res) { time++; } } if(time*2>array.length) { return res; } return 0; } public int MoreThanHalfNum_SolutionIII(int [] array) { if(array==null||array.length==0) { return 0; } if(array.length==1) { return array[0]; } Map<Integer, Integer> record = new HashMap<Integer, Integer>(); for(int i=0;i<array.length;i++){ if(!record.containsKey(array[i])){ record.put(array[i], 1); }else { record.put(array[i], record.get(array[i])+1); } } for(Integer num : record.keySet()) { if(record.get(num)*2>array.length) { return num; } } return 0; } public static void main(String[] args) { int[] res = {1,2,3,2,2,2,5,4,2}; int moreThanHalfNum_Solution = new Main33().MoreThanHalfNum_SolutionI(res); System.out.println(moreThanHalfNum_Solution); } }