剑指Offer:面试题29——数组中出现次数超过一半的数字(java实现)
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];
}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:检查出现频率最高的是否超过一半,也还是需要遍历一次数组的。
剑指Offer:面试题29——数组中出现次数超过一半的数字(java实现)的更多相关文章
- 剑指Offer - 九度1370 - 数组中出现次数超过一半的数字
剑指Offer - 九度1370 - 数组中出现次数超过一半的数字2013-11-23 03:55 题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组 ...
- 【剑指Offer】28、数组中出现次数超过一半的数字
题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 例如:输入如下所示的一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过 ...
- 《剑指offer》39题—数组中出现次数超过一半的数字
题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...
- 剑指Offer:找出数组中出现次数超过一半的元素
题目:找出数组中出现次数超过一半的元素 解法:每次删除数组中两个不同的元素,删除后,要查找的那个元素的个数仍然超过删除后的元素总数的一半 #include <stdio.h> int ha ...
- 剑指offer(28)数组中出现次数超过一半的数
题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...
- 数组中出现次数超过一半的数字 -java
数组中出现次数超过一半的数字 -java 方法一: 数组排序,然后中间值肯定是要查找的值. 排序最小的时间复杂度(快速排序)O(NlogN),加上遍历. 方法二: 使用散列表的方式,也就是统计每个数组 ...
- 剑指Offer:面试题15——链表中倒数第k个结点(java实现)
问题描述 输入一个链表,输出该链表中倒数第k个结点.(尾结点是倒数第一个) 结点定义如下: public class ListNode { int val; ListNode next = null; ...
- 【Offer】[39] 【数组中出现次数超过一半的数字】
题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数 ...
- 《剑指offer》面试题39. 数组中出现次数超过一半的数字
问题描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, ...
随机推荐
- git提交远程仓库命令
在已有的git库中搭建新库,并且将本地的git仓库,上传到远程服务器的git库中,从而开始一个新的项目 首先,在本地新建文件夹abc,进入到abc里面,然后git init.这样就在本地初始化了一个g ...
- 启动odoo-10.0成功,但是访问时出错
启动odoo-10.0显示成功 2017-01-05 06:49:48,211 532 INFO ? odoo: Odoo version 10.02017-01-05 06:49:48,211 53 ...
- linux apache 配置URL地址栏大小写不敏感配置
1.apache配置 解决如下:把mod_speling.so放到apache目录下的 lib中... 然后修改http.conf文件, 加入:LoadModule speling_module /u ...
- 16个常用IO流
在包java.io.*:下 有以下16个常用的io流类: (Stream结尾的是字节流,是万能流,通常的视频,声音,图片等2进制文件, Reader/Writer结尾的是字符流,字符流适合读取纯文本文 ...
- 转-decorators.xml的用法-http://blog.csdn.net/gavinloo/article/details/7458062
今天改前人做的项目,用struts2,spring,hibernate框架做的,对了,还有jQuery.我用jquery做异步请求到后台,生成json数据返回前台生成下拉输入框,请求到后台以后,成功生 ...
- while 循环的使用
以下是一个基本的while循环,测试条件是:如果COUNTER小于5,那么返回 true.COUNTER从0开始,每次循环处理时,COUNTER加1.运行上述脚本,返回数字1到5,然后终止. COUN ...
- Eclipse for j2ee 无法调式问题
首先要配置tomcat,window--preference--server--Installed Runtimes, add--选择tomcat--next--选择tomcat的安装目录(根目录)- ...
- GDB详解
1 简介 2 生成调试信息 3 启动GDB 的方法 4 程序运行上下文 4.1 程序运行参数 4.2 工作目录 4.3 程序的输入输出 5 设置断点 5.1 简单断点 5.2 多文件设置断点 5.3 ...
- javascript介绍
1.javascript的简介 1.1javascript的特点 1.安全性(不允许方问本地硬盘),它可以做的是信息的动态交互. 2.跨平台.(只要是可以解释js的浏览器都可以执行,与平台无关) 1. ...
- flex 布局 初次接触这个好使又不是特别好用的布局方法
刚开始学前端的童鞋们应该也是一样先学习的table然后再学习了盒子模型,感觉终于学会了简单的网页布局,使用各种display,float,position绞尽脑汁给页面布局成自己想要的页面样式,然而, ...