题目:

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

例如输入一个长度为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:数组中出现次数超过一半的数字的更多相关文章

  1. 剑指Offer:面试题29——数组中出现次数超过一半的数字(java实现)

    PS:在前几天的面试中,被问到了这个题.然而当时只能用最低效的方法来解. 问题描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2, ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. 剑指offer 面试题56. 数组中只出现一次的两个数字

    题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 方法1:用set记录出现过的数字 class Solution { public: void F ...

  10. 【剑指offer】找出数组中任意一个重复的数字,C++实现

    原创博文,转载请注明出处! # 题目 # 思路 对于长度为n的数组,范围为0~n-1的数字而言,如果不粗在重复数字,则排序后数组元素和数组角标相同.如果存在重复数字,则在排序的过程中会出现不同下标对应 ...

随机推荐

  1. DB time实时过程分析

    在我们查看awr报告的时候总是会有一个关键指标需要注意,那就是DB time,这个指标一般都是通过awr报告来看到的.比如我们得到的awr报告头部显示的下面的信息,我们就清楚的知道DB time是15 ...

  2. 一:ZooKeeper简介

    一:背景                --->随着互联网技术的高速发展,企业对计算机系统的计算,存储能力要求越来越高,最简单的明证就是出现一些诸如:高并发,海量存储这样的词汇.在这样的背景下, ...

  3. 【转】uboot移植(一)BootLoader基本概念

    原文网址:http://blog.chinaunix.net/uid-25445243-id-3869348.html 一.BootLoader简介1.1.嵌入式Linux软件结构与分布 在一般情况下 ...

  4. SSH框架面试题

    Hibernate工作原理及为什么要用? 原理: 1. 读取并解析配置文件 2. 读取并解析映射信息,创建SessionFactory 3. 打开Sesssion 4. 创建事务Transation ...

  5. POJ 2241 Mondriaan's Dream

    题意:给一块n×m的空地,用1×2的砖铺,有多少种方案. 解法:状压dp.考虑dp[i][j]表示前i - 1行都铺满时第i行的状态为j时的方案数.对于第i行,每个格子上是否有砖用0和1表示,0表示不 ...

  6. PreferenceActivity使用方法

              public class MainActivity extends Activity { @Override protected void onCreate(Bundle save ...

  7. Why automate?为什么要自动化?

    The need for speed is practically the mantra of the information age. Because technology is now being ...

  8. 九度 Online Judge 之《剑指 Offer》一书相关题目解答

    前段时间准备华为机试,正好之前看了一遍<剑指 Offer>,就在九度 Online Judge 上刷了书中的题目,使用的语言为 C++:只有3题没做,其他的都做了. 正如 Linus To ...

  9. Configuring and troubleshooting a Schema Provider

    原文:https://codesmith.atlassian.net/wiki/display/Generator/Configuring+and+troubleshooting+a+Schema+P ...

  10. git初步使用

    git初步使用 主要目的:使用代码控制工具,练习使用git 1.创建新项目 网址如下: https://github.com/kellyseeme?tab=repositories 注意每个人使用的名 ...