题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

比如输入一个长度为9的数组{1,2,3,2。2,2。5,4,2}。因为数字2在数组中出现5次,超过数组长度的一半,因此输出2.

解法一:基于Partition函数的O(n)算法:

我们的算法是受高速排序的算法的启示。在随机高速排序的算法中。我们先在数组中随机的选择一个数字。然后调数组中数字的顺序,使得比选中的数字小数字排在它的左边。比选中的数字大的数字都排在它的右边。比方这个选中的数字的下标刚好是n/2。那么这个数字就是数组中的中位数。假设它的下标大于n/2。那么中位数应该位于它的左边。我们能够接着在它的左边部分的数组中查找。假设它的下标小于n/2,那么中位数应该在它的右边,我们能够接着在它的右边部分中查找。这是一个典型的递归过程。

Java代码实现步骤例如以下:

/**
*
*/
package swordForOffer; /**
* @author JInShuangQi
*
* 2015年8月8日
*/
public class E29MoreThanHalfNumber {
//适用partition函数
public int partition(int[] arr,int left,int right){
int result = arr[left];
if(left > right)
return -1; while(left <right){
while(left <right && arr[right]>= result){
right --;
}
arr[left] = arr[right];
while(left <right && arr[left] <result){
left++;
}
arr[right] = arr[left];
}
arr[left] = result;
return left;
}
public int moreThanHalfNum(int[] arr){
if(arr.length ==0)
return -1; int length = arr.length;
int middle = length >>1;
int start = 0;
int end = length -1;
int index = partition(arr,start,end);
while(index != middle){
if(index >middle){
end = index - 1;
index = partition(arr,start,end);
}
else{
start = index + 1;
index = partition(arr,start,end);
}
} int result = arr[middle];
if(!checkMoreThanHalf(arr,result)){
result = -1;
}
return result;
}
//验证是否存在
public boolean checkMoreThanHalf(int[] arr,int number){
int times = 0;
for(int i = 0;i<arr.length;i++){
if(arr[i] == number)
times ++;
}
boolean isMoreThanHalf = true;
if(times *2 <= arr.length){
isMoreThanHalf = false;
}
return isMoreThanHalf;
}
public static void main(String[] args){
int[] arr= {1,2,3,3,2,5,4,2};
E29MoreThanHalfNumber test = new E29MoreThanHalfNumber();
System.out.println(test.moreThanHalfNum(arr));
}
}

解法二:依据数组的特点找出O(n)的算法:

接下来我们从另外一个角度来解决问题。

数组中有一个数字出现的次数超过数组长度的一半。也就是说它出现的次数比其它全部数字出现的次数的和还要多。因此我们能够遍历数组的时候保存两个值:一个是数组中的一个数字,一个是次数。当我们遍历到下一个数字的时候。假设下一个数字和我们之前保存的数字同样,则次数加1;假设下一个数字和我们之前保存的数字不同,则次数减1.假设次数为0,我们须要保存下一个数字,并把次数设为1.因为我们要找的数字出现的次数比其它全部数字出现的次数之和还要多。那么要找的数字肯定是最后一次把次数设为1时相应的数字。

//解法二:
public int moreThanHalfNum2(int[] arr){
if(arr.length == 0)
return -1;
int result = arr[0];
int times = 1;
for(int i = 1;i<arr.length;i++){
if(times == 0){
result = arr[i];
times = 1;
}else if(arr[i] == result)
times++;
else
times--;
}
if(!checkMoreThanHalf(arr,result))
result = -1;
return result;
}

