跟我一起刷leetCode算法題4之Majority Element

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毫秒時間長,看來第二種算法的速度明顯比我快。

雖然我的算法速度慢,但是我從別人那里學到了新的方法,總體來講還是挺滿足的,因為有了新收獲。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容