leetcode-求衆數

題目:求衆數ios

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

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

示例 1:函數

輸入: [3,2,3] 輸出: 3

示例 2:spa

輸入: [2,2,1,1,1,2,2] 輸出: 2

首先了解一下什麼是分治設計

維基百科code

計算機科學中,分治法是建基於多項分支遞歸的一種很重要的算法範式。字面上的解釋是「分而治之」,就是把一個複雜的問題分紅兩個或更多的相同或類似的子問題,直到最後子問題能夠簡單的直接求解,原問題的解即子問題的解的合併。blog

 

這個技巧是不少高效算法的基礎,如排序算法快速排序歸併排序)、傅立葉變換快速傅立葉變換)。排序

 

另外一方面,理解及設計分治法算法的能力須要必定時間去掌握。正如以概括法去證實一個理論,爲了使遞歸可以推行,不少時候須要用一個較爲歸納或複雜的問題去取代原有問題。並且並無一個系統性的方法去適當地歸納問題。遞歸

 

分治法這個名稱有時亦會用於將問題簡化爲只有一個細問題的算法,例如用於在已排序的列中查找其中一項的折半搜索算法(或是在數值分析中相似的勘根算法)。這些算法比通常的分治算法更能有效地運行。其中,假如算法使用尾部遞歸的話,便能轉換成簡單的循環。但在這廣義之下,全部使用遞歸或循環的算法均被視做「分治算法」。所以,有些做者考慮「分治法」這個名稱應只用於每一個有最少兩個子問題的算法。而只有一個子問題的曾被建議使用減治法這個名稱。

 

分治算法一般以數學概括法來驗證。而它的計算成本則多數以解遞歸關係式來斷定。

 

  • 第一種

集合(Map),實現。執行用時:46 ms

public int majorityElement(int[] nums) { // [n/2] 元素
        int majorityElement = nums.length / 2; // 建立一個集合
        Map<Integer, Integer> map = new HashMap(); for (int num : nums) { // 思路:數組元素爲key,出現次數爲value。若是存在key,value+1,若是不存在key,第一次設置value 爲1
            map.put(num, map.get(num) != null ? map.get(num).intValue() + 1 : 1); } for (Map.Entry<Integer, Integer> entry : map.entrySet()) { // 出現次數和[n/2] 進行比較,大於,則返回(其實應該用一個集合來保存全部知足條件的衆數,而後再返回)
            if (entry.getValue() > majorityElement) { return entry.getKey(); } } return 0; }
  • 第二種

分治法 實現

// 用分治法求衆數 #include <iostream> #include <cstdio>
 using namespace std; // 本程序的關鍵。 以中間的數字爲界限。 肯定左右起始和終止界限 void split(int s[], int n, int &l, int &r) { int mid = n/2; for(l=0; l<n; ++l) { if (s[l] == s[mid]) break; } for(r=l+1; r<n; ++r) { if (s[r] != s[mid]) break; } } // num 衆數。 maxCnt 重數 void getMaxCnt(int &mid, int &maxCnt, int s[], int n) { int l, r; split(s, n, l, r); // 進行分割。這個函數是本程序的關鍵 int num = n/2; int cnt = r-l; // update if (cnt > maxCnt) { maxCnt = cnt; mid = s[num]; } // l 表示左邊的個數。左邊的個數必須大於 maxCnt 纔有必要搜尋 if (l+1 > maxCnt) { getMaxCnt(mid, maxCnt, s, l+1); } // 右邊搜尋, 右邊數組的起始地址要變動 if (n-r > maxCnt) { getMaxCnt(mid, maxCnt, s+r, n-r); } } int main(void) { int s[] = {1, 2, 2, 2, 3, 3, 5, 6, 6, 6, 6}; int n = sizeof(s)/sizeof(s[0]); int maxCnt = 0; int num = 0; getMaxCnt(num, maxCnt, s, n); printf("%d %d\n", num, maxCnt); return 0; }

 

  • 第三種

時間最快的  執行用時:7 ms

public int majorityElement2(int[] nums) { int result = nums[0], count = 0; for (int i = 0; i < nums.length; i++) { if (count == 0) { result = nums[i]; count++; } else if (result == nums[i]) { count++; } else { count--; } } return result; }
相關文章
相關標籤/搜索