返回
发现数据世界的隐秘宝藏——算法揭示数组中反复出现的数字及最小的数字
前端
2023-09-29 16:26:40
算法的世界里,总有一些神奇的操作能够帮助我们解决各种各样的问题。今天,我们就来看看一个非常有趣的算法问题——找出数组中出现次数超过一半的数字以及最小的k个数。
寻找数组中出现次数超过一半的数字
首先,我们来看一下如何找到数组中出现次数超过一半的数字。这个问题乍一看似乎很难,但实际上有一个非常简单的算法可以解决它。这个算法叫做“摩尔投票法”。
摩尔投票法的基本思想是,如果一个数字出现次数超过数组长度的一半,那么它在数组中出现的次数肯定会比其他任何数字都多。因此,我们可以先给这个数字记上1票,然后遍历整个数组,如果遇到相同的数字就给它记上1票,如果遇到不同的数字就把之前记的票减1票。如果在遍历完整个数组之后,这个数字的票数仍然大于0,那么它就是出现次数超过一半的数字。
function findMajorityElement(arr) {
let count = 0;
let majorityElement = null;
for (let i = 0; i < arr.length; i++) {
if (count === 0) {
majorityElement = arr[i];
count = 1;
} else {
if (majorityElement === arr[i]) {
count++;
} else {
count--;
}
}
}
if (count > 0) {
return majorityElement;
}
return null;
}
寻找数组中最小的k个数
接下来,我们再来看看如何找到数组中最小的k个数。这个问题同样有一个非常简单的算法可以解决它,这个算法叫做“快速选择算法”。
快速选择算法的基本思想是,我们可以通过一次划分将数组分成两部分,一部分包含所有大于等于第k个最小数字的数字,另一部分包含所有小于第k个最小数字的数字。然后,我们只需要在其中一部分中继续寻找第k个最小数字即可。
function findKthSmallestElement(arr, k) {
if (arr.length < k) {
return null;
}
return quickSelect(arr, 0, arr.length - 1, k);
}
function quickSelect(arr, left, right, k) {
if (left === right) {
return arr[left];
}
let pivotIndex = partition(arr, left, right);
if (pivotIndex === k - 1) {
return arr[pivotIndex];
} else if (pivotIndex < k - 1) {
return quickSelect(arr, pivotIndex + 1, right, k);
} else {
return quickSelect(arr, left, pivotIndex - 1, k);
}
}
function partition(arr, left, right) {
let pivot = arr[right];
let i = left - 1;
for (let j = left; j < right; j++) {
if (arr[j] < pivot) {
i++;
swap(arr, i, j);
}
}
swap(arr, i + 1, right);
return i + 1;
}
function swap(arr, i, j) {
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
希望这些算法能够帮助你解决你遇到的问题。如果你还有其他问题,欢迎随时咨询我。