• 众数(Mode)算法


      1.求众数有很多种解法,直觉上第一种就是用哈希表统计,这种方法需要O(n)的时间和空间。另一种叫摩尔投票法,需要O(n)的时间和O(1)的空间,比哈希表要好,这种投票法先将第一个数字假设为众数,然后把计数器设为1,比较下一个数和此数是否相等,若相等则计数器加1,否则计数器减1.然后看此时计数器的值,若为0,则将下一个值设为候选众数。以此类推直到遍历完整个数组,当前候选众数即为该数组的众数。精妙!通俗的讲,他是把原数组精简化,相互抵消。首先是有个强大的前提存在,就是众数一定存在。如果计数器减到0了,说明目前不是候选者的数字的个数已经跟候选者出现的个数相同了,那么这个候选者已经很weak,不一定能出现超过半数,我们选择更换当前的候选者。那么可能你会有疑问,那万一后面又大量出现了之前的候选者怎么办,不需要担心,如果之前的候选者在后面大量出现的话,其又会重新变为候选者,直到最终验证成为正确的众数。

    using System;
    using System.Windows.Forms;
    
    namespace repo.素材
    {
        public partial class ModeSolve : Form
        {
            public ModeSolve()
            {
                InitializeComponent();
            }
            /// <summary>
            /// 求众数
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void button1_Click(object sender, EventArgs e)
            {
                // 
                int[] numer = new int[] { 3, 3, 0, 1, 3, 2, 4 };
                int mresult = majorityElement(numer); //majorityElementIO(numer);
    
                // 
                System.Diagnostics.Debug.WriteLine(mresult);
            }
            /// 哈希表统计,需要O(n)的时间和空间。
            /// 摩尔投票法,需要O(n)的时间和O(1)的空间。
            /// 位操作方法  需要O(n)的时间和>O(n)的空间。
    
            // 摩尔投票法-目前只能适用于众数个数>数组个数一般的情况
            public int majorityElement(int[] nums)
            {
                int cnt = 1;
                int res = nums[0];
                for (int i = 1; i < nums.Length; i++)
                {
                    //也可直接遍历数组for(int num:nums)
                    if (cnt == 0)
                    {
                        res = nums[i];
                    }
                    if (res == nums[i]) ++cnt;
                    else --cnt;
                }
                // 不能得出众数验证
                int resNumber = 0;
                for (int i = 0; i < nums.Length; i++)
                {
                    if (res == nums[i])
                    {
                        resNumber++;
                    }
                }
                if (resNumber >= nums.Length/2)
                {
                    return res;
                }
                else
                {
                    return 2147483647;
                }
            }
            // 位操作法-未调试
            public int majorityElementIO(int[] nums)
            {
                int res = 0, n = nums.Length;
                for (int i = 0; i < 32; ++i)
                {
                    int ones = 0, zeros = 0;
                    for (int num=0; num< n;num++)
                    {
                        if (ones > n / 2 || zeros > n / 2) break;
                        if ((num & (1 << i)) != 0) ++ones;
                        else ++zeros;
                    }
                    if (ones > zeros) res |= (1 << i);
                }
                return res;
            }
        }
    }

    原文:求众数[Leetcode](https://www.cnblogs.com/zhlz/p/10486072.html)

    365个夜晚,我希望做到两天更一篇博客。加油,小白!
  • 相关阅读:
    Control Group(CGroup)资源限制组
    系统安全之用户认证
    如何在Linux中禁用和挂起休眠
    ubuntu18 virtualbox启动失败Kernel driver not installed (rc=-1908)
    C# Winform 多线程更新界面UI控件,解决界面卡顿问题(转)
    【573】LaTeX相关技巧
    程序计时函数
    王炸!!Spring 终于对 JVM 动手了…
    ThreadLocalRandom 是线程安全的吗?
    Spring Boot 应用可视化监控,一目了然!
  • 原文地址:https://www.cnblogs.com/qq2806933146xiaobai/p/13213791.html
Copyright © 2020-2023  润新知