獨樂樂不如衆樂樂,如何裝逼的求衆數

今天分享的題目來源於 LeetCode 上第 169 號問題:求衆數(求數組中超過一半的數字)。題目難度爲 Easy,目前經過率爲 45.8% 。數組

最後一種解法 Cool !!!優化

題目描述

給定一個大小爲 n 的數組,找到其中的衆數。衆數是指在數組中出現次數大於 ⌊ n/2 ⌋ 的元素。動畫

你能夠假設數組是非空的,而且給定的數組老是存在衆數。spa

示例 1:code

輸入: [3,2,3]
輸出: 3複製代碼

示例 2:blog

輸入: [2,2,1,1,1,2,2]
輸出: 2複製代碼

題目解析

題目意思很好理解:給你一個數組,裏面有一個數字出現的次數超過了一半,你要找到這個數字並返回。ip

解法一:暴力解法

遍歷整個數組,同時統計每一個數字出現的次數。get

最後將出現次數大於一半的元素返回便可。it

動畫描述

暴力解法.gif

代碼實現

class Solution {
    public int majorityElement(int[] nums) {
        int majorityCount = nums.length/2;

        for (int num : nums) {
            int count = 0;
            for (int elem : nums) {
                if (elem == num) {
                    count += 1;
                }
            }
            if (count > majorityCount) {
                return num;
            }

        }  
    }
}複製代碼

複雜度分析

時間複雜度:O(n2)io

暴力解法包含兩重嵌套的 for 循環,每一層 n 次迭代,所以時間複雜度爲 O(n2) 。

空間複雜度:O(1)

暴力解法沒有分配任何與輸入規模成比例的額外的空間,所以空間複雜度爲 O(1)。

解法二:哈希表法

這個問題能夠視爲查找問題,對於查找問題每每可使用時間複雜度爲 O(1) 的 哈希表,經過以空間換時間的方式進行優化。

直接遍歷整個 數組 ,將每個數字(num)與它出現的次數(count)存放在 哈希表 中,同時判斷該數字出現次數是不是最大的,動態更新 maxCount,最後輸出 maxNum。

動畫描述

哈希表法.gif

代碼實現

class Solution {
    public int majorityElement(int[] nums) {
    Map<Integer, Integer> map = new HashMap<>();
    // maxNum 表示元素,maxCount 表示元素出現的次數
    int maxNum = 0, maxCount = 0;
    for (int num: nums) {
      int count = map.getOrDefault(num, 0) + 1;
      map.put(num, count);
      if (count > maxCount) {
        maxCount = count;
        maxNum = num;
      }
    }
    return maxNum;
  }
}複製代碼

複雜度分析

時間複雜度:O(n)

總共有一個循環,裏面哈希表的插入是常數時間的,所以時間複雜度爲 O(n)。

空間複雜度:O(n)

哈希表佔用了額外的空間 O(n),所以空間複雜度爲 O(n)。

解法三:摩爾投票法

再來回顧一下題目:尋找數組中超過一半的數字,這意味着數組中其餘數字出現次數的總和都是比不上這個數字出現的次數

即若是把 該衆數記爲 +1 ,把其餘數記爲 −1 ,將它們所有加起來,和是大於 0 的。

因此能夠這樣操做:

  • 設置兩個變量 candidate 和 count,candidate 用來保存數組中遍歷到的某個數字,count 表示當前數字的出現次數,一開始 candidate 保存爲數組中的第一個數字,count 爲 1
  • 遍歷整個數組
  • 若是數字與以前 candidate 保存的數字相同,則 count 加 1
  • 若是數字與以前 candidate 保存的數字不一樣,則 count 減 1
  • 若是出現次數 count 變爲 0 ,candidate 進行變化,保存爲當前遍歷的那個數字,而且同時把 count 重置爲 1
  • 遍歷完數組中的全部數字便可獲得結果

動畫描述

摩爾投票法.gif

代碼實現

class Solution {
    public int majorityElement(int[] nums) {
    int candidate = nums[0], count = 1;
    for (int i = 1; i < nums.length; ++i) {
      if (count == 0) {
        candidate = nums[i];
        count = 1;
      } else if (nums[i] == candidate) {
        count++;
      } else{
        count--;
      }
    }
    return candidate;
  }
}複製代碼

複雜度分析

時間複雜度:O(n)

總共只有一個循環,所以時間複雜度爲 O(n)。

空間複雜度:O(1)

只須要常數級別的額外空間,所以空間複雜度爲 O(1)。

相關文章
相關標籤/搜索