116 lines
3.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
*https://leetcode.cn/problems/majority-element/description/?envType=study-plan-v2&envId=top-interview-150
* @param {number[]} nums
* @return {number}
*/
const majorityElement = function (nums) {
f1(nums);
f2(nums);
f3(nums, 0, nums.length - 1);
f4(nums);
};
/*
暴力法,遍历所有元素,统计每一个元素出现的次数,之后再遍历统计的结果,统计结果中大于数组长度二分之一的就是我们要找
的多数元素
*/
function f1(nums) {
const countMap = new Map();
// 遍历数组,统计数组元素中每个元素出现的次数
for (const num of nums) {
countMap.set(num, (countMap.get(num) || 0) + 1);
}
// 遍历countMap 找到出现次数大于数组长度一半的元素就是多数元素
const majorityCount = nums.length / 2;
for (const [num, count] of countMap) {
if (count > majorityCount) return num;
}
// 如果没有就返回, 根据题目要求,不会发生这一情况
return null;
}
/*
排序法, 按照题目要求,多数元素一定会大于数组长度的一半, 所以只要把数组拍一个需那么在1/2位置的元素一定是多数
元素why? 我们可以这样思考想象大脑里面有一个进度条进度条现在是51%,移动进度条的颜色部分,无论怎么移动,这个
颜色部分总是会覆盖中间位置, 这里以数组长度3和4为例如果数组长度是3那么中间元素就是 3/2 = 1.5但在js中不会自动
丢弃小数位所以要Math.floor()向下取整再来看看四如果有多数元素这个多数元素一定有三个4/2 = 2,刚好也符合,所以
奇偶无需特殊处理
*/
function f2(nums) {
// 先对数组排序
nums.sort((a, b) => a - b);
return nums[Math.floor(nums.length / 2)];
}
/*
分治法,把大问题化成小问题,把原数组分成左右两部分,找出左右俩部分多数的数,如果这两个数相同就返回这个数,如果
不相同,再比较谁多,返回多的那个
*/
/**
*
* @param {number[]} nums 原数组
* @param {number} left 开始的部分
* @param {number} right 结束的部分
*/
function f3(nums, left, right) {
// 如果left和right相等表明只有一个元素直接返回即可
if (left === right) return nums[left];
// 递归计算左右两部分的多数元素
const mid = Math.floor((left + right) / 2);
const leftMajority = f3(nums, left, mid);
const rightMajority = f3(nums, mid + 1, right);
// 如果左右两边的元素相同,则返回这个元素
if (leftMajority === rightMajority) return leftMajority;
// 如果两个元素不相等,就比较它们谁出现的次数多
const leftMajorityCount = countInRange(nums, left, mid, leftMajority);
const rightMajorityCount = countInRange(nums, mid + 1, right, rightMajority);
return leftMajorityCount > rightMajorityCount ? leftMajority : rightMajority;
}
/**
*
* @param {number[]} nums 要处理的元素组
* @param {number} left 左边界
* @param {number} right 右边界
* @param {number} target 要统计的目标元素
* @description 统计目标元素出现的次数
*/
function countInRange(nums, left, right, target) {
let count = 0;
for (let i = left; i <= right; i++) {
if (nums[i] === target)count++;
}
return count;
}
/*
投票法:假设数组中举行选择,这样的话,多数元素肯定会选举胜利,如果当前选择的元素和自己是一样的那么就投票,不是就反对
是对手票减少一个
*/
function f4(nums) {
if (nums.length === 1) return nums[0];
let count = 1;
let num = nums[0]; // 候选的
for (let i = 1; i < nums.length; i++) {
if (nums[i] === num) {
count++;
} else if (count > 0) {
count--;
} else {
num = nums[i];
count = 1;
}
}
return num;
}
majorityElement([2, 2, 1, 1, 1, 2, 2]);