【自刷 剑指offer39】数组中出现次数超过一半的数字

我好菜

题目描述

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

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

 

 

我的想法 

搞一个maxPoint记录下出现次数最多的数字,而当这个maxPoint大于数组的一半了,那么就可以break了,还别忘了记录下他的下标,且每次循环结束要让point清0。

一开始做的慢,经过调试以后发现打印出来的都是NaN,是因为我审错题,想搞一个空数组记录下他们每个数出现的次数,但是空数组没有赋值为0。

(真的不敲几行代码就凭上课听的理论真的没用)

我的代码

/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
    let point=0,maxPoint=0;
    let len=nums.length/2;
    let a=0,r=0;
    const copyArr=nums;
    
for(let i=0;i<nums.length;i++)
{
    a=nums[i];
    for(let k=1;k<nums.length;k++)
    {
        if(a==copyArr[k])
        {
            point++;
            {
                if(point>maxPoint)
                {
                    maxPoint=point;
                    if(maxPoint>len)
                    {
                    r=k;
                    break;
                    }
           }
            } 
        }
    }
    point=0;
}
return nums[r];
};

虽然很麻烦,但是好歹是写出来了((

去看看题解

题解 

题解是这么说的,不愧是题解

“想象一下,假如数组是一个投票箱,数组元素是一张写了选举人编号的一张选票。

题目要求我们找出哪个数字,超过了数组的一半!

是否就可以想象为,哪个人成为了最终选举的胜利者呢?

那么,接下来我们要做的事情,就是找到票数最多的那个人的编号即可。”

经过对题解的理解,我发现我的思路兜了圈,直接找那个数就好了,为啥还要多次一举找下标,(找数)应该会快一丢丢 。题解用了不同元素可以抵消的办法,那就要思考这个抵消的规则是什么样的了。

首先我们的角色是有攻擂者和守擂者,守擂者就是那个暂时胜利者(票最多/元素最多的)

当存在多个攻擂者时,他们的一次攻击可以打掉守擂者的一滴血,攻擂者每次也要掉一滴血才能发动攻击;

如果大家的血都没了,那就要选出新的守擂者。

(咱们就是说,没看答案之前完全想不到这样的办法解题啊

解释一下为啥这样能找到数组中出现次数超过一半的数字,但其实也不难想,因为这个数的出现的次数总是多于其他数字的,那么全部抵消了剩下的,肯定就是出现最多那个咯。

有了思路以后,力扣大神就把这个思路转化到数组里面,进而找到解题等式(?忘记叫啥了

佬的办法,4492/84约等于53.。。可恶,这个时间换空间到底还是换的不怎么划算

再敲一遍

var majorityElement = function(nums) {
   //首先有两个需要记录的变量
   let winner=0,winPoint=0;
//初始化
      winner=nums[0];
      winPoint=1;
   for(let i=1;i<nums.length;i++)
   {
       if(nums[i]==winner)
       {
           winPoint++;
       }
       else{
           if(winPoint>0)
           {
           winPoint--;
           }else{
               winner=nums[i];
               winPoint=1;
           }

       }
      
   }
   return winner;
};

嘿嘿 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值