剑指offer_数组中出现次数超过一半的数字
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
第一反应肯定是直接二层遍历一下
1 public class Solution { 2 public int MoreThanHalfNum_Solution(int [] array) { 3 int sum = array.length/2; 4 for(int i=0;i<array.length;i++){ 5 int count = 0; 6 for(int j=0;j<array.length;j++){ 7 if(array[j]==array[i]) count++; 8 if(count>sum) return array[i]; 9 } 10 } 11 return 0; 12 13 } 14 }
方法二:
多数投票问题,使得时间复杂度为O(n),可以利用Boyer-Moore Majority Vote Algorithm来解决这个问题,使用cnt来统计一个元素出现的次数,当遍历到元素与统计元素相等时,cnt加一票,否则减一票,如果前面查找了i个元素且cnt==0,说明当前i个元素没有majority,或者有majority但是出现次数少于1/2,因为如果多余1/2的话cnt就不会为0,此时剩下的n-i个元素中,major的数目依然多余(n-i)/2,因此继续查找就能找出majority。
1 public class Solution { 2 public int MoreThanHalfNum_Solution(int [] array) { 3 int major = array[0]; 4 for(int j=1,cnt=1;j<array.length;j++){ 5 if(major == array[j]){ 6 cnt++; 7 }else{ 8 cnt--; 9 } 10 if(cnt == 0){ 11 major = array[j]; 12 cnt = 1; 13 } 14 } 15 int cnt = 0; 16 for(int j=0;j<array.length;j++){ 17 if(array[j]==major){ 18 cnt++; 19 } 20 } 21 if(cnt > array.length/2){ 22 return major; 23 }else{ 24 return 0; 25 } 26 } 27 }
方法三:直接排序取中位数
1 import java.util.Arrays; 2 public class Solution { 3 public int MoreThanHalfNum_Solution(int [] array) { 4 Arrays.sort(array); 5 int major = array[array.length/2]; 6 int cnt = 0; 7 for(int num : array){ 8 if(num == major) cnt++; 9 } 10 if(cnt>array.length/2) 11 return major; 12 else 13 return 0; 14 } 15 }
方法四:使用Map
1 import java.util.HashMap; 2 public class Solution { 3 public int MoreThanHalfNum_Solution(int [] array) { 4 HashMap<Integer,Integer> map = new HashMap<>(); 5 for(int num :array){ 6 int count = 0; 7 if(map.get(num)!=null) 8 count = map.get(num); 9 map.put(num,++count); 10 } 11 int max = 0; 12 int major =0; 13 for(int num : array){ 14 if(map.get(num) > max) 15 { 16 max = map.get(num); 17 major=num; 18 } 19 } 20 if(max > array.length/2) 21 return major; 22 else 23 return 0; 24 25 } 26 }

浙公网安备 33010602011771号