刷题笔记:力扣第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)分治法

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

相关推荐
bug嘛我经常写1 小时前
MIKE21结合ArcGIS制作随时间变化的降水文件(.dfs2)-笔记
经验分享·笔记·arcgis
hfywmsj1 小时前
广州餐饮铺位招租数据建模:基于多维评估体系的选址算法设计与实现
人工智能·算法·广州餐饮铺位招租
wabs6661 小时前
关于二叉树【力扣116.填充每个节点的下一个右侧节点指针的思考】
数据结构·c++·算法·leetcode·二叉树·层序遍历
kaixin_啊啊1 小时前
中国研究生数学建模竞赛(华为杯)学习笔记——数据预处理全流程
人工智能·笔记·学习·数学建模·ai·大模型·数据预处理
Nil2081 小时前
leetcode 74搜索二维矩阵
算法·leetcode·矩阵
新知图书2 小时前
第 14 章 后训练算法GRPO详解与实战
人工智能·算法
shirsl4 小时前
算法 Day1-数组 / 哈希 + 双指针
python·算法·哈希算法
星云API|微信接口开发4 小时前
企业微信二次开发实战笔记:如何用在线调试快速验证接口功能
数据库·笔记·企业微信
David猪大卫10 小时前
【C++修炼】智能指针使用及原理
开发语言·c++·经验分享·笔记·学习·考研·面试