多数元素题解

题目:

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

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

前置点播:

 

摩尔投票法(Moore's Voting Algorithm)的核心思想是通过两两抵消不同的元素,最终剩下的元素就是出现次数超过一半的元素。以下是其具体的思想和步骤介绍:

  • 核心思想:在任何数组中,出现次数超过一半的元素,其出现次数比其他所有元素出现次数的总和还要多。因此,可以通过不断抵消不同的元素,来找到那个出现次数超过一半的元素。
  • 算法步骤
    • 初始化:设置一个候选元素candidate和一个计数器count,初始时count为 0。

    • 遍历数组:对于数组中的每个元素num,如果count为 0,就将candidate设置为当前元素num,并将count加 1;如果count不为 0,且当前元素num等于candidate,则将count加 1;如果count不为 0,且当前元素num不等于candidate,则将count减 1。

    • 最终结果:遍历完数组后,candidate中存储的就是出现次数超过一半的元素。

摩尔投票法的时间复杂度为(O(n)),其中n是数组的长度,因为只需要遍历数组一次。空间复杂度为(O(1)),因为只需要常数级别的额外空间来存储候选元素和计数器。

代码:

int majorityElement(int* nums, int numsSize) 
{
    int candidate = nums[0], count = 1;  // 初始化候选元素和计数器
    for (int i = 1; i < numsSize; i++) 
    {                                    // 从第二个元素开始遍历
        if (count == 0) 
        {                                // 当前候选已被完全抵消
            candidate = nums[i];         // 更新候选为当前元素
            count = 1;                   // 重置计数器
        } else if (nums[i] == candidate) // 当前元素支持候选
        {                                
            count++;                      // 增加支持数
        } else                            // 当前元素反对候选 
        {                                
            count--;                     // 减少支持数(抵消)
        }
    }
    return candidate;  // 返回最终的候选元素(题目保证存在)
}

 代码分析:

1. 初始化阶段

int candidate = nums[0], count = 1;

  • candidate:初始化为数组的第一个元素,作为首个候选多数元素。

  • count:初始化为1,表示当前候选的支持次数。

2. 遍历数组(从第二个元素开始)

for (int i = 1; i < numsSize; i++) 
  • 从索引 1 开始遍历,逐个处理数组元素。

3. 处理候选抵消逻辑

if (count == 0)                   // 当前候选已被完全抵消
{                       
    candidate = nums[i];         // 更新候选为当前元素
    count = 1;                   // 重置计数器
}
  • 触发条件:当 count 降为0时,表示

    else if (nums[i] == candidate)     // 当前元素支持候选
    {  
        count++;                      // 增加支持数
    } else                            // 当前元素反对候选         
    {                         
        count--;                     // 减少支持数(抵消)
    }
  • 操作:将当前元素设为新候选,并重置 count = 1

4. 处理支持或抵消

  • 支持候选:若当前元素与候选相同,增加计数器。

  • 抵消候选:若不同,减少计数器(模拟对抗抵消)。

5. 返回结果

return candidate;

  • 直接返回最终的 candidate

其他算法比较:

方法 时间复杂度 空间复杂度 是否依赖题目保证(存在多数元素)
摩尔投票法 O(n)O(n) O(1)O(1) 是(若不确定需遍历验证)
哈希表统计法 O(n)O(n) O(n)O(n) 否(可自行验证)
排序取中位数法 O(nlog⁡n)O(nlogn) O(1)O(1)

你可能感兴趣的:(算法,c语言,leetcode)