问题:

长度为n的数组,有一个数重复出现了n/2+1次,找出这个数;
 
解决:
比较直接的思路是遍历每个元素,让其与剩下其他元素比较,相等一次计数器sum++,直到sum=n/2+1为止;
#include <stdio.h>
#include <stdlib.h>
#include <assert.h> int fun(int inp[],int size)
{
assert(inp!=NULL && size>);
int i=,j=;
for(;i<size-;i++){
int sum = ;
for(j=i+;j<size;j++){
if(inp[i]==inp[j]) sum++;
}
if(size/+ == sum) return inp[i];
}
return -;
} int main(){
int input[]={,,,,,,,,,};
int ret = fun(input,);
printf("result = %d\n",ret);
return ;
}

结果如下:

[root@admin Desktop]# ./a.out
result =
[root@admin Desktop]#
 
方法2:
有n/2+1个重复的,那我们每次从数组中提取出来一对不同的数,到最后数组中剩余的,就只能是重复的数了;
比如{1,3,1,2,1};
依次提取出1/3 , 1/2,剩余的就是1;
 
方案:
1.扫描一遍数组,找到不相同两个数,都置为-1;
2.最后剩下的,全都是重复数字;
 
#include <stdlib.h>
#include <stdio.h>
#include <assert.h> int fun(int inp[],int size)
{
assert(inp != NULL && size>);
int i=,j=;
for(;i<size-;i++){//外循环,保证每个数都被遍历到
printf("i==:%d\n",i);
if(- == inp[i]) continue;//外循环遇到-1时,证明该数被选中并剔除过
else{
printf("in else ==:\n");
for(j=i+;j<size;j++){ //内循环,从i往后寻找与inp[i]不同的且不为-1的元素;
if(inp[i] != inp[j] && - != inp[j]){
printf("j==:%d\n",j);
inp[i]=inp[j]=-;//找到后都置为-1
break;
}
if(size- == j) return inp[i];//如果j走到头都没找到,证明剩下的都与inp[i]重复
}
}
}
return -;//失败,返回-1
} int main()
{
int input[] = {,,,,,,,,,};
int ret = fun(input,);
printf("the number is:%d\n",ret);
return ;
}

结果:

[root@admin Desktop]# ./a.out
i==:
in else ==:
j==:
i==:
i==:
in else ==:
j==:
i==:
i==:
in else ==:
j==:
i==:
i==:
in else ==:
j==:
i==:
i==:
in else ==:
the number is:
[root@admin Desktop]#
方法3:
这个方法不是我想到的,感觉思路极其巧妙,扫描一遍即可,且复杂度只有0(n),上面两个算法复杂度都为O(n2);
 
方案:充分利用出现次数超过一半这个特点,使用两个变量candidate和vote,分别代表候选人和票数,遍历数组按如下方式投票和更换候选人:

1.若当前数的值与候选人candidate一样,则把候选人的票数加1;

2.若当前数与候选人不一样,则把它的票数减1,如果减掉后票数小于0,则把候选人踢掉,用当前数作为新的候选人;

3.最后剩下的候选人就是出现次数超过一半的数。

算法的正确性证明: 数组中,数值相同的数都会投赞成票,数值不同的都会投反对票,有一个数出现的次数超过一半,其它数得到的反对票必然大于一半,所以其它数中,任何一个得票都会小于0,遭到淘汰。剩下来的只能是超过一半的那个数。

 
#include <stdlib.h>
#include <stdio.h>
#include <assert.h> int fun(int inp[],int size)
{
assert(inp != NULL && size>);
int i=,candidate=inp[],vote=;
for(;i<size;i++){
printf("i = %d; candidate is:%d; vote=%d\n",i,candidate,vote);
if(inp[i] == candidate) vote++;
else{
vote--;
if(vote < ){
candidate = inp[i];
vote = ;
}
}
}
return candidate;
} int main()
{
int input[] = {,,,,,,,,,};
int ret = fun(input,);
printf("the number is:%d\n",ret);
return ;
}

结果:

[root@admin Desktop]# ./a.out
i = ; candidate is:; vote=
i = ; candidate is:; vote=
i = ; candidate is:; vote=
i = ; candidate is:; vote=
i = ; candidate is:; vote=
i = ; candidate is:; vote=
i = ; candidate is:; vote=
i = ; candidate is:; vote=
i = ; candidate is:; vote=
i = ; candidate is:; vote=
the number is:
[root@admin Desktop]#
 
 
 
 
 
 
 
 

