1. 题目描述
2. 解题思路
再一次,哈希表仍然是解决这类问题刻在DNA里的记忆,只需要存储每个数的出现次数,发现大于n/2则返回即可。这道题难点在于进阶算法,时间复杂度O(n),可以,没问题,可空间复杂度O(1)就过分了吧?不都是空间换时间嘛!
吐槽归吐槽,官解这投票算法确实又给我大开眼界了,它的思想是这样的:
对于这个算法的正确性证明,我个人感觉官方的说法不是很好理解,但我在下面评论中发现了一个很通俗易懂的解释,这里贴上来给大家参考一下:
3. 代码实现
3.1 HashSet
public int majorityElement(int[] nums) {
if (nums.length == 1)
return nums[0];
HashMap<Integer, Integer> map = new HashMap<>();
int value;
for (int num : nums) {
if (map.containsKey(num)) {
value = map.get(num);
map.put(num, value + 1);
if (value + 1 > nums.length / 2) {
return num;
}
} else
map.put(num, 1);
}
return -1;
}
3.2 摩尔投票算法
public int majorityElement(int[] nums) {
int can = nums[0];
int ticket = 1;
for (int i = 1; i < nums.length; i++) {
if (ticket == 0) {
ticket++;
can = nums[i];
continue;
}
if (nums[i] == can)
ticket++;
else
ticket--;
}
return can;
}
3.3 对比
对于时间复杂度而言,两种算法都是O(n),但哈希表消耗时间明显更多,最近做的好几个题都是这种情况,看来哈希表的存储时间消耗比较严重。对于空间复杂度而言,摩尔投票算法完胜,只需要常数变量维持整个数组的遍历过程,达到了O(1)的时间复杂度,而哈希表的空间复杂度是O(n)。