Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.
You may assume that the array is non-empty and the majority element always exist in the array.
思路1:采用计数排序法:
时间复杂度为0(n),但是需要一个map存储不同数据,需要占用一定的空间复杂度小于0(n/2)
统计数组nums中不同的数值的个数,当统计的个数大于 ⌊ n/2 ⌋时,则return
JS代码如下:
var majorityElement = function(nums) {//此题采用计数排序法
var map = {},
majority = [],
temp,
n = nums.length,
maxLength = Math.floor(n/2);
if(n===0)
{
return null;
}else if(n === 1)
{
return nums[0];
}
for(var i = 0; i < n; i++)
{
temp = nums[i];
if(map[temp]) //若nums[i]存在于map对象中,则计数加1,并判断计数值是否大于maxLength = Math.ceil(n/2),大于则存储至majority数组中
{
map[temp]++;
if(map[temp] > maxLength)
{
// majority.push(nums[i]);
return temp;
}
}else{ //若nums[i]不在map对象中,则加入nums[i]对象值
map[temp] = 1;
}
}
};
思路2:消除法:
这个是参考网上的思路,个人觉得比较经典,自愧不如,https://leetcode.com/discuss/19151/solution-computation-space-problem-can-extended-situation
这个算法的时间复杂度为0(n),空间复杂度为0(1).
每找出两个不同的element,则成对删除。最终剩下的一定就是所求的。
可扩展到⌊ n/k ⌋的情况,每k个不同的element进行成对删除。
JS代码实现:
//每找出两个不同的element,则成对删除。最终剩下的一定就是所求的。
//可扩展到⌊ n/k ⌋的情况,每k个不同的element进行成对删除。
var majorityElement = function(nums) {
var count=0,
temp,
n = nums.length,
maxLength = Math.floor(n/2);
if(n===0)
{
return null;
}else if(n === 1)
{
return nums[0];
}
for(var i = 0; i < n; i++)
{
if(count === 0)
{
temp = nums[i];
count++;
}else
{
if(temp === nums[i]) //遇到相同的元素则,计数值继续增加
{
count++;
}else{ //遇到不同的元素则一对一配对删除
count--;
}
}
}
return temp;
}
总结:针对此题,分治法与计数法比较优势在于:
(1)计数法的空间复杂度为0(n/2),而消除法的空间复杂度为0(1);
(2)虽然两者的时间复杂度都为0(n),然而,计数法中还存在 if(map[temp] > maxLength)的比较以及map[temp]的取值;所以在leenCode上,验证消除法要稍快于计数法。