找出整型数组中占比超过一半的数(javascript版)-豆包marscode算法刷题

75 阅读1分钟

问题描述

小R从班级中抽取了一些同学,每位同学都会给出一个数字。已知在这些数字中,某个数字的出现次数超过了数字总数的一半。现在需要你帮助小R找到这个数字。

测试样例

样例1:

输入:array = [1, 3, 8, 2, 3, 1, 3, 3, 3]
输出:3

样例2:

输入:array = [5, 5, 5, 1, 2, 5, 5]
输出:5

样例3:

输入:array = [9, 9, 9, 9, 8, 9, 8, 8]
输出:9

题解


function solution(array) {
    let candidate = null;
    let count = 0;

    // Phase 1: Find a candidate
    for (let num of array) {
        if (count === 0) {
            candidate = num;
        }
        count += (num === candidate) ? 1 : -1;
    }

    // Phase 2: Verify the candidate
    count = 0;
    for (let num of array) {
        if (num === candidate) {
            count++;
        }
    }

    if (count > Math.floor(array.length / 2)) {
        return candidate;
    } else {
        throw new Error("No majority element found");
    }
}

function main() {
    // Add your test cases here
    console.log(solution([1, 3, 8, 2, 3, 1, 3, 3, 3]) === 3);
    console.log(solution([5, 5, 5, 1, 2, 5, 5]) === 5);
    console.log(solution([9, 9, 9, 9, 8, 9, 8, 8]) === 9);
}

main();

解题思路

要解决这个问题,我们可以使用摩尔投票算法(Boyer-Moore Voting Algorithm)。该算法能够在O(n)的时间复杂度和O(1)的空间复杂度内找到出现次数超过一半的数字。

  1. Phase 1: 找到候选者

    • 初始化候选者candidatenull,计数器count为0。
    • 遍历数组nums,如果count为0,则将当前数字设为候选者。
    • 如果当前数字等于候选者,则count加1,否则减1。
  2. Phase 2: 验证候选者

    • 重置计数器count为0。
    • 再次遍历数组nums,统计候选者出现的次数。
    • 如果候选者出现次数超过数组长度的一半,则返回该候选者,否则抛出错误。