剑指Offer面试题29(java版):数组中出现次数超过一半的数字的更多相关文章

  1. 《剑指offer》— JavaScript(28)数组中出现次数超过一半的数字

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

  2. 剑指offer面试题3 二维数组中的查找(c)

    剑指offer面试题三:

  3. 剑指offer面试题3二维数组中的查找

    题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 需要与面试官确认的是,这 ...

  4. 剑指offer面试题14(Java版):调整数组顺序使奇数位于偶数的前面

    题目:输入一个整数数组.实现一个函数来调整该数组中数字的顺序.使得全部奇数位于数组的前半部分.全部偶数位于数组的后半部分. 1.基本实现: 假设不考虑时间复杂度,最简单的思路应该是从头扫描这个数组,每 ...

  5. 剑指offer面试题3 二维数组中的查找 (java)

    注:java主要可以利用字符串的length方法求出长度解决这个问题带来方便 public class FindNum { public static void main(String[] args) ...

  6. 剑指offer面试题4: 二维数组中的查找

    题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...

  7. 剑指Offer面试题:6.旋转数组中的最小数字

    一 题目:旋转数组中的最小数字 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1, ...

  8. Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)

    剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...

  9. 剑指Offer:数组中出现次数超过一半的数字【39】

    剑指Offer:数组中出现次数超过一半的数字[39] 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于这 ...

  10. 剑指Offer - 九度1384 - 二维数组中的查找

    剑指Offer - 九度1384 - 二维数组中的查找2013-11-23 23:23 题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个 ...

随机推荐

  1. 关于动态添加的html元素绑定的事件不生效的解决办法

    1.可以通过行内添加事件的方法,比如onclick="fn()"; 在js中写好方法名对应的方法就可以了,如果绑定方法的元素太多 2.jquery的on事件绑定 //on事件可以给 ...

  2. CentOS7.4 搭建和使用telnet

    1.先检查是否安装了telnet rpm -qa | grep telnet  //检查你的CentOS是否安装了telnet和telnet-server rpm -qa xinetd //检查你的C ...

  3. Kvm:启动报错:error: internal error: process exited while connecting to monitor: 2018-11-12T01:47:14.993371Z qemu-system-x86_64: cannot set up guest memory 'pc.ram': Cannot allocate memory

    今天有台kvm挂了,物理机启动时报错 很明显看报错显示内存不足,无法分配内存,查看物理机内存使用正常,.xml修改虚机内存后启动依然报错 报错: 这时候需要看一下主机确保可以分配多少内存 sysctl ...

  4. 十款开发者常用的Chrome插件,让chrome成为开发利器!

    Chrome浏览器无论是作为浏览器市场的NO1还是其强大的跨平台能力以及丰富的扩展插件,一直是许多开发者的首要选择的浏览器.chrome浏览器也因为其丰富的Chrome插件,帮助开发者们在开发流程中极 ...

  5. [Android] java代码无错误,但跳转失败

    今天在调代码的时候,出现了这样的问题,我晕了半天,才找到解决办法. 查看日志发现:Initialize Binary Program Cache: Load Failed 从来没见过这种问题,Java ...

  6. Ubuntu中Hadoop环境搭建

    Ubuntu中Hadoop环境搭建 JDK安装 方法一:通过命令行直接安装(不建议) 有两种java可以安装oracle-java8-installer以及openjdk (1)安装oracle-ja ...

  7. 牛客网暑期ACM多校训练营(第二场)B discount

    链接:https://www.nowcoder.com/acm/contest/140/B来源:牛客网 题目描述 White Rabbit wants to buy some drinks from ...

  8. HDU 5025 状态压缩蛇+bfs+dp

    题目大意:孙悟空要找到一条花费时间最短的路径,路上为S的代表有蛇,经过需多花一分钟,其他情况下都是走过花费一分钟,但数字必须依次得到,最后到了唐僧处,可以经过也可以救出,救出前提是得到所有种类的钥匙 ...

  9. 上传文件表单file,限制上传文件类型的方法--参数accept

    我们使用<input type="file" />来上传文件,但是当你只想要上传某种格式的文件,比如说(jpg)文件时.可以通过accept来限制. <form& ...

  10. Inversion 归并求逆元

    bobo has a sequence a 1,a 2,…,a n. He is allowed to swap twoadjacent numbers for no more than k time ...