方法一:每次取出两个不同的数,剩下的数字中重复出现次数超过一半的数字肯定,将规模缩小化。如果每次删除两个不同的数,这里当然不是真的把它们踢出数组,而是对于候选数来说,出现次数减一,对于其他数来说,循环遍历就行。在剩余的数字里,原最高频数出现的频率一样超过了50%,不断重复这个过程,最后剩下的将全是同样的数字,即最高频数。此算法避免了排序,时间复杂度只有O(n).

程序示例如下:

#include "stdafx.h"
#include <stdio.h> int FindMostApperse(int* num, int len)
{
int candidate = 0;
int count = 0;
for (int i = 0; i < len; i++)
{
if (count == 0)
{
candidate = num[i];
count = 1;
}
else
{
if (candidate == num[i])
count++;
else
count--;
}
printf("num[%d]=%d,count=%d,candidate=%d\n", i, num[i], count, candidate);
}
return candidate;
}
int main()
{
int arr[] = { 2, 1, 1, 2, 3, 1, 1, 1 };
int len = sizeof(arr) / sizeof(arr[0]);
printf("%d\n", FindMostApperse(arr, len));
getchar();
return 0;
}

  效果如图:

方法二:Hash法。首先创建一个hash_map,其中key为数组元素值,value为此数出现的次数。遍历一遍数组,用hash_map统计每个数出现的次数,并用两个值存储目前出现次数最多的数和对应出现的次数,此时的时间复杂度为O(n),空间复杂度为O(n),满足题目的要求。

方法三:原创,用map,不知时间复杂度是否符合要求,代码如下:

#include "stdafx.h"
#include <iostream>
#include <map>
using namespace std;
bool findOverHalf(int *a, int size, int &val)
{
if (a == NULL || size <= 0)
return false;
map<int, int> m;
for (int i=0; i < size; i++)
{
m[a[i]]++;
if (m[a[i]]>size / 2)
{
val = a[i];
return true;
}
}
return false;
}
int main()
{
int val = 0;
int a[] = { 1, 5, 4, 3, 4, 4, 0, 5, 5, 5, 5 };
if (findOverHalf(a, 11, val))
cout << val << endl;
else
cout << "无出现次数过半的数" << endl;
getchar();
return 0;
}

如何在O(n)的时间复杂度内找出数组中出现次数超过了一半的数的更多相关文章

  1. 229. Majority Element II -- 找出数组中出现次数超过 ⌊ n/3 ⌋ 次的数

    Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorit ...

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

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

  3. 找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数

    找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数 #include<iostream>using namespace s ...

  4. <C#>找出数组中重复次数最多的数值

    给定一个int数组,里面存在重复的数值,如何找到重复次数最多的数值呢? 这是在某社区上有人提出的问题,我想到的解决方法是分组. 1.先对数组中的所有元素进行分组,那么,重复的数值肯定会被放到一组中: ...

  5. Java实现找出数组中重复次数最多的元素以及个数

    /**数组中元素重复最多的数 * @param array * @author shaobn * @param array */ public static void getMethod_4(int[ ...

  6. 【Java】 剑指offer(1) 找出数组中重复的数字

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字 ...

  7. 【剑指offer】找出数组中任意重复的数字(不修改数组),C++实现

    原创博文,转载请注明出处! # 题目 在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的.请找出数组中任意一个重复的数字,但不能修改输入的数组.例如,如果输入长度 ...

  8. 一起来刷《剑指Offer》-- 题目一:找出数组中重复的数字(Python多种方法实现)

    数组中重复的数字 最近在复习算法和数据结构(基于Python实现),然后看了Python的各种"序列"--比如列表List.元组Tuple和字符串String,后期会写一篇博客介绍 ...

  9. 剑指offer:1.找出数组中重复的数(java版)

    数组中重复的数:题目:找出数组中重复的数,题目描述:在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任 ...

随机推荐

  1. Linux用户及用户组管理命令

    一,组操作 1.创建组 groupadd  test 增加一个test组 2.修改组 groupmod -n test2  test 将test组的名子改成test2  3.删除组 groupdel ...

  2. 常用css3技巧

    H5移动前端开发常用高能css3汇总   1.禁止a标签点击高亮,这些都是非官方属性,但实用性超强   html,body{ -webkit-touch-callout: none; //禁止或显示系 ...

  3. Git 克隆操作

    我们有一个裸库Git服务器,Tom 也推了他的第一个版本.现在,Jerry 可以查看他的变化.克隆操作的远程存储库创建实例. Jerry 在他的home目录,并创建新的目录,执行克隆操作. [jerr ...

  4. Publishing to IIS 发布到IIS

    原文:https://docs.asp.net/en/latest/publishing/iis.html 发布到IIS Publishing to IIS By Rick Anderson and  ...

  5. headfirst 07

    WEB 不论你在web上做什么, 都离不开请求和响应. web请求作为某个用户交互的结果由web浏览器发送到web服务器. 在web服务器上会生成web响应并发回到web浏览器.整个过程可以总结为5步 ...

  6. Navi.Soft31.阅读导航

    Navi.Soft31.核心类库 Navi.Soft31.WinForm框架 Navi.Soft31.WebMVC框架 Navi.Soft31.微信WinForm框架 Navi.Soft31.Mobi ...

  7. js关于弹也遮罩层

    1:什么是遮罩层 遮罩层:我是弹也一个(遮罩层)还有一个(内容层),下面上图片看一效果 我们看到一个灰蒙蒙的遮盖(其实也是一个层)还有一个层(也就是我们展示的内容). 2:  弹出层效果居中分析 在这 ...

  8. 助你简化开发的 jQuery 插件

    Vanity Toolset vanity toolset是一套方便的UI工具集,可以帮助你快速的搭建幻灯,聚光灯,占位,收放相关的UI,它完成了大部分的UI功能,你只需要花费很少时间就可以构建一个完 ...

  9. 关于Unity中的特殊文件目录和资源管理(专题四)

    编辑器扩展目录: 1: Editor目录 Editor文件夹可以在根目录下,也可以在子目录里,夹就可以; Editor下面放的所有资源文件或者脚本文件都不会被打进发布包中,并且脚本也只能在编辑时使用; ...

  10. linux下硬盘的分区:

    提到硬盘的分区,以前就是很乱,有什么主分区/扩展分区/逻辑分区等;它们有什么区别呢?现在简单的了解一下: 由于在MBR的主引导记录中的分区表里面最多只能记录4个分区记录,这个不够用啊,为了解决这个问题 ...