找出数列中个数大于总数一半的元素

这篇博文讨论了一种面试常考题——找出数列中出现次数超过一半的元素。文中指出了常见代码的错误,并提出了一种巧妙的解决方案,利用核心值特性,通过两个辅助变量进行计数。当计数器count不为0时,最后的coreNum即为所求元素。若count为1,需要二次验证,以避免错误结果,如数组{2,2,2,3,3,3,4}的情况。" 98212125,7337509,Vue 数据更新与视图同步问题解析,"['Vue', '数据绑定', '响应式', '数组操作', '对象属性']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有一些公司招聘时还在用这个题目,但是网上流传的代码有问题,所以有必要发一篇博文。解决这个问题的算法有很多种,最巧妙的算法思路我提一嘴。该算法充分利用了核心值特性(也就是出现次数超过一半的值),利用两个辅助变量coreNum,count。coreNum用于临时存储数组中的数据,count用于存储某个数出现的次数。开始时coreNum存储数组中的第一个数,count为0,如果数组出现的数于coreNum相等,则count加1,否则就减1。如果count为0,就把当前数组中的数赋给coreNum,count设为1。因为指定的数出现的次数大于数组长度的一半,所有count++与count--相抵消之后,最后count的值是大于1的,coreNum中存的那个数就是出现最多的那个数。小于1,则返回-1,表示没有找到coreNum。当等于1时,需要进行特殊检查。网上流传的代码有问题,对于形如{2,2,2,3,3,3,4}。这样的数据其实是无解的。但网上流传的代码会返回4。

发现该问题后,我做了一些简单粗暴的改进,也是当count为1时,再次线性扫描一遍来做最终的验证。

class Program
    {
        static int[] testArray = { 2,2,2,3,3,3,3,3,3,3,5,6,6 };

        static int searchCoreNum(int[] nums)
        {
            if (nums == null || nums.Length == 0)
            {
                return -1;
            }

            int coreNum = 0, count = 0;
            for (int i = 0; i < nums.Length; i++)
            {
                if (count == 0 ) 
                {
                    coreNum = nums[i];
                    count = 1;
                }
                else
                {
                    if (coreNum == nums[i])
                        count++;
                    else
                        count--;
                }
            }
          
            if (count > 1)
                return coreNum;
            else if (count == 1)
            {
                int reCount = 0;
                foreach (int num in nums)
                    if (num == coreNum) reCount++;
                if (reCount > nums.Length / 2)
                    return coreNum;
                else
                    return -1;
            }
            else
                return -1;
        }
        
        static void Main(string[] args)
        {
            Console.WriteLine(searchCoreNum(testArray));
            Console.ReadKey();
        }
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值