[LeetCode] Majority Element

简介: Well, if you have got this problem accepted, you may have noticed that there are 7 suggested solutions for this problem.

Well, if you have got this problem accepted, you may have noticed that there are 7 suggested solutions for this problem. The following passage will implement 6 of them except the O(n^2)brute force algorithm.

Hash Table

The hash-table solution is very straightforward. We maintain a mapping from each element to its number of appearances. While constructing the mapping, we update the majority element based on the max number of appearances we have seen. Notice that we do not need to construct the full mapping when we see that an element has appeared more than n / 2 times.

The code is as follows, which should be self-explanatory.

 1 class Solution {
 2 public:
 3     int majorityElement(vector<int>& nums) {
 4         unordered_map<int, int> counts;
 5         int n = nums.size();
 6         for (int i = 0; i < n; i++)
 7             if (++counts[nums[i]] > n / 2)
 8                 return nums[i];
 9     }
10 };

Sorting

Since the majority element appears more than n / 2 times, the n / 2-th element in the sortednums must be the majority element. This can be proved intuitively. Note that the majority element will take more than n / 2 positions in the sorted nums (cover more than half of nums). If the first of it appears in the 0-th position, it will also appear in the n / 2-th position to cover more than half of nums. It is similar if the last of it appears in the n - 1-th position. These two cases are that the contiguous chunk of the majority element is to the leftmost and the rightmost in nums. For other cases (imagine the chunk moves between the left and the right end), it must also appear in the n / 2-th position.

The code is as follows, being very short if we use the system sort.

1 class Solution {
2 public:
3     int majorityElement(vector<int>& nums) {
4         sort(nums.begin(), nums.end());
5         return nums[nums.size() / 2];
6     }
7 };

Randomization

This is a really nice idea and works pretty well (16ms running time on the OJ, almost fastest among the C++ solutions). The proof is already given in the suggested solutions.

The code is as follows, randomly pick an element and see if it is the majority one.

 1 class Solution {
 2 public:
 3     int majorityElement(vector<int>& nums) {
 4         int n = nums.size();
 5         srand(unsigned(time(NULL)));
 6         while (true) {
 7             int idx = rand() % n;
 8             int candidate = nums[idx];
 9             int counts = 0; 
10             for (int i = 0; i < n; i++)
11                 if (nums[i] == candidate)
12                     counts++;
13             if (counts > n / 2) return candidate;
14         }
15     }
16 };

Divide and Conquer

This idea is very algorithmic. However, the implementation of it requires some careful thought about the base cases of the recursion. The base case is that when the array has only one element, then it is the majority one. Moreover, this solution is relatively slow in practice.

 1 class Solution {
 2 public:
 3     int majorityElement(vector<int>& nums) {
 4         return majority(nums, 0, nums.size() - 1);
 5     }
 6 private:
 7     int majority(vector<int>& nums, int left, int right) {
 8         if (left == right) return nums[left];
 9         int mid = left + ((right - left) >> 1);
10         int lm = majority(nums, left, mid);
11         int rm = majority(nums, mid + 1, right);
12         if (lm == rm) return lm;
13         return counts(nums, lm) > counts(nums, rm) ? lm : rm;
14     }
15     int counts(vector<int>& nums, int elem) {
16         int cnt = 0;
17         for (int i = 0; i < int(nums.size()); i++)
18             if (nums[i] == elem) cnt++;
19         return cnt;
20     }
21 };

Moore Voting Algorithm

A brilliant and easy-to-implement algorithm! It also runs very fast, about 20ms.

 1 class Solution {
 2 public:
 3     int majorityElement(vector<int>& nums) {
 4         int major, counts = 0, n = nums.size();
 5         for (int i = 0; i < n; i++) {
 6             if (!counts) {
 7                 major = nums[i];
 8                 counts = 1;
 9             }
10             else counts += (nums[i] == major) ? 1 : -1;
11         }
12         return major;
13     }
14 };

Bit Manipulation

Another nice idea! The key lies in how to count the number of 1's on a specific bit. Specifically, you need a mask with a 1 on the i-the bit and 0 otherwise to get the i-th bit of each element in nums. The code is as follows.

 1 class Solution {
 2 public:
 3     int majorityElement(vector<int>& nums) {
 4         int major = 0, n = nums.size();
 5         for (int i = 0, mask = 1; i < 32; i++, mask <<= 1) {
 6             int bitCounts = 0;
 7             for (int j = 0; j < n; j++) {
 8                 if (nums[j] & mask) bitCounts++;
 9                 if (bitCounts > n / 2) {
10                     major |= mask;
11                     break;
12                 }
13             }
14         } 
15         return major;
16     } 
17 };

 

目录
相关文章
Leetcode 230. Kth Smallest Element in a BST
先来看下二叉搜索树的性质,对于任意一个非叶子节点,它的左子树中所有的值必定小于这个节点的val,右子树中所有的值必定大于或等于当前节点的val。 这条性质就保证了如果我们对二叉搜索树做中序遍历,中序遍历的结果肯定是有序的。对于此题而言,我们只需要拿到中序遍历结果,然后返回第k个即可,时间复杂度是O(n)。
68 1
|
Python
LeetCode 378. Kth S Element in a Sorted Matrix
给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素。 请注意,它是排序后的第k小元素,而不是第k个元素。
118 0
LeetCode 378. Kth S Element in a Sorted Matrix
|
算法
LeetCode 229. Majority Element II
给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。 说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1)。
94 0
LeetCode 229. Majority Element II
|
索引
LeetCode 162. Find Peak Element
给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。 数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。
109 0
LeetCode 162. Find Peak Element
|
算法 Python
LeetCode 169. 多数元素 Majority Element
LeetCode 169. 多数元素 Majority Element
LeetCode 215. Kth Largest Element in an Array
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
93 0
|
Java C++
LeetCode之Remove Element
LeetCode之Remove Element
120 0
LeetCode之Next Greater Element I
LeetCode之Next Greater Element I
91 0
|
容器
LeetCode 169 Majority Element(主要元素)(vector、map)
版权声明:转载请联系本人,感谢配合!本站地址:http://blog.csdn.net/nomasp https://blog.csdn.net/NoMasp/article/details/50504698 翻译 给定一个长度为n的数组,找出主要的元素。
812 0
|
4月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行