长度为n的数组,有一个数重复出现了n/2+1次,找出(三种方法)的更多相关文章

  1. (PASS)JAVA数组去重 三种方法 (不用集合)

    第一种方法(只学到数组的看): 定义一个新的数组长度和旧数组的长度一样,存储除去重复数据的旧数组的数据和0, package demo01; import java.sql.Array; import ...

  2. 数组k平移三种方法(java)

    上代码,本文用了三种方法实现,时间复杂度不一样,空间复杂度都是o(1): public class ArrayKMove { /** * 问题:数组的向左k平移,k小于数组长度 * @param ar ...

  3. js二维数组定义和初始化的三种方法总结

    js二维数组定义和初始化的三种方法总结 方法一:直接定义并且初始化,这种遇到数量少的情况可以用var _TheArray = [["0-1","0-2"],[& ...

  4. php将数组写入到文件的三种方法

    php将数组原样写入或保存到文件有三种方法可以实现, 第一种方法是使用serialize, 第二种方法是使用print_r, 第三种方法是使用var_export, 本文章向大家介绍这三种方法是如何将 ...

  5. php数组合并有哪三种方法

    php数组合并有哪三种方法 一.总结 一句话总结:array_merge():array_merge_recursive():‘+'号 $a = array('color'=>'red',5,6 ...

  6. 输入n个数组,数组长度不等,每个数组取出一个数进行组合,求出所有的组合。

    转载声明:原文转自http://www.cnblogs.com/xiezie/p/5511707.html 昨天晚上,有个朋友找到我,他在用matlab编程,但是遇到一个问题,解决不了. 问题如下: ...

  7. 0..n去掉一个数,给你剩下的数,找出去掉的那个数

    转载请注明转自blog.csdn.net/souldak , 微博@evagle 首先,考虑没有去掉那些数,如果n是奇数,n+1个最低位肯定是0101...01,count(0)=count(1),如 ...

  8. python3的leetcode题,两个数求和等于目标值,返回这两个数的索引组成的列表(三种方法)

    给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为gai目标值的 两个 整数. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数组中同样的元素. 示例: 给定 ...

  9. 前端面试题1:Object.prototype.toString.call() 、instanceof 以及 Array.isArray()三种方法判别数组的优劣和区别

    1. Object.prototype.toString.call() 每一个继承 Object 的对象都有 toString 方法,如果 toString 方法没有重写的话,会返回 [Object ...

随机推荐

  1. js中prototype用法(转)

    JavaScript能够实现的面向对象的特征有:·公有属性(public field)·公有方法(public Method)·私有属性(private field)·私有方法(private fie ...

  2. 前端学习笔记(zepto或jquery)——对li标签的相关操作(一)

    对li标签的相关操作——点击li标签进行样式切换的两种方式 Demo演示: 1 2 3 4 // 详解: 第一种方式(以ul为基础): $("ul").bind("cli ...

  3. linux_设置开机自启动程序脚本

    设置开机自启动

  4. [CLR via C#]1.1 将源代码编译成托管代码

    原文:[CLR via C#]1.1 将源代码编译成托管代码 1. 公共语言运行时(Common Language Runtime,CLR)是一种可由多种编程语言使用的"运行时". ...

  5. C# - Recommendations for Abstract Classes vs. Interfaces

     The choice of whether to design your functionality as an interface or an abstract class can somet ...

  6. iOS 学习

    iOS 学习资料 (适合初学者) 本文资料来源于GitHub 一.视频教程(英文) Developing iOS 7 Apps for iPhone and iPad斯坦福开放教程之一, 课程主要讲解 ...

  7. 一些常用的jquery数字正则表达式

    使用 <script type="text/javascript"> function validate(){ var reg = new RegExp("^ ...

  8. 序列化悍将Protobuf-Net

    序列化悍将Protobuf-Net,入门动手实录 最近在研究web api 2,看了一篇文章,讲解如何提升性能的, 在序列化速度的跑分中,Protobuf一骑绝尘,序列化速度快,性能强,体积小,所以打 ...

  9. CSS下背景属性background的使用方法

    背景颜色(background-color) CSS可以用纯色来作为背景,也可以将背景设置为透明,background相当于xhtml中的bgcolor. 它的两个值: transparent(默认值 ...

  10. jmeter之自定义java请求性能测试

    一.环境准备         1.新建一个java工程         2.导入jar包:ApacheJMeter_core.jar     ApacheJMeter_java.jar         ...