剑指Offer:面试题29——数组中出现次数超过一半的数字(java实现)
来源:互联网 发布:淘宝的免费开店是什么 编辑:程序博客网 时间:2024/06/06 00:10
PS:在前几天的面试中,被问到了这个题。然而当时只能用最低效的方法来解。
更新:抱歉各位,这里好多代码并没有得到验证,可能有错.大家慎入坑.
问题描述:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路1:
低效的做法:直接用哈稀表来存储
<key, value>
,并找出出现次数value大于等于一半的那个key。
代码:
import java.util.Map;import java.util.HashMap;public class Solution { boolean InvalidInput = false; public int MoreThanHalfNum_Solution(int [] array) { if(array == null || array.length == 0){ InvalidInput = true; return 0; } Map<Integer, Integer> map = new HashMap<Integer, Integer>(); int max = -1; int ind = -1; for(int i = 0; i < array.length; i++){ if(!map.containsKey(array[i])){ map.put(array[i], 1); }else{ map.put(array[i], map.get(array[i])+1); } if(max < map.get(array[i])){ max = map.get(array[i]); ind = array[i]; } } if(max > array.length/2){ return ind; }else{ return 0; } }}
思路2:
—由于出现的次数超过了数组的一半,那么如果我们将数组排序,中间的那个数一定是要求的数字(前提是它一定存在)
—这里排序时采用快排的基本思想,随机选择一个数,调整数组使得它左边的数都小于它,右边的数都大于它。(参考Partition函数)(下一篇博客的代码中给出了关于Partition函数详细的注释)
import java.util.Map;import java.util.HashMap;public class Solution { static boolean InvalidInput = false; public int MoreThanHalfNum_Solution(int [] array) { if(array == null || array.length == 0){ InvalidInput = true; return 0; } int middle = array.length >> 1;//设定中位数位置 int start = 0; int end = array.length - 1; int index = Partition(array, start, end);//随机选择一个标杆,进行调整数组 while(index != middle){//若所选的标杆最后位置不是中位数的位置,则根据情况对符合情况的部分进行再次调整 if(index > middle){ end = index - 1; index = Partition(array, start, end); }else{ start = index + 1; index = Partition(array, start, end); } } int result = array[middle]; //检查中位数出现的次数是否超过了一半 if(!CheckMoreThanHalf(array, result)){ result = 0; } return result; } public static boolean CheckMoreThanHalf(int[] array, int number){ int times = 0; int length = array.length; for(int i = 0; i < length; i++){ if(array[i] == number){ times++; } } boolean isMoreThanHalf = true; if(times * 2 <= length){ InvalidInput = true; isMoreThanHalf = false; } return isMoreThanHalf; } public static int Partition(int[] array, int start, int end){ if(array == null || array.length == 0 || start < 0 || end < 0){ InvalidInput = true; return -1; } int index = RandomInRange(start ,end); int tmp = array[index]; array[index] = array[end]; array[end] = tmp; int small = start - 1; for(index = start; index < end; index++){ if(array[index] < array[end]){ small++; if(small != index){ int temp = array[index]; array[index] = array[small]; array[small] = temp; } } } small++; tmp = array[small]; array[small] = array[end]; array[end] = tmp; return small; } public static int RandomInRange(int s, int e){ int Min = s; int Max = e; int result = Min + (int)(Math.random() * ((Max - Min) + 1)); return result; }}
思路3:
根据数组特点找出O(n)的算法
1.数组中有一个数字出现的次数超过数组长度的一半,也就是说它出现的次数比其他所有的数字出现的次数的和还要多。
2.因此我们可以考虑在遍历数组的时候保存两个值:一个是数组中的一个数字,一个是次数。
3.当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1,否则减1.
代码:
import java.util.Map;import java.util.HashMap;public class Solution { static boolean InvalidInput = false; public int MoreThanHalfNum_Solution(int [] array) { if(array == null || array.length == 0){ InvalidInput = true; return 0; } int result = array[0]; int times = 1; for(int i = 1; i < array.length; i++){ if(times == 0){ result = array[i]; times = 1; }else if(array[i] == result){ times++; }else{ times--; } } if(!CheckMoreThanHalf(array, result)){ InvalidInput = true; result = 0; } return result; } public static boolean CheckMoreThanHalf(int[] array, int number){ int times = 0; int length = array.length; for(int i = 0; i < length; i++){ if(array[i] == number){ times++; } } boolean isMoreThanHalf = true; if(times * 2 <= length){ InvalidInput = true; isMoreThanHalf = false; } return isMoreThanHalf; }}
PS:检查出现频率最高的是否超过一半,也还是需要遍历一次数组的。
1 1
- 剑指Offer面试题29:数组中出现次数超过一半的数字 Java实现
- 剑指Offer:面试题29——数组中出现次数超过一半的数字(java实现)
- 剑指offer——面试题29:数组中出现次数超过一半的数字
- 剑指offer 面试题29—数组中出现次数超过一半的数字
- 剑指Offer面试题29(java版):数组中出现次数超过一半的数字
- 剑指Offer面试题29(java版):数组中出现次数超过一半的数字
- 【剑指offer】5.2时间效率——面试题29:数组中出现次数超过一半的数字
- [剑指offer][面试题29]数组中出现次数超过一半的数字
- 剑指Offer:面试题29 数组中出现次数超过一半的数字
- 《剑指Offer》学习笔记--面试题29:数组中出现次数超过一半的数字
- 【剑指Offer学习】【面试题29 :数组中出现次数超过一半的数字】
- 剑指offer面试题29-数组中出现次数超过一半的数字
- 剑指offer-面试题29:数组中出现次数超过一半的数字
- 剑指offer之面试题29:数组中出现次数超过一半的数字
- 剑指offer之面试题29数组中出现次数超过一半的数字
- 剑指Offer----面试题29:数组中出现次数超过一半的数字
- 剑指offer-----面试题29(数组中出现次数超过一半的数字)
- 剑指offer面试题29:数组中出现次数超过一半的数字
- c指针-01
- Android 深入理解Android中的自定义属性
- Spring 定时任务之 @Scheduled cron表达式
- 使用nodejs+express(4.x+)实现文件上传
- Android Bluetooth Low Energy官方文档翻译
- 剑指Offer:面试题29——数组中出现次数超过一半的数字(java实现)
- CreateThread和_beginthreadex区别
- 树、森林和二叉树的转换
- mac xcode7编译老版本程序程序出错
- IONIC----01.ionicActionSheet
- android static Handler
- jquery遍历节点 children(),next(),prev(),siblings()closest()
- Centos7安装Chrome浏览器
- iOS-最新,最全的App上架教程