169.Majority Element
這是leetCode第169題
題目
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.
意思是說:給你一個大小為n的數組,找到majorityElement,該元素在數組中的出現次數超過n/2次(因此n為奇數)。
你可以假設數組不是空數組,和majorityElement元素總是存在。
也就是說,測試用例的數組中總是存在我們要找到的元素。
我的思路
既然數組中一定存在majorityElement元素,那么如果我們給數組進行排序,那么數組的中間的一個元素就是majorityElement;
因為我的代碼如下:
//題目中提示,數組不為空,目標一定存在,所以代碼可以這么寫。
var majorityElement = function(nums) {
var n = Math.floor(nums.length/2);
nums.sort(function(a,b){
return a-b;
});
return nums[n];
};
雖然方法寫出來了,但是我用了數組的sort方法,因此我的算法的時間復雜度為O( nlog2(n) )*。
還有一種更快的算法,時間復雜度為O(n);
下面這種算法,是我從別人那學來的:
var majorityElement = function(nums) {
var major = '';
var count = 0;
var length = nums.length;
for(var i=0; i<length; i++) {
if (count === 0) {
major = nums[i];
count =1;
} else if(nums[i] === major) {
count++;
} else {
count--;
}
}
return major;
} ;
該算法假設每個元素都有可能是majorityElement。當count===0時,就更新majorityElement。如果第i 個元素==major,count就加1,否則就減1。
因為majorityElement元素的次數大于n/2,所以當某個元素被假設為majorityElement時,真正的majorityElement都總能把count減為0,最后真正的majorityElement就一定會上位。
舉個例子:
[2,3,2,3,2]
//count變化=> 1,0,1,0,1
// major變化=> 2,2,2,2,2
[2,2,2,2,3,3,4]
//count變化=>1,2,3,4,3,2,1
//major變化=>2,2,2,2,2,2,2
對比兩個算法的速度
執行下面的代碼,來生成一個模塊Array.js,該模塊導出一個長度為200001的數組,數組中一定存在majorityElement。
node product.js
product.js的代碼如下:
var fs = require("fs");
var nums =[];
var boundary = 100000;
for(var i=0;i<boundary;i++){
nums.push(i);
}
//確認一個隨機的majorityElement
var random = Math.floor(Math.random()*boundary);
//然后把majorityElement,隨機插入數組中,boundary+1次
//這樣majorityElement出現次數肯定超過n/2
for(var i=0;i<=boundary;i++){
nums.splice(Math.floor(Math.random()*boundary),0,random);
}
//轉成字符串,注意字符串“module.exports=array"
//這樣就會生成一個模塊,供其他文件加載。
var str = "var array=["+nums+"];module.exports=array;";
//寫入Array.js文件,生成了js代碼
fs.writeFile('Array.js', str, function(err) {
if (err) {
return console.error(err);
}
console.log("數據寫入成功!");
});
數組有了,我們開始測試算法的速度。
首先測試我寫的算法:
//導入數組
var nums = require('./Array.js');
var start = new Date().getTime();
console.log("majorityElement : "+majorityElement(nums));
var end = new Date().getTime();
console.log("time: "+(end-start));
測試結果:
majorityElement : 13424
time: 57
測試別人的算法:
//導入數組
var nums = require('./Array.js');
var start = new Date().getTime();
console.log("majorityElement : "+majorityElement(nums));
var end = new Date().getTime();
console.log("time: "+(end-start));
測試結果:
majorityElement : 13424
time: 18
對比一下,57毫秒明顯比18毫秒時間長,看來第二種算法的速度明顯比我快。
雖然我的算法速度慢,但是我從別人那里學到了新的方法,總體來講還是挺滿足的,因為有了新收獲。