我好菜
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
我的想法
搞一个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;
};
嘿嘿