欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录)
字体风格:
红色文字表示:重难点
蓝色文字表示:思路以及想法
JZ39 数组中出现次数超过一半的数字【五种方法解决】
- 方法一:哈希法
- 方法二:排序求中间值
- 方法三:抵消法
- 方法四:利用快排的思想
- 方法五:target-other>=1
思路:
- 首先,我们要清楚我们要找的是数组中,出现次数为大于数组个数一半的数
- 我们的第一个想法就是,建立一个个数与最大value值相等的数组A,然后遍历所给数组,出现一个值,就在数组A中相应的位置+1,最后,我们遍历数组A找到要求的值。但是这个需要很大的空间复杂度,和时间复杂度。
- 怎么优化呢?首先看着数组A,想优化,我们想到把数组A中数值为0的,都省略去。我们发现,省略后的数组A,其实就是在原数组上,进行了一个从小到大的排序!那么优化就出来了,我们只需要把原数组从新重排序,然后位于数组中间的值,出现的次数,一定是出现次数大于数组的一半。(题中说了,所给的数组一定有一个值,出现了一半多!)
- 既然用排序了,并且要找到中间位置,我们可以理解,中间位置的数,一定是这个数组,数值大小位于中间的数,所以我们可以直接采取快速排序,这样就可以直接找到
- 我们再继续想,还是数组A,既然已经删去了数值为0的位置,剩余的,很像map,所以我们也可以用map进行存储哦!
- 大佬思想:为方法4,5。可以看代码
方法一:哈希法
public static int solution1(int[] arr){//利用map的key value模型来存放arr[i]和相对应出现的次数HashMap<Integer,Integer> map=new HashMap<>();for(int i=0;i<arr.length;i++){if(map.containsKey(arr[i])){map.put(arr[i],map.get(arr[i])+1);//已经存在就给value加1}else{map.put(arr[i],1);}}for(Map.Entry<Integer,Integer> entry:map.entrySet()){if(entry.getValue()>arr.length/2){return entry.getKey();}}return 0;}
方法二:排序求中间值
public static int solution2(int[] arr){//先对数组排序,如果这个数存在,那它一定在arr[mid]的位置,Arrays.sort(arr);int count=0;int mid=arr.length/2;for(int i=0;i<arr.length;i++){if(arr[i]==arr[mid]){count++;}}if(count>mid){//出现的次数超过mid,则返回它;return arr[mid];}return 0;}
方法三:抵消法
public static int solution3(int[] arr){//抵消法:将target和其他元素进行抵消,由于target出现的次数大于别的元素,所以最后剩下的就是我们要找的//1,4,5,7,2,4,5,4,6,4,5,4,4,4,4int target=arr[0];//target先设为arr[0];int times=1;for(int i=0;i<arr.length;i++){if(times==0){//重新设置target=arr[i];times=1;}else{if(arr[i]==target){times++;} else {times--;}}}return target;}
方法四:利用快排的思想
public static int solution4(int[] arr){int low=0;int high=arr.length-1;int mid=(high-low)/2;int index=partition(arr,low,high);while(index!=arr.length/2){if(index<arr.length/2){low=index+1;index=partition(arr,low,high);}else{high=index-1;index=partition(arr,low,high);}}int num=arr[index];int times=0;for(int i=0;i<arr.length;i++){if(arr[i]==num){times++;}}if(times*2>arr.length){return num;}return 0;}public static int partition(int[] arr,int low,int high){int key=arr[low];while(low<high){while(low<high&&arr[high]>=key){high--;}int temp=arr[low];arr[low]=arr[high];arr[high]=temp;while(low<high&&arr[low]<=key){low++;}temp=arr[low];arr[low]=arr[high];arr[high]=temp;}return low;}
方法五:target-other>=1
public static int solution(int[] arr){int count=0;int aws=0;for(int i=0;i<arr.length;i++){if(count==0){aws=arr[i];}if(arr[i]==aws){count++;} else {count--;}}return aws;}