LeetCode 169.多数元素:摩尔投票法

1 阅读2分钟

前言

今天没有解出来,我想用选择排序后,直接返回中间值但选择排序的边界选错了,返回中间值也写错了


一、题目再解读

原题题干

给定一个大小为 n **的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

 

示例 1:

输入: nums = [3,2,3]
输出: 3

示例 2:

输入: nums = [2,2,1,1,1,2,2]
输出: 2

二、新手踩坑实录(我的反思复盘)

/** * @param {number[]} nums * @return {number} */ 
var majorityElement = function (nums) {
    let len = nums.length;
    function swap(x, y) {
    let temp = nums[x];
    nums[x] = nums[y];
    nums[y] = temp;
    for (let i = 1; i < len - 1; i++) { 
        let max = 0; 
        for (let j = 0; j <= len - i; j++) {
            if (nums[j] > nums[max]) { 
                max = j;
            } 
        }    
        if (max != 0) { 
            swap(max, len - i); 
        } 
    } 
    let index=len/2+1; 
    return nums[index]; 
    };
  1. index = len/2 +1 写错

应该是 向下取整的中间下标

js

let index = Math.floor(len / 2);
  1. 排序逻辑完全错误

你的选择排序根本没排对

  1. 循环边界错误

js

for (let i=1; i<len-1; i++)
/** * @param {number[]} nums * @return {number} */ 
var majorityElement = function (nums) {
    let len = nums.length;
    function swap(x, y) {
    let temp = nums[x];
    nums[x] = nums[y];
    nums[y] = temp;
    for (let i = 0; i < len ; i++) { 
        let maxIndex = 0; 
        for (let j = 0; j < len - i; j++) {
            if (nums[j] > nums[maxIndex]) { 
                maxIndex = j;
            } 
        }    
        if (maxIndex != 0) { 
            swap(maxIndex, len - i-1); 
        } 
    } 
    let index=Math.floor(len/2);
    return nums[index]; 
    };

三、最优解法:摩尔投票法(O (n) 时间 + O (1) 空间)

解法思路

同归于尽抵消法

  • 相同的数 → 队友
  • 不同的数 → 敌人
  • 一个队友抵消一个敌人
  • 因为众数人数最多,最后一定活下来!
var majorityElement = function(nums) {
    let count=0;
    let res=null;
    
    for(let num of nums){
        if(count===0) res=num;
        count+=(res==num?1:-1);
    }
};

四、复杂度分析

时间复杂度:O(n),数组仅遍历一次,移动总次数不超过n

空间复杂度:O(1),仅用了两个变量,无额外数组空间开销,完全符合题目要求


结语

还得继续学习,解法不够优秀,思考太久,写博客也写了很久,以后写快点 加油加油