LeetCode 169. Majority Element (Java)

题目:

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exist in the array.

Example 1:
Input: [3,2,3]
Output: 3

Example 2:
Input: [2,2,1,1,1,2,2]
Output: 2

解答:

自己采用了哈希表的解法

//使用hashmap
//遍历nums,判断nums[i]是否在hashmap中,存在则对应的value+1,不存在就重新put进去,并且设置value为1。最终遍历hashmap,找出value最大的对应的key即为所求众数
//这种算法的时间复杂度为O(n),哈希表的插入为常数时间
class Solution {
    public int majorityElement(int[] nums) {
        HashMap<Integer,Integer> hashmap=new HashMap<>();
        for(int i=0;i<nums.length;i++){
            if(hashmap.containsKey(nums[i])){
                hashmap.put(nums[i],hashmap.get(nums[i])+1);
            }else{
                hashmap.put(nums[i],1);
            }
        }
        for(Integer key:hashmap.keySet()){
            if(hashmap.get(key)>nums.length/2)
                return key;
        }
        return 0;
    }
}

官方给出了其他多种解法,如采用分而治之。

//分治算法递归求解,直到所有的子问题都是长度为1的数组
//由于传输子数组需要额外的时间和空间,所以我们实际上只传输子区间的左右指针lo和hi表示相应区间的左右下标
//长度为1的子数组中唯一的数显然是众数,直接返回即可。如果回溯后某区间的长度大于1,我们必须将左右子区间的值合并。如果它们的众数相同,那么显然这一段区间的众数是它们相同的值。否则,我们需要比较两个众数在整个区间内出现的次数来决定该区间的众数
//时间复杂度为O(nlgn)
class Solution {
    private int countInRange(int[] nums, int num, int lo, int hi) {
        int count = 0;
        for (int i = lo; i <= hi; i++) {
            if (nums[i] == num) {
                count++;
            }
        }
        return count;
    }
    private int majorityEleme(int[] nums, int lo, int hi) {
        //大小为1的数组中唯一的元素是多数元素
        if (lo == hi) {
            return nums[lo];
        }
        int mid = (hi-lo)/2 + lo;
        int left = majorityEleme(nums, lo, mid);
        int right = majorityEleme(nums, mid+1, hi);
        //若左右两边在多数元素上达成一致,则将其返回
        if (left == right) {
            return left;
        }
        //否则,计算每个元素出现的次数并返回较多者
        int leftCount = countInRange(nums, left, lo, hi);
        int rightCount = countInRange(nums, right, lo, hi);
        return leftCount > rightCount ? left : right;
    }
     public int majorityElement(int[] nums) {
        return majorityEleme(nums, 0, nums.length-1);
    }
}

另一种更巧妙的解法为Boyer-Moore投票算法,它的基本思想如下所示:
LeetCode 169. Majority Element (Java)_第1张图片

class Solution{
    public int majorityElement(int[] nums) {
    int result = nums[0];
    int count = 0;
    for (int num : nums) {
        if (count == 0) {
            result = num;
            count++;
        } else {
            if (result == num) {
                count++;
            } else {
                count--;
            }
        }
    }
    return result;
    }
}

你可能感兴趣的:(LeetCode)