问题描述
小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)的空间复杂度内找到出现次数超过一半的数字。
-
Phase 1: 找到候选者
- 初始化候选者
candidate为null,计数器count为0。 - 遍历数组
nums,如果count为0,则将当前数字设为候选者。 - 如果当前数字等于候选者,则
count加1,否则减1。
- 初始化候选者
-
Phase 2: 验证候选者
- 重置计数器
count为0。 - 再次遍历数组
nums,统计候选者出现的次数。 - 如果候选者出现次数超过数组长度的一半,则返回该候选者,否则抛出错误。
- 重置计数器