【LeetCode】169. 多數元素


169. 多數元素

知識點:數組;排序;消消樂;分治

題目描述

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

你可以假設數組是非空的,並且給定的數組總是存在多數元素。

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

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

解法一:排序

因為這道題中說了一定有一個數字是大於一半的,所以可以直接將數組進行排序,然后中間那個數一定是出現超過一半的。

class Solution {
    public int majorityElement(int[] nums) {
        if(nums.length == 1) return nums[0];
        Arrays.sort(nums);
        return nums[nums.length/2];
    }
}

解法二:消消樂(投票法)

一定有一個數字超過一半,所以如果兩個不同的數字兩兩抵消的話最后留下來的那個一定就是出現次數超過一半的。先選最開始的作為候選人,然后count=1, 如果后面遇到一樣的,count++,遇到不一樣的,count--,count一旦到0以后,那就需要換新的候選人了。

class Solution {
    public int majorityElement(int[] nums) {
        int res = 0, count = 0;
        for(int i = 0; i < nums.length; i++){
            if(count == 0){
                res = nums[i];
                count++;
            }else if(res == nums[i]){
                count++;
            }else if(res != nums[i]){
                count--;
            }
        }
        return res;
    }
}

解法三:分治

如果有一個數字出現次數超過了一半,那將這個數組分成兩半后,那這個數必定至少在其中一部分超過一半。
反證:如果這個數字在兩半里都沒超過一半,那在整個數組里必定也沒超過一半。所以可以分別求兩個子數組里超過一半的數字,然后選出兩個里真正的出現最多的。

  • 如果這兩個數字相同,那必定就是它了;
  • 如果這兩個數字不同,統計兩個數字分別在數組里出現的次數,大的就是了;
class Solution {
    public int majorityElement(int[] nums) {
        return majorityElement(nums, 0, nums.length-1); //區間是左閉右閉;
    }
    private int majorityElement(int[] nums, int left, int right){
        if(left == right){
            return nums[left];  //結束條件;
        }
        int mid = left+((right-left) >> 1);
        int leftnum = majorityElement(nums, left, mid);  //左右兩側的超過一半的數字;
        int rightnum = majorityElement(nums, mid+1, right);

        if(leftnum == rightnum) return leftnum;
        int leftcount = countNum(nums, leftnum, left, right);  //比較兩個數字誰次數多;
        int rightcount = countNum(nums, rightnum, left, right);
        return leftcount > rightcount ? leftnum : rightnum;
    }
    private int countNum(int[] nums, int num, int left, int right){
        int count = 0;
        for(int i = left; i <= right; i++){
            if(nums[i] == num){
                count++;
            }
        }
        return count;
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM