• 169. Majority Element


    ▶ 整数数组中有一个数出现的频数超过了数组长度的一半,求这个数

    ● 自己的代码,27 ms,使用散列表,最快的解法算法与之相同,但是用的数据结构是 map

     1 class Solution
     2 {
     3 public:
     4     int majorityElement(vector<int>& nums)
     5     {       
     6         const int n = nums.size();
     7         unordered_map<int, int> table;
     8         int i;
     9         for (i = 0; i < n; i++)
    10         {
    11             if (table.find(nums[i]) == table.end())
    12                 table[nums[i]] = 1;
    13             else
    14                 table[nums[i]]++;
    15         }
    16         for (i = 0; i < n; i++)
    17         {
    18             if (table[nums[i]] > n / 2)
    19                 return nums[i];
    20         }
    21         return -1;
    22     }
    23 };

    ● 大佬的解法,16 ms,摩尔投票算法(Boyer-Moore Voting Algorithm),时间复杂度 O(n) 空间复杂度 O(1) 。

    ■ 从头扫描原数组时对 nums[ 0 ] 计数,新元素等于 nums[ 0 ] 时计数加一,不等于 nums[ 0 ] 时计数减一,如果扫描完第 k 元素时计数减到了 0,说明在第 0 到第 k 元素中 nums[ 0 ] 和其他元素各有 ( k +1 ) / 2 个

    ■ 这时考虑把第 0 到 第 k 元素砍掉:① 若 nums[ 0 ] 本来就是所求的众数,砍掉这段后 nums[ 0 ] 在剩下的部分中仍然具有 “频数超过一半” 的性质;②若 nums[ 0 ] 不是所求的众数,则由于砍掉的其他元素个数之和不超过 nums[ 0 ](极端情况是其他 ( k +1 ) / 2 个元素都相等,它是所求众数的另一个有力竞争者),所以也不影响剩余数组中真正的所求众数的性质

    ■ 若数组还有剩余,则取下一个元素作为被计数的元素,重复以上过程。这样就能在最后一段中获得所求众数(完成扫描后计数器应当 ≥ 0)。

    ■ 注意该算法只能用于计算出现次数超过原数组长度一半的情况(如 [ 1,1,1,2,2,3,3 ] 就不行),当数组没有满足该条件的数字时,将会返回最后一段的被计数元素

     1 class Solution
     2 {
     3 public:
     4     int majorityElement(vector<int>& nums)
     5     {
     6         const int n = nums.size();
     7         int i, count, numMajor; 
     8         for (int i = count = numMajor = 0; i < n; i++)
     9         {
    10             if (count == 0)
    11                 numMajor = nums[i];
    12             if (numMajor == nums[i])
    13                 count++;
    14             else
    15                 count--;
    16         }
    17         return numMajor;
    18     }
    19 };

    ● 其他方法(后接时间复杂度 / 空间复杂度):逐项计数法 O(n) / O(1),排序法 O(n log n) / O(1) ,分治法 O(n log n) / O(log n) 。

  • 相关阅读:
    JS基础(一)异常错误
    实验四 主存空间的分配和回收
    实验三、进程调度模拟程序实验
    学习进度条
    软件工程学期总结
    实验四、主存空间的分配和回收
    诚信与道德
    【操作系统】实验三、进程调度模拟程序实验
    软件工程---在此基础上,进行软件的改进
    【操作系统】实验二 作业调度模拟程序
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/8395369.html
Copyright © 2020-2023  润新知