• leetCode 229. 多数元素 II + 摩尔投票法 + 进阶 + 优化空间


    229. 多数元素 II - 力扣(LeetCode)


    给定一个大小为 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。

    进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1)的算法解决此问题。 


    (1)哈希表

    1. class Solution {
    2. public:
    3. // 哈希
    4. vector<int> majorityElement(vector<int>& nums) {
    5. unordered_map<int,int> mp;
    6. for(const int& a:nums) mp[a]++;
    7. int n = nums.size() / 3;
    8. int i=0;
    9. vector<int> ans;
    10. for(auto &it:mp) {
    11. if(it.second > n) ans.push_back(it.first);
    12. }
    13. return ans;
    14. }
    15. };

    (2) 摩尔投票法

    推荐看这篇文章,有关摩尔投票法的介绍:229. 多数元素 II - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/majority-element-ii/solutions/123170/liang-fu-dong-hua-yan-shi-mo-er-tou-piao-fa-zui-zh/① k=1时,举个栗子

    • 初始化

    • 执行流程 

    ② k=2时,举个栗子 

    • 初始化

    1. class Solution {
    2. public:
    3. // 摩尔投票法
    4. vector<int> majorityElement(vector<int>& nums) {
    5. // 创建返回值
    6. vector<int> res;
    7. if (nums.empty() || nums.size() == 0) return res;
    8. // 初始化两个候选人candidate,和他们的计票
    9. int cand1 = nums[0],count1 = 0;
    10. int cand2 = nums[0],count2 = 0;
    11. // 摩尔投票法,分为两个阶段:配对阶段 和 计数阶段
    12. // (1) 配对阶段
    13. for(const int &num : nums) {
    14. // 投票
    15. if(cand1 == num) {count1++;continue;}
    16. if(cand2 == num) {count2++;continue;}
    17. // 第 1 个候选人配对
    18. if(count1 == 0) {
    19. cand1 = num;
    20. count1++;
    21. continue;
    22. }
    23. // 第 2 个候选人配对
    24. if(count2 == 0) {
    25. cand2 = num;
    26. count2++;
    27. continue;
    28. }
    29. count1--;
    30. count2--;
    31. }
    32. // (2)计数阶段 : 找到了两个候选人之后,需要确定票数是否满足大于 N/3
    33. count1=0;
    34. count2=0;
    35. for(const int &num : nums) {
    36. if (cand1 == num) count1++;
    37. else if (cand2 == num) count2++;
    38. }
    39. if (count1 > nums.size() / 3) res.push_back(cand1);
    40. if (count2 > nums.size() / 3) res.push_back(cand2);
    41. return res;
    42. }
    43. };

    (3)进阶版 k值投票法

    1. class Solution {
    2. public:
    3. // k值摩尔投票法
    4. int k = 3;
    5. vector<int> majorityElement(vector<int>& nums) {
    6. // 创建返回值
    7. vector<int> res;
    8. if (nums.empty() || nums.size() == 0) return res;
    9. if (nums.size() == 1) return nums;
    10. int n = k-1, m = 2, cands[n][m];
    11. memset(cands, 0, sizeof(cands));
    12. for(int i=0;i
    13. cands[i][0]=nums[0];
    14. // cands[i][1]=0;
    15. }
    16. // 摩尔投票法,分为两个阶段:配对阶段 和 计数阶段
    17. bool voteflag=0;
    18. bool matchflag = 0;
    19. for(const int &num : nums) {
    20. for(int i=0;i
    21. // 投票
    22. if(cands[i][0] == num) {cands[i][1]++;voteflag=1;break;}
    23. else voteflag=0;
    24. }
    25. if(voteflag) continue;
    26. for(int i=0;i
    27. // 第 i 个候选人配对
    28. if(cands[i][1] == 0) {
    29. cands[i][0] = num;
    30. cands[i][1]++;
    31. matchflag=1;
    32. break;
    33. }
    34. else matchflag=0;
    35. }
    36. if(matchflag) continue;
    37. for(int i=0;i
    38. cands[i][1]--;
    39. }
    40. }
    41. // (2) 计数阶段
    42. for(int i=0;i
    43. if(cands[i][1]==0) cands[i][0] = INT_MAX;
    44. cands[i][1]=0;
    45. }
    46. for(const int &num : nums) {
    47. for(int i=0;i
    48. if (cands[i][0] == num ) {
    49. cands[i][1]++;
    50. }
    51. }
    52. for(int i=0;i
    53. if (cands[i][1] > nums.size() / k ) res.push_back(cands[i][0]);
    54. }
    55. return res;
    56. }
    57. };

    总结来自作者:我脱下短袖

    • 如果至多选一个代表,那他的票数至少要超过一半(⌊ 1/2 ⌋)的票数;
    • 如果至多选两个代表,那他们的票数至少要超过 ⌊ 1/3 ⌋ 的票数;
    • 如果至多选m个代表,那他们的票数至少要超过 ⌊ 1/(m+1) ⌋ 的票数。
    • 所以以后碰到这样的问题,而且要求达到线性的时间复杂度以及常量级的空间复杂度,直接套上摩尔投票法。

    作者:我脱下短袖
    链接:https://leetcode.cn/problems/majority-element-ii/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    推荐和参考文章:

    229. 多数元素 II - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/majority-element-ii/solutions/123170/liang-fu-dong-hua-yan-shi-mo-er-tou-piao-fa-zui-zh/229. 多数元素 II - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/majority-element-ii/solutions/1060343/gong-shui-san-xie-noxiang-xin-ke-xue-xi-ws0rj/

  • 相关阅读:
    【AUTOSAR-CAN-3】COM 模块详解
    掼蛋—算牌高手的博弈
    计算机组成原理_1
    Flink不止于计算,存算一体才是未来
    [入门一]C# webApi创建、与发布、部署、api调用
    cpu设计和实现(协处理器cp0)
    13个培训师游戏
    linux服务器部署项目
    JMeter自定义HTTP组件
    数据库第二次作业
  • 原文地址:https://blog.csdn.net/weixin_41987016/article/details/134097586