如何在O(n)的时间复杂度内找出数组中
来源:互联网 发布:苹果手机摄影软件 编辑:程序博客网 时间:2024/05/22 15:41
方法一:每次取出两个不同的数,剩下的数字中重复出现次数超过一半的数字肯定,将规模缩小化。如果每次删除两个不同的数,这里当然不是真的把它们踢出数组,而是对于候选数来说,出现次数减一,对于其他数来说,循环遍历就行。在剩余的数字里,原最高频数出现的频率一样超过了50%,不断重复这个过程,最后剩下的将全是同样的数字,即最高频数。此算法避免了排序,时间复杂度只有O(n).
程序示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#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,不知时间复杂度是否符合要求,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#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;
}
0 0
- 如何在O(n)的时间复杂度内找出数组中
- 如何在O(n)的时间复杂度内找出数组中出现次数超过一半的数
- 如何在O(N)的时间复杂度内找出数组中出现次数超过了一半的数
- 如何在O(n)的时间复杂度内找出数组中出现次数超过了一半的数
- 在时间复杂度为 O(n) 内找出数组中出现次数超过一半的数
- 在O(n)时间复杂度内找出数组中的众数
- 在O(n)的时间复杂度内找出数组中出现次数超过了一半的数
- 如何快速找出一个数组中只出现一次的两个数,其他元素出现两次?保证时间复杂度O(n),空间复杂度O(1)
- 找出数组中出现次数超过一半的数(时间复杂度O(n))
- 在时间复杂度O(n)内,实现将数组A[n]中所有元素左循环移n位
- 如何在时间复杂度为O(n),空间复杂度为O(1)的条件下,统计数组中不同元素出现的次数
- LeetCode Median of Two Sorted Arrays 在两个已排列的数组中找出中位数。时间复杂度为O(log(min(N,M))
- 在O(n)时间复杂度O(1)空间复杂度求一个数组中出现多次和未出现的数字
- 在O(n)时间复杂度O(1)空间复杂度求一个数组中出现多次和未出现的数字
- 从俩个有序数组中找出第K小的数。要求时间复杂度O(logmin(m,n))
- 找出一个数组中出现次数超过一半的那个数字,要求时间复杂度O(n)和空间复杂度为O(1)。
- 《编程题》找出数组中出现次数超过一半的数(时间复杂度O(n),空间复杂度为O(1))
- 一个数组中,存在两个只出现一次的数字,其余的数字均出现两次。要求在时间复杂度o(n),空间复杂度为o(1)的情况下找出这两个数字
- WebView重定向问题的解决方案
- 为什么说 Objective-C 没有私有方法和私有变量
- Fastlane安装
- 多渠道打包动态修改Assets 中的内容 APKTool
- erlang 最简单的安装方法
- 如何在O(n)的时间复杂度内找出数组中
- 工厂方法模式笔记
- Android内存优化之OOM
- 算法 第一天
- 动态创建表格
- Git 常用命令
- 面试题之指针函数与函数指针的区别
- LeetCode30. Substring with Concatenation of All Words
- java轻量级IOC框架Guice