1)桶结构
当数组中每个元素的大小范围给定时并且不超过空间限制时,用该数组的下标或下标+偏移量映射为该值的大小,数组的值表示该数字出现的次数的数据结构 优点:有效提高数据的访问效率和处理速度 缺点:必须知道每个元素的大小范围并且能够映射到
[
0
,
N
]
[0,N]
[ 0 , N ] 才可以使用
一本通 1186:出现次数超过一半的数
1:桶做法
# include <bits/stdc++.h>
# define x first
# define y second
using namespace std;
typedef long long ll;
typedef pair< int , int > PII;
const int N= 1e2 + 10 ;
int a[ N] ;
int main ( ) {
int n;
cin>> n;
for ( int i= 1 ; i<= n; i++ ) {
int temp;
cin>> temp;
a[ temp+ 50 ] ++ ;
}
bool flag= false;
for ( int i= 1 ; i<= 99 ; i++ ) {
if ( a[ i] > n/ 2 ) {
flag= true;
cout<< i- 50 ;
}
}
if ( flag== false) cout<< "no" ;
return 0 ;
}
2:map做法
m
a
p
map
ma p 是
C
+
+
C++
C + + STL库中自带的一种数据结构,可以理解为
P
y
t
h
o
n
Python
P y t h o n 中的
d
i
c
t
dict
d i c t 字典数据结构,map中有两个关键字,一个是键(索引),一个是键值,它是一个二元组,和本题不谋而合,让第一个关键字存储这个值的大小,第二关键字存储出现的次数即可,而且不用考虑从
[
−
49
,
49
]
[-49,49]
[ − 49 , 49 ] 映射到
[
1
,
99
]
[1,99]
[ 1 , 99 ]
# include <bits/stdc++.h>
# define x first
# define y second
using namespace std;
typedef long long ll;
typedef pair< int , int > PII;
const int N= 1e5 + 5 ;
int main ( ) {
map< int , int > m;
int n;
cin>> n;
for ( int i= 1 ; i<= n; i++ ) {
int temp;
cin>> temp;
m[ temp] ++ ;
}
bool flag= false;
for ( auto it= m. begin ( ) ; it!= m. end ( ) ; it++ ) {
if ( it-> second> n/ 2 ) {
flag= true;
cout<< it-> first;
}
}
if ( flag== false) cout<< "no" ;
return 0 ;
}
2)桶排序
当数据入桶后其实就相当于已经排好了序,我们可以从元素最小值遍历到最大值,又因为桶中的元素代表着这个元素出现的次数,那么出现了多少次我们就输出多少次这个元素,又因为是从小到大遍历的,所以倒桶的过程就是桶排序 桶排序的时间复杂度是
O
(
n
)
O(n)
O ( n ) ,其中n是元素个数
# include <bits/stdc++.h>
# define x first
# define y second
using namespace std;
typedef long long ll;
typedef pair< int , int > PII;
const int N= 1e3 + 5 ;
int a[ N] ;
int main ( ) {
int n;
cin>> n;
while ( n-- ) {
int temp;
cin>> temp;
a[ temp] ++ ;
}
for ( int i= 1 ; i<= 1000 ; i++ ) {
if ( a[ i] ) {
for ( int j= a[ i] ; j> 0 ; j-- ) {
cout<< i<< ' ' ;
}
}
}
return 0 ;
}