Leetcode:169. Majority Element

来源:互联网 发布:云端网络趋势 编辑:程序博客网 时间:2024/06/14 09:47

Description:

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.

1. 问题分析

本题的意思是在数组中找出一个数字出现的次数超过数组长度的一半,找出这个数。要注意到的是这道题只是要找出多数元素,已经默认存在多数元素了,而不需要去判断是否存在多数元素。

2. 算法描述

一开始最容易想到的就是哈希表,将数组中的数装进一个无序map即为哈希表中,查询平均时间是O(1),然后map的第一个key为数组的数,第二个value为出现的次数,最后把大于size/2的数返回即可。但是该算法的空间复杂度达到了O(n),可以将其改进分析:存在多数元素(个数大于size/2),则无论它的每个元素在数组中如何分布,它的个数经过抵消和增加后一定是大于或等于1的,改进算法如下:
(1)初始化majority数为max,并且使元素个数num为1
(2)遍历数组,若当前元素与max相同则num加一,否则减一;若num为0,则意味着多数元素要更改,重设num为1
(3)最后遍历结束后返回多数元素max

3. 解题代码

哈希表求解

class Solution {public:    int majorityElement(vector<int>& nums) {        unordered_map<int,int> temp;        int size = nums.size();        for (int i = 0; i < size; i++) {            if (temp.find(nums[i])==temp.end()) {                temp[nums[i]] = 0;            } else {                temp[nums[i]]++;            }            if (temp[nums[i]] >= size/2) return nums[i];        }    }}; 

改进解法

class Solution {public:    int majorityElement(vector<int>& nums) {        int max= nums[0], num = 1;        for (int i = 1; i < nums.size(); i++) {            if (num == 0) {                num++;                max = nums[i];            } else if (max == nums[i]) {                num++;            } else {                num--;            }        }        return max;    }};

4. 其他解法及其算法分析

本周老师讲到了分治算法,在解决完这道题时就想是否可以采用分治的方法解决呢?就是如何把一个问题转化为规模较小的若干个问题。分治、递推和贪心等都有这样的思想。在转化过程中,如果能保证小的问题跟原问题的解是一致的就成功了。这样,我们可以通过寻找这样的方式将小问题转化为更小的问题。如何将大问题拆成小问题,或者如何大规模的数据降成小规模,而不影响解呢?本题比较简单,解法很多,总结如下:

1、Runtime: O(n2) — Brute force solution: Check each element if it is the majority element.

2、Runtime: O(n), Space: O(n) — Hash table: Maintain a hash table of the counts of each element, then find the most common one.

3、Runtime: O(n log n) — Sorting: Find the longest contiguous identical element in the array after sorting.

4、Average runtime: O(n), Worst case runtime: Infinity — Randomization: Randomly pick an element and check if it is the majority element. If it is not, do the random pick again until you find the majority element. As the probability to pick the majority element is greater than 1/2, the expected number of attempts is < 2.

5、Runtime: O(n log n) — Divide and conquer: Divide the array into two halves, then find the majority element A in the first half and the majority element B in the second half. The global majority element must either be A or B. If A == B, then it automatically becomes the global majority element. If not, then both A and B are the candidates for the majority element, and it is suffice to check the count of occurrences for at most two candidates. The runtime complexity, T(n) = T(n/2) + 2n = O(n log n).

6、Runtime: O(n) — Moore voting algorithm: We maintain a current candidate and a counter initialized to 0. As we iterate the array, we look at the current element x:
(1)If the counter is 0, we set the current candidate to x and the counter to 1.
(2)If the counter is not 0, we increment or decrement the counter based on whether x is the current candidate.
After one pass, the current candidate is the majority element. Runtime complexity = O(n).

7、Runtime: O(n) — Bit manipulation: We would need 32 iterations, each calculating the number of 1’s for the ith bit of all n numbers. Since a majority must exist, therefore, either count of 1’s > count of 0’s or vice versa (but can never be equal). The majority number’s ith bit must be the one bit that has the greater count.

以上算法各有优劣,关键还是要看自己的需要。
请大家多多指正 。