【牛客网】—— 出现次数大于n/2的数

上篇博客讲到 2017年校招真题之倒置字符串 的三种解法,今天来介绍一下校招真题中的出现次数超过n/2的数的解法

2017年校招真题 出现次数大于n/2的数

题目描述

输入n个整数,输出出现次数大于等于数组长度一半的数。
输入描述:

每个测试输入包含 n个空格分割的n个整数,n不超过100,其中有一个整数出现次数大于等于n/2。

输出描述:

输出出现次数大于等于n/2的数。

示例1

输入 : 3 9 3 2 5 6 7 3 2 3 3 3
输出 : 3

解题思路

  • 解法一
    思路是通过unordered_map统计每个数出现的次数,再遍历unordered_map,找出出现次数超过数组大小一半的数,输出即可,有兴趣的读者可以参考博客 unordered_map/set的应用 有很多类似的题目
    在这里插入图片描述
  • 解法二
    思路是将出现的数放入vector数组中,对数组进行排序,若是某个数出现次数超过了数组个数的一半,那么整个数组中间的那个数必然是该数,输出数组中间那个数即可。
    时间空间复杂度
  • 解法三
    O(n)思想:因为要找过半的数,用一个变量count记录读取每个变量变化的次数,一个变量temp记录可能过半的数,先让count=1,然后让temp=v [0],然后往后遍历一遍,碰到和temp相同的数就给count++,否则就count–,如果,count变成0,就让(vector数组遍历过程中的当前值),并让count=1,如此遍历一遍,因为有一个数过半,所以temp最后肯定存储的是过半的数时间空间复杂度

代码实现

  • 解法一
#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;

int main()
{
    int n;
    vector<int> v;
    while(cin >> n)
        v.push_back(n);
    
    unordered_map<int,int> countmp;
    for(auto& e : v)
    {
        countmp[e]++;
    }
    
    for(auto& kv : countmp)
    {
        if(kv.second >= v.size()/2)
            cout << kv.first << endl;
    }
    return 0;
}
  • 解法二
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    int n;
    vector<int> v;
    while(cin >> n)
        v.push_back(n);
    
    sort(v.begin(),v.end());
    
    cout << v[v.size()/2 - 1] <<endl;
    return 0;
}
  • 解法三
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    int n;
    vector<int> v;
    while(cin >> n)
        v.push_back(n);
    int count = 1,temp = v[0];
    for(int i = 0;i < v.size();++i)
    {
        if(v[i] == temp)
            count++;
        else
            count--;
        if(count == 0)
        {
            temp = v[i];
            count = 1;
        }
    }
    cout << temp <<endl;
    return 0;
}
发布了167 篇原创文章 · 获赞 175 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/chenxiyuehh/article/details/90603906