代码训练LeetCode(18)多数元素

代码训练(18)LeetCode之多数元素

Author: Once Day Date: 2024年9月13日

漫漫长路,才刚刚开始...

全系列文章可参考专栏: 十年代码训练_Once-Day的博客-CSDN博客

参考文章:

文章目录

1. 原题

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

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

提示:

  • n == nums.length
  • 1 <= n <= 5 * 104
  • -109 <= nums[i] <= 109

示例 1:

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

示例 2:

yacas 复制代码
输入:nums = [2,2,1,1,1,2,2]
输出:2
2. 分析

本题目要求找出一个数组中的多数元素,即出现次数大于数组长度一半的元素。题目保证了这样的元素总是存在。

常见解题方法:

  • 哈希表法:使用哈希表记录每个元素的出现次数,然后遍历哈希表找到出现次数大于 n/2 的元素。这种方法的时间复杂度是 O(n),但空间复杂度也是 O(n)。
  • 排序法:将数组排序,中间的元素(索引为 n/2)必为多数元素。时间复杂度是 O(nlogn),因为排序的平均时间复杂度为 O(nlogn),空间复杂度取决于排序实现,通常为 O(1) 到 O(n)。
  • 摩尔投票法(Boyer-Moore Voting Algorithm):这是一种时间复杂度为 O(n) 且空间复杂度为 O(1) 的优秀算法。基本思想是两两抵消不同的元素,最后剩下的元素可能是多数元素。

这里将展开摩尔投票法的具体实现步骤:

  1. 初始化一个候选人candidate和计数器count为0。
  2. 遍历数组中的每个元素x:
    • 如果count为0,则将candidate设置为xcount设置为1。
    • 如果x等于candidate,则count加1。
    • 否则,count减1。
  3. 经过上述过程,candidate应该是多数元素。

性能优化关键点

  • 摩尔投票法在时间和空间复杂度上是最优的,时间复杂度为 O(n),空间复杂度为 O(1)。
  • 由于这种算法不需要额外的存储空间(除了几个基本变量),它特别适合处理大数据量的问题。
3. 代码实现
c 复制代码
#include <stdio.h>

int majorityElement(int* nums, int numsSize) {
    int candidate = 0;
    int count = 0;
    
    for (int i = 0; i < numsSize; i++) {
        if (count == 0) {
            candidate = nums[i];
        }
        if (nums[i] == candidate) {
            count++;
        } else {
            count--;
        }
    }
    
    return candidate;
}

这个函数的作用是寻找一个整数数组中的多数元素,即在数组中出现次数超过一半的元素。函数采用了一种名为"摩尔投票算法"(Boyer-Moore Voting Algorithm)的高效方法来实现这一目标。

摩尔投票算法的核心思想是通过一系列的比较和计数来找到可能的候选者,然后验证这个候选者是否真的是多数元素。具体到这个函数,它首先初始化两个变量:candidate用于存储当前的候选者,而count用于记录这个候选者的计数值

函数的处理流程大致如下:

  1. 遍历输入数组nums,数组的大小为numsSize
  2. 对于每个元素nums[i],首先检查count是否为0。如果为0,说明前面的所有候选者都被完全抵消了,需要重新选取当前元素作为新的候选者,并重置计数为1。
  3. 接下来验证当前元素是否等于候选者candidate:
    • 如果相等,则增加count的值,表示候选者获得了支持。
    • 如果不等,则减少count的值,表示候选者失去了一些支持。
  4. 经过一轮完整的遍历后,candidate变量中存储的就是数组中的多数元素。

这个算法的优势在于它的时间复杂度为O(n),空间复杂度为O(1),非常适合处理大数据集。它巧妙地通过抵消机制避免了需要额外存储空间来记录每个元素的出现次数,而是直接在遍历过程中确定可能的多数元素。

4. 总结

对编程能力的考查主要集中在对数组操作的理解和算法效率的优化上。通过此题,可以加深对线性时间算法设计的理解,尤其是摩尔投票算法的巧妙之处。

相关推荐
源代码•宸28 分钟前
Leetcode—322. 零钱兑换【中等】(memset(dp,0x3f, sizeof(dp))
c++·算法·leetcode·职场和发展·dp
机械心29 分钟前
最优化理论与自动驾驶(一):概述
人工智能·算法·自动驾驶
给自己做减法30 分钟前
排序算法快速记忆
java·算法·排序算法
新知图书41 分钟前
Rust的常量
算法·机器学习·rust
DdddJMs__1351 小时前
C语言 | Leetcode题解之第403题青蛙过河
c语言·数据结构·算法
小林熬夜学编程1 小时前
【Linux系统编程】第二十弹---进程优先级 && 命令行参数 && 环境变量
linux·运维·服务器·c语言·开发语言·算法
向阳逐梦1 小时前
ROS 编程入门的介绍
人工智能·算法·机器学习
六点半8881 小时前
【C/C++】涉及string类的经典OJ编程题
c语言·开发语言·c++·算法
Python大数据分析@2 小时前
Python中给定一个数组a = [2,3,9,1,0],找出其中最大的一个数,并打印出来 求解?
python·算法·排序算法
DKPT2 小时前
数据结构之排序的基本概念
java·数据结构·笔记·学习·算法