一、题目
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [3,2,3]
输出: 3
示例 2:
输入: [2,2,1,1,1,2,2]
输出: 2
二、题目
1、暴力
思路: 针对数组的每一个元素进行枚举,然后再来一层循环对每个元素进行计数,最后返回最大值的那个。
代码: 略。
时间复杂度: O(
n
2
n^2
n2)
空间复杂度: O(1)
2、HashMap
思路: 这个看代码吧,比较容易理解。
代码:
class Solution {
public int majorityElement(int[] nums) {
int ans = 0;
Map<Integer, Integer> map = new HashMap<>();
for(int num:nums) {
int cnt = map.getOrDefault(num, 0) + 1;
map.put(num, cnt);
if(cnt>nums.length/2) { ans = num; break; }
}
return ans;
}
}
时间复杂度: O(n)
空间复杂度: O(n)
3、摩尔投票法
思路: 遇到相同的+1,不同的-1,因为众数大于n/2,所以到最后数量一定>=1,对应的数一定是众数。
代码:
class Solution {
public int majorityElement(int[] nums) {
int count = 0; int major = nums[0];
for(int i:nums) {
if(count==0){ major=i; count++; }
else if(i==major) count++;
else count--;
}
return major;
}
}
时间复杂度: O(nlogn)
空间复杂度: O(n)
4、Sort
思路: 排序,取中间。因为这里的众数数量大于 n / 2 n/2 n/2,所以排序后,在中间位置的一定是众数,否则众数数量< n / 2 n/2 n/2,与定义自相矛盾。
代码:
class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length/2];
}
}
时间复杂度: O(nlogn)
空间复杂度: O(n)
5、分治
思路: 略。
代码: 比较冗长,暂时略。
时间复杂度: O(nlogn)
空间复杂度: O(logn)
6、位运算
思路: 有点难以理解,且效率也没那么高,暂时略。
三、参考
1、Java-3种方法(计数法/排序法/摩尔投票法)̶
2、多数元素
3、Java solutions (sorting, hashmap, moore voting, bit manipulation).
4、O(n) time, O(1) space
5、java 位运算
6、面试题39. 数组中出现次数超过一半的数字(摩尔投票法,清晰图解)