问题:

长度为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. Unity插件之NGUI学习(8)—— Table和NGUI尺寸转换为世界坐标系尺寸

    依据 Unity插件之NGUI学习(2),创建一个UI Root,在UI Root下创建一个Texture作为背景图,并设置图片,在Wiget下调整大小:然后在UI Root下再创建一个Panel. ...

  2. Android 从硬件到应用程序:一步一步爬上去 6 -- 我写的APP测试框架层硬件服务(终点)

    创Android Applicationproject:采用Eclipse的Android插入ADT创Androidproject,project名字Gpio,创建完成后,project文件夹pack ...

  3. EF 事物

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...

  4. 【 D3.js 入门系列 --- 9.6 】 生产的包图

    我的个人博客是:www.ourd3js.com csdn博客为:blog.csdn.net/lzhlzz 转载请注明出处,谢谢. 打包图( Pack ).用于包括与被包括的关系,也表示各个对象的权重, ...

  5. 国内首篇介绍JanOS物联网操作系统的文章 - 如何把你的手机主板打造成物联网平台

    天地会珠海分舵注:如无意外,您现在正在看的将是国内首篇且是唯一一篇介绍炙手可热的物联网的操作系统JanOS的文章!不信你去百度!希望大家能喜欢.但本文只是引言,更多信息请还是访问JanOS的官网:ht ...

  6. Appium Android Bootstrap源码分析之控件AndroidElement

    通过上一篇文章<Appium Android Bootstrap源码分析之简介>我们对bootstrap的定义以及其在appium和uiautomator处于一个什么样的位置有了一个初步的 ...

  7. windows下 composer常见问题及处理

    错误一: Warning: This development build of composer is over 30 days old. It is recommend ed to update i ...

  8. MVC5 EF6 Bootstrap3 HtmlHelper

    MVC5 + EF6 + Bootstrap3 (9) HtmlHelper用法大全(下) 上一节:MVC5 + EF6 + Bootstrap3 (8) HtmlHelper用法大全(上) 源码下载 ...

  9. .NET源代码的内部排序实现

    使用JetBrains的DotPeek工具能够方便地查看.net的部分源代码.于是看了一下.NET的内部是怎样实现排序的算法. 在System.Collections.Generic 命名空间下能够看 ...

  10. UC编程:输入输出重定向(系统调用)

    在Unix下,系统重定向是使用dup和dup2函数完成的 在学习使用这两个函数之前,必须要搞懂一个概念就是文件描述符 摘自:<文件描述符和文件指针的区别> 文件描述符就是open文件时产生 ...