Description
Given an array nums of size n, return the majority element.
The majority element is the element that appears more than ⌊n / 2⌋ times. You may assume that the majority element always exists in the array.
Examples
Example 1:
Input: nums = [3,2,3]
Output: 3
Example 2:
Input: nums = [2,2,1,1,1,2,2]
Output: 2
Constraints:
n == nums.length
1 <= n <= 5 * 10410^4104
−109-10^9−109 <= nums[i] <= 10910^9109
Follow-up: Could you solve the problem in linear time and in O(1) space?
思路
虽然这题只是easy,但还是有几种不同的方式来处理。以下所有处理方式都基于 “majority number的数量超过数组数量的一半”
排序
最开始也是最简单的方法,就是对数组进行排序,由于majority数量超过数组数量的一半,所以直接查找排序后的中点即可。
MAP
通过map存储每个数字的数量,一旦这个数量超过一半,就退出循环,认为这个数是majority number
二分查找
我们对一个序列,递归的搜索他左半边和右半边的majority number,对以下两重情况进行分别处理
- majority左 === majority右 → majority确定
- majority左 ≠\neq= majority右 → 分别计算majority左和majority右在序列中的数量,选择数量多的作为该序列的majority
Boyer-Moore Voting
这个solution里面看到的,他用了一个很tricky的方法,既然majority的数量一定是 > half 的,那我们假设[0]为majority,count的数量为1,然后依次对序列中的每个单词进行判断
- count == 0? 重置当前num为majority
- count != 0?
- 当前num == majority → count++
- 当前num != majority → count–
到最后剩下的majority就是majority,取一种最极端的情况
- 前 n/2+1 都是majority,那到最后 count=1,majority=[0]
其他情况下,由于count(majority) > half,都会导致最后剩下的是majortiy
代码
排序
class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length / 2];
}
}
MAP
class Solution {
public int majorityElement(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
for (int num: nums){
int n = map.getOrDefault(num, 0);
if (n >= nums.length / 2)
return num;
map.put(num, n + 1);
}
return -1;
}
}
二分查找
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 majorityElementRec(int[] nums, int lo, int hi) {
// base case; the only element in an array of size 1 is the majority
// element.
if (lo == hi) {
return nums[lo];
}
// recurse on left and right halves of this slice.
int mid = (hi-lo)/2 + lo;
int left = majorityElementRec(nums, lo, mid);
int right = majorityElementRec(nums, mid+1, hi);
// if the two halves agree on the majority element, return it.
if (left == right) {
return left;
}
// otherwise, count each element and return the "winner".
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 majorityElementRec(nums, 0, nums.length-1);
}
}
Boyer-Moore Voting
class Solution {
public int majorityElement(int[] nums) {
int count = 0;
Integer candidate = null;
for (int num : nums) {
if (count == 0) {
candidate = num;
}
count += (num == candidate) ? 1 : -1;
}
return candidate;
}
}
这篇博客探讨了如何在给定数组中找到多数元素,即出现次数超过数组长度一半的元素。文章介绍了四种不同的解决方法:排序、使用哈希映射、二分查找以及Boyer-Moore投票算法,并对每种方法进行了详细解释。通过实例展示了这些算法的工作原理和效率,帮助读者理解如何在不同场景下选择合适的解决方案。

868

被折叠的 条评论
为什么被折叠?



