169. 多数元素
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋
的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:[3,2,3]
输出:3
示例 2:
输入:[2,2,1,1,1,2,2]
输出:2
进阶:
- 尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。
二、方法一
哈希存储
class Solution {
public int majorityElement(int[] nums) {
if(nums.length==0){
return 0;
}
Map<Integer,Integer> map=new HashMap<>();
for(int i:nums){
map.put(i,map.getOrDefault(i,0)+1);
}
for(int key:map.keySet()){
int val=map.get(key);
if(val>nums.length/2){
return key;
}
}
return 0;
}
}
复杂度分析
-
时间复杂度:O(n),其中 n 是数组 nums 的长度。我们遍历数组 nums 一次,对于 nums 中的每一个元素,将其插入哈希表都只需要常数时间。如果在遍历时没有维护最大值,在遍历结束后还需要对哈希表进行遍历,因为哈希表中占用的空间为 O(n),那么遍历的时间不会超过O(n)。因此总时间复杂度为 O(n)。
-
空间复杂度:O(n)。
三、方法二
排序
class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length / 2];
}
}
复杂度分析
-
时间复杂度:O(nlogn)。将数组排序的时间复杂度为O(nlogn)。
-
空间复杂度:O(logn)。如果使用语言自带的排序算法,需要使用O(logn) 的栈空间。如果自己编写堆排序,则只需要使用 O(1) 的额外空间。
四、方法三
可以看我之前的博客
摩尔投票法
class Solution {
public int majorityElement(int[] nums) {
int count = 0;
Integer cur = null;
for (int num : nums) {
if (count == 0) {
cur = num;
}
count += (cur == num) ? 1 : -1;
}
return cur;
}
}
复杂度分析
-
时间复杂度:O(n)。Boyer-Moore 算法只对数组进行了一次遍历。
-
空间复杂度:O(1)。Boyer-Moore 算法只需要常数级别的额外空间。