(剑指Offer)面试题29:数组中出现次数超过一半的数字
题目:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
思路:
1、方法1:
先排序,然后找中位数;
时间复杂度O(nlogn)
2、方法2:
基于Partition函数的O(n)算法,即寻找第k(k=n/2)大的数;
平均时间复杂度:O(n)
3、方法3:
根据数组特点,采用Moore-Vote方法。
由于该数字的出现次数比所有其他数字出现次数的和还要多,因此可以考虑在遍历数组时保存两个值:一个是数组中的一个数字,一个是次数,。当遍历到下一个数字时,如果下一个数字与之前保存的数字相同,则次数加1,如果不同,则次数减1,如果次数为0,则需要保存下一个数字,并把次数设定为1。由于我们要找的数字出现的次数比其他所有数字的出现次数之和还要大,则要找的数字肯定是组后一次把次数设为1时对应的数字。
时间复杂度为O(n),空间复杂度为O(1)。
代码:
方法2:
#include <iostream>
using namespace std;
bool g_bInputInvalid=false;
bool CheckInvalidArray(int* numbers,int length){
if(numbers==NULL || length<=0)
g_bInputInvalid=true;
return g_bInputInvalid;
}
bool CheckMoreThanHalf(int* numbers,int length,int number){
int times=0;
for(int i=0;i<length;i++){
if(numbers[i]==number)
times++;
}
bool isMoreThanHalf=true;
if(times*2<=length){
g_bInputInvalid=true;
isMoreThanHalf=false;
}
return isMoreThanHalf;
}
int Partition(int* numbers,int start,int end){
int key=numbers[start];
int i=start;
int j=end;
while(i<j){
while(i<j && numbers[j]>=key)
--j;
if(i<j) numbers[i++]=numbers[j];
while(i<j && numbers[i]<=key)
++i;
if(i<j) numbers[j--]=numbers[i];
}
numbers[i]=key;
return i;
}
int MoreThanHalfNum(int* numbers,int length){
if(CheckInvalidArray(numbers,length))
return 0;
int mid=length>>1;
int start=0;
int end=length-1;
int index=Partition(numbers,start,end);
while(index!=mid){
if(index>mid){
end=index-1;
index=Partition(numbers,start,end);
}
else{
start=index+1;
index=Partition(numbers,start,end);
}
}
int result=numbers[index];
if(!CheckMoreThanHalf(numbers,length,result))
result=0;
return result;
}
int main()
{
int A[]={3,1,3,2,4,3,3,5,3,7,3};
int length=sizeof(A)/sizeof(A[0]);
cout << MoreThanHalfNum(A,length) << endl;
return 0;
}
方法3:
#include <iostream>
using namespace std;
bool g_bInputInvalid=false;
bool CheckInvalidArray(int* numbers,int length){
if(numbers==NULL || length<=0)
g_bInputInvalid=true;
return g_bInputInvalid;
}
bool CheckMoreThanHalf(int* numbers,int length,int number){
int times=0;
for(int i=0;i<length;i++){
if(numbers[i]==number)
times++;
}
bool isMoreThanHalf=true;
if(times*2<=length){
g_bInputInvalid=true;
isMoreThanHalf=false;
}
return isMoreThanHalf;
}
int MoreThanHalfNum_1(int* numbers,int length){
if(CheckInvalidArray(numbers,length))
return 0;
int result=numbers[0];
int times=1;
for(int i=1;i<length;i++){
if(times==0){
result=numbers[i];
times=1;
}
if(result==numbers[i])
times++;
else
times--;
}
if(!CheckMoreThanHalf(numbers,length,result))
result=0;
return result;
}
int main()
{
int A[]={3,1,3,2,4,3,3,5,3,7,3};
int length=sizeof(A)/sizeof(A[0]);
cout << MoreThanHalfNum_1(A,length) << endl;
return 0;
}
在线测试OJ:
http://www.nowcoder.com/books/coding-interviews/e8a1b01a2df14cb2b228b30ee6a92163?rp=2
AC代码:
方法1:
class Solution {
public:
int Partition(vector<int> &numbers,int start,int end){
int key=numbers[start];
int i=start;
int j=end;
while(i<j){
while(i<j && numbers[j]>=key)
--j;
if(i<j) numbers[i++]=numbers[j];
while(i<j && numbers[i]<=key)
++i;
if(i<j) numbers[j--]=numbers[i];
}
numbers[i]=key;
return i;
}
int MoreThanHalfNum_Solution(vector<int> numbers) {
int length=numbers.size();
if(length<=0)
return 0;
int mid=length>>1;
int start=0;
int end=length-1;
int index=Partition(numbers,start,end);
while(index!=mid){
if(index>mid){
end=index-1;
index=Partition(numbers,start,end);
}
else{
start=index+1;
index=Partition(numbers,start,end);
}
}
int result=numbers[index];
int times=0;
for(int i=0;i<length;i++){
if(numbers[i]==result)
times++;
}
if(times*2<=length)
result=0;
return result;
}
};
方法2:
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int length=numbers.size();
if(length<=0)
return 0;
int result=numbers[0];
int times=1;
for(int i=1;i<length;i++){
if(times==0){
result=numbers[i];
times=1;
}
if(result==numbers[i])
times++;
else
times--;
}
int t=0;
for(int i=0;i<length;i++){
if(numbers[i]==result)
t++;
}
if(t*2<=length)
result=0;
return result;
}
};
(剑指Offer)面试题29:数组中出现次数超过一半的数字的更多相关文章
- 剑指Offer:面试题29——数组中出现次数超过一半的数字(java实现)
PS:在前几天的面试中,被问到了这个题.然而当时只能用最低效的方法来解. 问题描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2, ...
- 剑指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. ...
- 【Offer】[39] 【数组中出现次数超过一半的数字】
题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数 ...
- 《剑指offer》面试题39. 数组中出现次数超过一半的数字
问题描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, ...
- 剑指offer 面试题56. 数组中只出现一次的两个数字
题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 方法1:用set记录出现过的数字 class Solution { public: void F ...
- 【剑指offer】找出数组中任意一个重复的数字,C++实现
原创博文,转载请注明出处! # 题目 # 思路 对于长度为n的数组,范围为0~n-1的数字而言,如果不粗在重复数字,则排序后数组元素和数组角标相同.如果存在重复数字,则在排序的过程中会出现不同下标对应 ...
随机推荐
- Hadoop Hive基础sql语法
目录 Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构 化的数据文件映射为一张数据库表,并提供完整的 ...
- PHP 截取字符串专题
1. 截取GB2312中文字符串 < ?php//截取中文字符串function mysubstr($str, $start, $len) { $tmpstr = "" ...
- POJ 1844 Sum
题意:给一个整数n,求当n由1到k的连续整数加或减组成时的最小的k. 解法:一开始觉得dp……后来觉得复杂度太大了……GG……百度了一下是个数学题orz. 如果n全部由加法组成,那么k可以组成k(k+ ...
- FontMetrics ----- 绘制文本,获取文本高度
Canvas 绘制文本时,使用FontMetrics对象,计算位置的坐标. public static class FontMetrics { /** * The maximum distance a ...
- hdu 1541 Stars(线段树单点更新,区间查询)
题意:求坐标0到x间的点的个数 思路:线段树,主要是转化,根据题意的输入顺序,保证了等级的升序,可以直接求出和即当前等级的点的个数,然后在把这个点加入即可. 注意:线段树下标从1开始,所以把所有的x加 ...
- 运行Python2.x程序报编码错误的解决办法-UnicodeDecodeError: 'ascii' codec can't decode byte 0xb7 in position 7: ordina not in range(128)[0m
Python编码问题的终极解决方案:在python的Lib\site-packages文件夹下新建一个sitecustomize.py文件,输入: import sys sys.setdefaulte ...
- Macbook pro内存升级
http://support.apple.com/kb/HT1270?viewlocale=zh_CN&locale=zh_CN#link1 https://support.apple.com ...
- 移动端的日期插件 mobiscroll 2.14.4 破解版
官方报价695美元 http://mobiscroll.com/pricing 这个 mobiscroll 2.14.4 破解版 包括datetime和calendar组件,包括mobiscroll和 ...
- 浅谈w3c标准
#浅谈w3c标准 ##w3c标准是什么 w3c标准包括多个方面,官方是从应用角度分的,相关的文档可以戳[这里](http://www.w3.org/standards/).如果从WEB技术角度,可以分 ...
- 【原创译文】基于Docker和Rancher的超融合容器云架构
基于Docker和Rancher的超融合容器云架构 ---来自Rancher和Redapt 超融合架构在现代数据中心是一项巨大的变革.Nutanix公司发明了超融合架构理论,自从我听说他们的“iPho ...