剑指offer(28)
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
题目分析
这题也有两种做法:
第一种:基于快排思想中的partition函数来做,因为根据题目,那么排序后的数组中间的数就是那个出现次数超过一半的数,那么我只需要利用快排中的partition,找到数组中间的那个数就行。
类似于之前写的查找第K大的数,只不过现在的K值为数组长度的一半
第二种:根据数组特点来做,数组中有一个数字出现的次数超过数组长度的一半,也就是说它出现的次数比其他所有数字出现的次数的和还要多,那么就可以从这里下手啦,具体看代码。
第一种要修改数组,第二种不需要修改数组。除此之外,注意检查是不是符合要求。
代码
第一种:
function MoreThanHalfNum_Solution(numbers)
{
if(!numbers.length) return 0;
if(numbers.length==1) return numbers;
let halfLen=~~((numbers.length)/2);
let res=search(numbers,0,numbers.length-1,halfLen);
if(!checkMoreThanHalf(numbers,res)){
return 0;
}
return res;
}
function search(numbers,left,right,k)
{
let key=partition(numbers,left,right);
if(left<right){
key=partition(numbers,left,right);
let len=right-key+1;
if(len==k){//重点,递归的结束条件
return numbers[key];
} else if(len>k){
return search(numbers,key+1,right,k);
} else{
return search(numbers,left,key-1,k-len);
}
}
}
function partition(a,left,right){
let key=a[left];//一开始让key为第一个数
while(left<right){//扫描一遍
while(key<=a[right]&&left<right){//如果key小于a[right],则right递减,继续比较
right--;
}
[a[left],a[right]]=[a[right],a[left]];//交换
while(key>=a[left]&&left<right){//如果key大于a[left],则left递增,继续比较
left++;
}
[a[left],a[right]]=[a[right],a[left]];//交换
}
return left;//把key现在所在的下标返回
}
function checkMoreThanHalf(numbers,num) {
let times=0;
for(let i=0;i<numbers.length;i++){
if(num==numbers[i]){
times++;
}
}
if(times*2<=numbers.length){
return false;
}else return true;
}第二种:
function MoreThanHalfNum_Solution(numbers)
{
let res=numbers[0],times=1;
for(let i=0;i<numbers.length;i++){
if(times==0){
res=numbers[i];
times=1;
}else if(numbers[i]==res){
times++;
}else{
times--;
}
}
if(!checkMoreThanHalf(numbers,res)){
res=0;
}
return res;
}
function checkMoreThanHalf(numbers,num) {
let times=0;
for(let i=0;i<numbers.length;i++){
if(num==numbers[i]){
times++;
}
}
if(times*2<=numbers.length){
return false;
}else return true;
} 相关推荐
bentocaffe 2020-05-09
Migle 2018-01-04
MySQLl 2019-04-07
shenghaomail 2011-12-17
87417203 2009-03-26
学习编程 2018-03-18
私宅 2018-03-02
稀土 2018-01-14