算法笔记三 求序列中出现次数大于序列长度一半的元素
题干
给定一个序列vector A, 返回序列中出现次数大于序列长度一半的元素, 若不存在该元素则返回0
解题思路
方法1
将A排序不影响最终的结果, 故首先应该想到, 经过快排之后, 如果A存在该元素, 中间位置的元素(A[len/2])必定是所求元素, 故问题转换为是否存在该元素. 我们任取元素tmp = A[i], 如果A[i]满足条件,那么经过排序后, A[i+len/2] == A[i], 直接返回A[len/2]即可. 时间复杂度为
O
(
n
l
o
g
n
+
n
)
=
O
(
n
l
o
g
n
)
O(nlogn+n)=O(nlogn)
O(nlogn+n)=O(nlogn)
c++实现如下
int sortSol(vector<int> &A){
sort(A.begin(), A.end());
int len = A.size();
for(int i=0; i<=len/2; i++){
if(A[i] == A[i+len/2]) return A[len/2];
}
return 0;
}
方法2
另一种思路是利用map<int, int>, key取为A的元素, value取为该元素出现的次数,遍历一遍序列A即可时间复杂度为
O
(
n
)
O(n)
O(n)
c++实现如下
int hashSol(vector<int> &A) {
sort(A.begin(), A.end());
map<int, int> count;
int len = A.size();
for (int i = 0; i < len; i++) {
int tmp = A[i];
map<int, int>::iterator iter = count.find(tmp); // 查找map中是否已存在该元素
if(iter!=count.end()){
count[tmp]++;
}else{
count.insert(pair<int, int>(tmp, 1));
}
if(count[tmp] > len/2)
return tmp;
}
return 0;
}