给定一个大小为
n
的数组nums
,返回其中的多数元素。多数元素是指在数组中出现次数 大于⌊ n/2 ⌋
的元素。你可以假设数组是非空的,并且给定的数组总是存在多数元素。
提示:
n == nums.length
1 <= n <= 5 * 104
-109 <= nums[i] <= 109
进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法
解决此问题。
法一:用哈希表,键:数组值,值:出现的次数。遍历判断一下值是否满足条件然后返回。
import java.util.HashMap;
import java.util.Map;
class Solution {
public int majorityElement(int[] nums) {
Map<Integer, Integer> mp = new HashMap<>();
for (int num : nums) {
mp.put(num, mp.getOrDefault(num, 0) + 1);
}
for (Map.Entry<Integer, Integer> entry : mp.entrySet()) {
if (entry.getValue() > nums.length / 2) {
return entry.getKey();
}
}
return -1;
}
}
getOrDefault(Object key, V defaultValue):如果mp中不存在该键key,则键对应的值为defaultValue;如果存在key,则返回键对应的值。
复杂度分析
-
时间复杂度:O(n)
-
空间复杂度:O(n)
法二:排序
如果将数组 nums 中的所有元素按照单调递增或单调递减的顺序排序,那么下标为 ⌊⌋ 的元素(下标从 0 开始)一定是众数。
对于这种算法,我们先将 nums 数组排序,然后返回上文所说的下标对应的元素。下面的图中解释了为什么这种策略是有效的。在下图中,第一个例子是 n 为奇数的情况,第二个例子是 n 为偶数的情况。
对于每种情况,数组上面的线表示如果众数是数组中的最小值时覆盖的下标,数组下面的线表示如果众数是数组中的最大值时覆盖的下标。对于其他的情况,这条线会在这两种极端情况的中间。对于这两种极端情况,它们会在下标为 ⌊⌋ 的地方有重叠。因此,无论众数是多少,返回⌊
⌋ 下标对应的值都是正确的。
class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length / 2];
}
}
复杂度分析
-
时间复杂度:O(nlogn)。将数组排序的时间复杂度为 O(nlogn)。
-
空间复杂度:O(logn)。