1. 程式人生 > >LeetCode---229.求眾數II

LeetCode---229.求眾數II

題目來源:https://leetcode-cn.com/problems/majority-element-ii/description/

題目描述:

本題是在上篇部落格題目的難度上做了略微提升,上題詳見:https://blog.csdn.net/qq_39241239/article/details/82871294 

演算法描述:相信你已經閱讀了上一篇部落格,那麼就好辦了。本題有兩種效率較高的做法。

第一種:摩爾投票法:

題目給了我們一個 nums array, 讓我們找出所有 數量超過 n/3 的眾數。這一題與 眾數之一 的區別在於,眾數之一 只要找到一個 眾數大於 n/2 的就可以。這一題要找到所有的數量 大於n/3的眾數,其實,最多也就會有兩個 大於n/3 的眾數。因為可能會出現兩個眾數,而且是要數量 大於n/3 的,所以我們需要遍歷兩次nums array。

  第一次遍歷 需要找出數量出現最多的 兩個數字;

  第二次遍歷 需要找出準確的出現次數,因為第一次遍歷可能會漏掉一些次數;

  最後,要檢查次數大於 n/3 的 才算眾數。

程式碼如下:

class Solution {
    public List<Integer> majorityElement(int[] nums) {
      		List<Integer> list = new ArrayList<Integer>();
		int result1 = 0, result2 = 0, count1 = 0, count2 = 0;
		for (int x : nums) {
			if (x == result1)
				count1++;
			else if (x == result2)
				count2++;
			else if (count1 == 0) {
				result1 = x;
				count1 = 1;
			} else if (count2 == 0) {
				result2 = x;
				count2 = 1;
			} else {
				count1--;
				count2--;
			}
		}
		count1 = count2 = 0;
		for(int x : nums) {
			if(x == result1)
				count1++;
			if(x == result2)
				count2++;
		}
		if(count1 > (nums.length/3))
			list.add(result1);
		if((count2 > (nums.length/3)) && (result2!=result1))
            list.add(result2);
		return list;  
    }
}

第二種:先排序,然後再遍歷

class Solution {
    public List<Integer> majorityElement(int[] nums) {
        int n=nums.length/3,count=1;
        List<Integer> result=new ArrayList<>();
        Arrays.sort(nums);
        for(int i=0;i<nums.length-1;i++){
            if(nums[i]==nums[i+1])
                count++;
            else{
                if(count>n)
                    result.add(nums[i]);
                count=1;
            }
        }
        if(count>n && nums.length>0)
            result.add(nums[nums.length-1]);
        return result;
    }
}