1. 程式人生 > >229. Majority Element II

229. Majority Element II

排除 int 得到 [] ret space 方法 nbsp 題目

Given an integer array of size n, find all elements that appear more than ? n/3 ? times. The algorithm should run in linear time and in O(1) space.

用的是摩爾投票法,原版的算法是找一個數組出現次數大於數組長度半數的數(只有當數組中存在這樣的數時,這個算法才會生效,而且不難理解,如果有也只可能有一個),方法就是定義一個變量m,記錄當前的候選數字,再定義一個變量c,記錄票數。然後遍歷數組

1.當前數字如果和候選數字相等,c++;

2.當前數字和候選數字不相等

  1)若c == 0;那麽令m = 當前數字;

  2)若從!= 0;那麽c--;

如果這種數真的存在,那麽這樣遍歷一遍,c絕對不為0。如果不能保證有這個數存在,那麽這個算法不能用,得到的結果不能說明任何情況。

這道題是找出現次數大於長度的1/3的數,這樣的數要是有的話最多兩個,但是題目中沒有說一定會有,所以最後要加上驗證。設置兩個變量m1,m2記錄候選數,兩個變量c1,c2記錄出現的次數。

按照摩爾投票的方法,進行統計。然後再遍歷一次數組,用來驗證這兩個數出現的次數是否大於n/3;情況有以下幾種:

1.如果數組中存在這樣的數,m1,m2中保存的一定是它(或者它們),且一定會通過驗證。如果只存在一個,那麽另外一個會在驗證中被排除

2.如果數組中不存在這樣的數,那麽m1,m2 中的數不代表任何意義,也會在驗證中排除。

這樣就保證了不會錯過一個好人,也不會放走一個壞人。

public class Solution {
    public List<Integer> majorityElement(int[] nums) {
        List<Integer> res = new ArrayList<Integer>();
        if(nums.length == 0)
        return res;
        int m1 = 0;
        int
m2 = 0; int c1=0,c2 = 0; for(int i =0;i<nums.length;i++) { int x = nums[i]; if(m1 == x) c1++; else if(m2 == x) c2++; else if(c1 == 0) { m1 = x; c1++; } else if(c2 == 0) { m2 = x; c2++; } else { c1--; c2--; } } c1 = 0; c2 = 0; for(int i = 0;i<nums.length;i++) { if(nums[i] == m1) c1++; else if(nums[i] == m2) c2++; } if(c1 > nums.length/3) res.add(m1); if(c2 > nums.length/3) res.add(m2); return res; } }

229. Majority Element II