【附JS、Python、C++题解】Leetcode面试150题(12)多数问题

一、题目

169. 多数元素

给定一个大小为 n的数组 nums ,返回其中的多数元素。

多数元素是指在数组中出现次数大于[n/2]的元素。你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:

复制代码
输入:nums = [3,2,3]
输出:3

示例 2:

复制代码
输入:nums = [2,2,1,1,1,2,2]
输出:2

二、思路

  1. 本题的关键就是用什么方法统计元素出现的次数,由此会引出多种解法。

① 参考前面题目的先排序后处理 思路,在这里也可以先进行排序,一个很有用的信息是,我们要找的多数元素,出现次数必须≥n/2,这意味着排序后的中位数一定就是这个多数元素

②Boyer-Moore 投票算法:这种算法的核心思想是通过"投票"机制来找到多数元素。每个元素都可以看作是一张票,投给当前的候选元素。

  • 当遇到相同的元素时,计数器增加,表示支持当前候选元素的票数增加。
  • 当遇到不同的元素时,计数器减少,表示反对当前候选元素的票数增加。
  • 当计数器为 0 时,说明当前没有候选元素,可以选择当前元素作为新的候选元素。

在这道题中:

  • 设置一个计数器 count,初始值为 0。
  • 设置一个候选元素 candidate,初始值为 null

对于数组中的每个元素 num,如果 num 不等于当前候选元素 candidate,将 count 减 1。如果 num 等于当前候选元素 candidate,将 count 加 1。如果 count 为 0,说明当前没有候选元素,将 num 设为候选元素。

③ 可以用哈希表来简化问题(主要是降低时间复杂度)。这里的映射很明显就是数组元素和元素出现次数之间的映射,也就是可以借助哈希表中的键值对匹配来判断出现次数要不要+1.具体见后续的代码。

三、代码

解法一:先排序后处理

① JavaScript:

javascript 复制代码
 function countTimes(nums){
    let n = nums.length;
    nums.sort((a,b)=>a-b);
    return nums[Math.floor(n/2)];
//这里的Math.floor可以确保结果是一个整数,即向下取整。
}

② C++:

cpp 复制代码
int majorityElement(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        return nums[nums.size() / 2];
}

③ Python:

python 复制代码
def majorityElement(nums]):
    nums.sort()
    return nums[len(nums) // 2]

解法二:Boyer-Moore投票算法

① JavaScript:

javascript 复制代码
function countTimes(nums){
    let major = null
    let count = 0
    for (let num of nums) {
        if (count === 0) {
            major = num
        }
        if (major === num) {
            count++
        } else {
            count--
        }
    }
    return major
}

② C++:

cpp 复制代码
int countTimes(const std::vector<int>& nums) {
    int major = 0;
    int count = 0;
    for (int num : nums) {
        if (count == 0) {
            major = num;
        }
        if (major == num) {
            count++;
        } else {
            count--;
        }
    }
    return major;
}

③ Python:

python 复制代码
def count_times(nums):
    major = None
    count = 0
    for num in nums:
        if count == 0:
            major = num
        if major == num:
            count += 1
        else:
            count -= 1
    return major

解法三:哈希表

① JavaScript:

javascript 复制代码
function countTimes (nums) {
    let hashTable = {};
    let n = nums.length;

    // 遍历数组,统计每个元素的出现次数
    for (let num of nums) {
        if (hashTable[num] == null) {
            hashTable[num] = 1;
        } else {
            hashTable[num]++;
        }
    }

    // 找到出现次数大于 n/2 的元素
    for (let num in hashTable) {
        if (hashTable[num] > Math.floor(n / 2)) {
            return parseInt(num);
        }
    }

    return null;  // 如果没有多数元素,返回 null
};

② C++:

cpp 复制代码
int countTimes(const std::vector<int>& nums) {
    unordered_map<int, int> hashtable;
    int n = nums.size();

    // 遍历数组,统计每个元素的出现次数
    for (int num : nums) {
        hashtable[num]++;
    }

    // 找到出现次数大于 n/2 的元素
    for (const auto& pair : hashtable) {
        if (pair.second > n / 2) {
            return pair.first;
        }
    }

    return -1;  // 如果没有多数元素,返回 -1
}

③ Python:

python 复制代码
def count_times(nums):
    # 使用 Counter 统计每个元素的出现次数
    counter = Counter(nums)
    n = len(nums)

    # 找到出现次数大于 n/2 的元素
    for num, count in counter.items():
        if count > n / 2:
            return num

    return None  # 如果没有多数元素,返回 None

四、反思

  1. 之前并不了解Boyer-Moore投票算法,从这道题来看该算法很适合用于高性能要求/内存限制高的题目;

  2. 一定要抓住题目中的信息,比如这道题中的n/2,想清楚以后可以简化我们的代码(帮助我们确定中位数一定也就是众数,也就是多数元素)。

相关推荐
niuniu_66632 分钟前
selenium应用测试场景
python·selenium·测试工具·单元测试·测试
满怀10152 小时前
Python扩展知识详解:lambda函数
开发语言·python
梭七y2 小时前
【力扣hot100题】(022)反转链表
算法·leetcode·链表
蓝博AI4 小时前
基于卷积神经网络的眼疾识别系统,resnet50,efficentnet(pytorch框架,python代码)
pytorch·python·cnn
牧歌悠悠5 小时前
【Python 算法】动态规划
python·算法·动态规划
Doris Liu.7 小时前
如何检测代码注入(Part 2)
windows·python·安全·网络安全·网络攻击模型
逢生博客7 小时前
阿里 FunASR 开源中文语音识别大模型应用示例(准确率比faster-whisper高)
人工智能·python·语音识别·funasr
噔噔噔噔@7 小时前
软件测试对于整个行业的重要性及必要性
python·单元测试·压力测试
猫猫不是喵喵.7 小时前
vue 路由
前端·javascript·vue.js
赵谨言8 小时前
基于Python的Django框架的个人博客管理系统
经验分享·python·毕业设计