刷题笔记:力扣第169题-多数元素

1.本题最不动脑子的做法便是设置一个哈希表,遍历数组的同时给元素对应位置的哈希表值+1,同时判断该值是否大于numsSize / 2,可写出完整代码如下:

cpp 复制代码
 1. int majorityElement(int* nums, int numsSize) {
 2.     int hash[2000000001] = {0};
 3.     for (int i = 0; i < numsSize; i++){
 4.         hash[nums[i] + 1000000000]++;
 5.         if (hash[nums[i] + 1000000000] > numsSize / 2){
 6.             return nums[i];
 7.         }
 8.     }
 9.  
10.     return nums[0];
11. }

该算法在逻辑上完全没有问题,但因为要考虑题目给出的元素数据范围为"-10^9 ~ 10^9",设置的哈希表范围也非常大,在该函数的栈上存不下这么多数据,会导致栈溢出,无法通过力扣的本地测试。该算法时间复杂度为O(n),空间复杂度为O(m),m为数据范围。

2.当题目保证一定存在出现次数大于n/2的元素时,就可以使用摩尔投票法。记录当前元素的值num_cur,这个值可以理解为擂主,出现一次相同的值就将计数值+1,反之则-1。当计数值减为负数,擂主就换成当前元素,因为最终出现次数大于n/2的元素一定会站在擂台最后,其他所有元素的出现次数和都小于它的次数。

3.基于以上思想,可写出完整代码如下:

cpp 复制代码
 1. int majorityElement(int* nums, int numsSize) {
 2.     // cur_num:摩尔投票的候选数;cnt:候选的计票
 3.     int cur_num = nums[0];
 4.     int cnt = 1;
 5.     // 从第2个元素开始遍历数组
 6.     for (int i = 1; i < numsSize; i++){
 7.         if (nums[i] == cur_num){
 8.             // 当前元素等于候选,票数+1
 9.             cnt++;
10.         } else {
11.             // 当前元素不等于候选,票数抵消-1
12.             cnt--;
13.             // 票数小于0,说明候选被抵消完,更换新候选,新候选票数初始化为1
14.             if (cnt < 0){
15.                 cnt = 1;
16.                 cur_num = nums[i];
17.             }
18.         }
19.     }
20.     return cur_num;
21. }

该算法时间复杂度为O(n),空间复杂度为O(1)。

4.非常神奇的一点是,如果将票数判断条件从cnt < 0改为cnt == 0,本题依然是正确的。按照正常的理解来说,这会导致新的元素被多算了一次,但实际上的逻辑为:

(1)如果是虚假的多数元素被推翻,那么真正的多数元素即使多加了1次仍然是多数,不影响。

(2)如果是真正的多数元素被暂时推翻,少数元素多加了1次,但因为多数元素一定严格大于其他所有元素的次数和,也就是至少大于1,所以它一定能卷土重来,推翻现在的少数元素擂主,之后它也多加了1次,将这个差距补回来了。

本质上只是凑巧对了,实际解题过程中还是应该使用cnt < 0这种正常逻辑。

5.本题题解给了非常多的解法,包括但不限于:

(1)哈希表

(2)摩尔投票法

(3)排序法,下标为n/2的元素一定是答案

(4)随机化法,随机挑选一个元素来验证它是不是答案

(5)分治法

从复杂度角度来说,还是摩尔投票法是本题最优解。

相关推荐
非优秀程序员8 小时前
第05章 播放器大战,暴风、快播与那一夜|《互联网产品恩仇录》
算法
文丑颜不良啊10 小时前
LeetCode2481~2500题目解析
java·leetcode
武子康14 小时前
驾驶轨迹换个坐标,就能给移动机器人用吗?
人工智能·算法·机器学习
David猪大卫14 小时前
【C++修炼】map 和 set 的使用
c语言·开发语言·数据结构·c++·经验分享·笔记·学习
星恒随风15 小时前
MySQL 从零入门(三):表的约束详解
linux·服务器·数据库·笔记·mysql
文丑颜不良啊17 小时前
LeetCode2461~2480题目解析
java·leetcode
文丑颜不良啊18 小时前
LeetCode2441~2460题目解析
java·leetcode
蒸蒸yyyyzwd19 小时前
从后端面经学到的 3 个知识
笔记·学习
17岁的勇气19 小时前
Unity Shader unity文档学习笔记(二十二):shader变体
笔记·学习·unity