找出整形数组中超过一半的数 | 豆包MarsCode KK 刷题 No.8

46 阅读1分钟

哈希表ko了。问了一下豆包有没有复杂度更低的解法。然后看到了这个基于数学的一个小trick。摩尔投票。

image.png

只要数字超过半数,通过这种方式,candidate一定存放的是目标数字。可以用反证法证明。(略)

下面记录我的代码和摩尔投票的代码。

哈希

#include <iostream>
#include <vector>
#include<map>
using namespace std;

int solution(vector<int> array) {
    // Edit your code here
    map<int,int>m;
    for(int i=0;i<array.size();i++){
        m[array[i]] +=1;
        if(m[array[i]]>array.size()/2) return array[i];
    }
    return 0;
}

int main() {
    // Add your test cases here
    
    cout << (solution({1, 3, 8, 2, 3, 1, 3, 3, 3}) == 3) << endl;
    
    return 0;
}

摩尔投票


#include <iostream>
#include <vector>
using namespace std;

int solution(vector<int> array) {
    int candidate = 0;
    int count = 0;
    
    // 第一遍遍历,找出候选者
    for (int num : array) {
        if (count == 0) {
            candidate = num;
        }
        count += (num == candidate) ? 1 : -1;
    }
    
    // 第二遍遍历,验证候选者是否出现次数超过一半
    count = 0;
    for (int num : array) {
        if (num == candidate) {
            count++;
        }
    }
    
    if (count > array.size() / 2) {
        return candidate;
    } else {
        // 题目保证一定存在这样的数字,所以这里理论上不会执行
        return -1;
    }
}

int main() {
    // 添加你的测试用例
    cout << (solution({1, 3, 8, 2, 3, 1, 3, 3, 3}) == 3) << endl;
    return 0;
}