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实现)的更多相关文章

  1. 剑指Offer - 九度1370 - 数组中出现次数超过一半的数字

    剑指Offer - 九度1370 - 数组中出现次数超过一半的数字2013-11-23 03:55 题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组 ...

  2. 【剑指Offer】28、数组中出现次数超过一半的数字

      题目描述:   数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.   例如:输入如下所示的一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过 ...

  3. 《剑指offer》39题—数组中出现次数超过一半的数字

    题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...

  4. 剑指Offer:找出数组中出现次数超过一半的元素

    题目:找出数组中出现次数超过一半的元素 解法:每次删除数组中两个不同的元素,删除后,要查找的那个元素的个数仍然超过删除后的元素总数的一半 #include <stdio.h> int ha ...

  5. 剑指offer(28)数组中出现次数超过一半的数

    题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...

  6. 数组中出现次数超过一半的数字 -java

    数组中出现次数超过一半的数字 -java 方法一: 数组排序,然后中间值肯定是要查找的值. 排序最小的时间复杂度(快速排序)O(NlogN),加上遍历. 方法二: 使用散列表的方式,也就是统计每个数组 ...

  7. 剑指Offer:面试题15——链表中倒数第k个结点(java实现)

    问题描述 输入一个链表,输出该链表中倒数第k个结点.(尾结点是倒数第一个) 结点定义如下: public class ListNode { int val; ListNode next = null; ...

  8. 【Offer】[39] 【数组中出现次数超过一半的数字】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数 ...

  9. 《剑指offer》面试题39. 数组中出现次数超过一半的数字

    问题描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, ...

随机推荐

  1. css技术

    CSS是英语Cascading Style Sheets(层叠样式表单)的缩写,它是一种用来表现HTML或 XML 等文件式样的计算机语言. CSS 目前最新版本为CSS2,能够真正做到网页表现与内容 ...

  2. ORACLE 数据库 MOD 函数用法

    1.求2和1的余数. Select mod(2,1) from dual: 2能被1整除所以余数为0. 2.MOD(x,y)返回X除以Y的余数.如果Y是0,则返回X的值. Select mod(2,0 ...

  3. algorithm 学习之 for_each

    对于algorithm里面的函数使用不算多,但是用过之后才发现,之前写过很多多余的代码,所以打算系统的学习使用下algorithm里的东西,首先就是for_each. 先看下for_each的定义: ...

  4. 学习css中得与惑

    css的学习分享 所学的css知识看多,会看懂.这只是在实践中发现的问题:  一. ???h1比div还大  h1上下有边距   为什么浮动不了  (现不知道) 二. css写了 表现不出来.... ...

  5. Sublime Text 添加eclipse快捷键

    [ // editor配置 { "keys": ["ctrl+v"], "command": "paste_and_indent& ...

  6. Request.UrlReferrer

    1:Request.UrlReferrer可以获取客户端上次请求的url,这样就可以实现类似“上一页”的功能等 2:刷新当前页面,不会改变Request.UrlReferrer的值 3:如果有A,B两 ...

  7. ThinkPhp单字母函数

    首先A.D.S.L.C.F.I 他们都在 /THINKPHP/Common/functions.php 这个文件中 下面我分别说明一下他们的功能 A() 加载Action类 D() 加载Model类 ...

  8. 转载:JAVA的静态变量、静态方法、静态类

    静态变量和静态方法都属于静态对象,它与非静态对象的差别需要做个说明. (1)Java静态对象和非静态对象有什么区别? 比对如下: 静态对象                                ...

  9. AngularJS中的Provider们:Service和Factory等的区别

    引言 看了很多文章可能还是不太说得出AngularJS中的几个创建供应商(provider)的方法(factory(),service(),provider())到底有啥区别,啥时候该用啥,之前一直傻 ...

  10. Javascript中变量提升的问题

    一.函数声明变量提升 函数声明具有变量提升的问题,所以在函数被声明之前就可以访问. //else中的语句相当于将if中的function重写,因此无论flag为何值,返回的方法始终为重写后的方法. / ...