7.10每日一题

125 阅读1分钟

面试题 17.10. 主要元素

摩尔投票:依次将两个不同元素删除/抵消,这样剩下的元素数量就可能会是比数组中所有元素数量的一半都大。

这里的可能是有些情况比如:1212333,这个数列依次抵消剩下333,这个3的数量显然没有该数列长度的一般。而被抵消的数可以确保一定不会比数列长度的一半还大(我认为摩尔投票利用的数学原则就是这个)。

总结:摩尔投票可以保证被抵消的元素一定不会是主要元素,而剩下的元素的数量可能是会占据数组数量的一半以上的。

理清楚这个思想,那么对于这道题就轻松了,可以先设置一个变量n来存放可能会是数组中元素数量最多的元素。sum来存放当前该元素拥有的数量。

  • 首先是从头到尾遍历一次数组
  • 判断sum是否为0;如果是0,则将当前元素作为可能是数组中元素数量最多的那个,n=sum[i];若不是,则保留n。
  • 判断n与当前元素是否相等,不想等则sum-1表示抵消一次候选元素n的数量,相等就加一。

到这里得出来的n是经过摩尔投票后抵消剩余的元素,sum保存的也是抵消后的数量,所以要再次用一个循环统计所有n出现的次数。

最终用统计的数量sum与nums.length/2进行比较,判断是否是主要元素。

代码如下:

var majorityElement = function(nums) {
  let n=-1 ;
  let sum =0;
  for(let i=0;i<nums.length;i++){n = sum==0?nums[i]:n
​    sum = n==nums[i]?sum+1:sum-1
  }
  sum=0
  for(let i =0;i<nums.length;i++){sum= n==nums[i]?sum+1:sum
  }
  return sum>nums.length/2?n:-1
};