排序算法笔记--摩尔投票算法

摩尔投票算法

摩尔投票算法是一种用于在数组中查找出现次数超过一半的元素的有效算法。算法的核心思想是利用候选元素和计数器进行投票,通过消除不同元素之间的抵消来找到出现次数超过一半的元素。

算法原理

如果数组中存在一个出现次数超过一半的元素,那么这个元素的剩余部分一定会抵消其他元素的出现次数,最终剩下的就是该元素。

算法步骤

  1. 初始化候选元素 candidate 为数组的第一个元素,计数器 count 为 1。
  2. 从数组的第二个元素开始遍历。
  3. 如果当前元素与候选元素相同,则将计数器 count 加 1。
  4. 如果当前元素与候选元素不同,则将计数器 count 减 1。
  5. 如果计数器 count 减为零,则更新候选元素为当前元素,并将计数器 count 重置为 1。
  6. 完成遍历后,候选元素就是出现次数超过一半的元素。

实例

例子:

假设数组为 2, 2, 1, 1, 1, 2, 2

  • 初始时,候选元素 candidate 为 2,计数器 count 为 1。
  • 开始遍历数组:
    • 遍历到 2,与候选元素相同,计数器 count 加 1,计数器变为 2。
    • 遍历到 1,与候选元素不同,计数器 count 减 1,计数器变为 1。
    • 遍历到 1,与候选元素不同,计数器 count 减 1,计数器变为 0。
    • 计数器 count 变为 0,更新候选元素为当前元素 1,计数器 count 重置为 1。
    • 遍历到 1,与候选元素相同,计数器 count 加 1,计数器变为 2。
    • 遍历到 2,与候选元素相同,计数器 count 加 1,计数器变为 1。
    • 遍历到 2,与候选元素相同,计数器 count 加 1,计数器变为 0。
    • 计数器count变为0,更新候选元素为当前元素2,计数器count重置为2

完成遍历后,候选元素为 2,它是出现次数超过一半的元素

解题模板

java 复制代码
class Solution {
    public int majorityElement(int[] nums) {
        int candidate = nums[0];
        int count = 1;
        
        for (int i = 1; i < nums.length; i++) {
            if (count == 0) {
                candidate = nums[i];
                count = 1;
            } else if (nums[i] == candidate) {
                count++;
            } else {
                count--;
            }
        }
        
        return candidate;
    }
}

题目:寻找发帖的水王

当水王发帖数大于一半时,直接使用模板进行解答:

java 复制代码
public class test1 {
    //出现次数大于一半
    public int  solve(int []arr){
        int candidate = arr[0];
        int count =1;
        for(int i =1;i<arr.length;i++){
            if(count == 0){
                candidate = arr[i];
                count =1;
            }else if(arr[i] == candidate){
                count++;
            }else{
                count--;
            }
        }
        return candidate;
    }
 }

题目变形:当水王发帖数刚好等于一半时,需要判断寻找元素是否是最后一位

java 复制代码
//寻找发帖水王 出现次数刚好是一半
    public static void solve1(int[] arr){
        int candidate = arr[0];
        int nTimes =0;
        int countOfLast = 0;
        int N = arr.length;
        for(int i =0;i<N;i++){
            if(arr[i] == arr[N-1]){
                countOfLast++;
            }
            if(nTimes ==0){
                candidate = arr[i];
                nTimes =1;
                continue;
            }
            if (arr[i] == candidate){
                nTimes++;
            }else{
                nTimes--;
            }
        }
        if(countOfLast == N/2){
            System.out.println(arr[N-1]);
        }else{
            System.out.println(candidate);
        }
    }
相关推荐
mCell7 小时前
Lua 编程入门:从基础语法到元表
javascript·算法·lua
wuyk5559 小时前
98.C语言易混难点:字符数组与字符串指针的底层差异
c语言·开发语言·c++·stm32·嵌入式硬件·算法
峥无9 小时前
从0到1手撕红黑树:封装实现 my_map 与 my_set(SGI-STL 源码级深度解析)
开发语言·c++·笔记·算法·stl
不会代码的小猴10 小时前
3. 控件学习1
开发语言·c++·笔记·qt·算法
疯狂打码的少年11 小时前
【数据结构】图的存储结构:邻接矩阵与邻接表
数据结构·笔记
203号居民12 小时前
LeetCode hot 100 —41. 缺失的第一个正数
数据结构·算法·leetcode
专注仿真14 小时前
问答大模型技术方案算法实现-熵权法融合算法 + 交叉编码器重排算法
人工智能·python·算法·语言模型·问答大模型关键算法·熵权融合算法·交叉编码器重排算法
地平线开发者15 小时前
量化为什么会有损失:从量化误差到精度下降
算法
手写码匠15 小时前
华为云Flexus+DeepSeek征文|Dify 多 Agent 会话管理与上下文工程实战:让智能体“记住该记住的,忘掉该忘掉的“
人工智能·深度学习·算法·aigc