zoukankan      html  css  js  c++  java
  • 剑指 Offer 39. 数组中出现次数超过一半的数字

    思路

    下文使用majority来代表“数组中出现次数超过一半的数字 ” 。

    方法一:哈希表

    遍历数组 nums ,用 map 统计各数字的数量,即可找出 majority 。

    时间复杂度:O(n)

    空间复杂度:O(n)

     1 class Solution {
     2 private:
     3     unordered_map<int, int> cntMap;
     4 public:
     5     int majorityElement(vector<int>& nums) {
     6         for(int& num: nums) {
     7             cntMap[num]++;
     8             if(cntMap[num] > nums.size()/2)
     9                 return num;
    10         }
    11 
    12         return -1;
    13     }
    14 };

    方法二:排序

    将数组 nums 排序,数组中点的元素 一定为 majority。

    时间复杂度:O(nlogn)

    1 class Solution {
    2 public:
    3     int majorityElement(vector<int>& nums) {
    4         sort(nums.begin(), nums.end());
    5         return nums[nums.size()/2];
    6     }
    7 };

    方法三:Boyer-Moore 投票算法 (摩尔投票法)

    设置一个计数器vote,每遇到一个和当前的数字相同的数字,就让vote自增,遇到一个和当前数字不一样的数字,就让vote--,当vote< 0时,就将majority设置为当前遍历的数字。因为有一个数字出现次数超过数组长度的一半,最后得到的必然是该数字。

    时间复杂度:O(n)

    空间复杂度:O(1)

    此方法时间和空间复杂度分别为 O(N)和 O(1),为本题的最佳解法。

     1 class Solution {
     2 public:
     3     int majorityElement(vector<int>& nums) {
     4         int vote = 0;
     5         int majority = 0;
     6         for(int& num: nums) {
     7             if(vote == 0)
     8                 majority = num;
     9             if(majority == num)
    10                 vote++;
    11             else
    12                 vote--;
    13         }
    14 
    15         return majority;
    16     }
    17 };
  • 相关阅读:
    字符串转换成整数
    回文字符串判断
    字符串包含
    翻转单词顺序VS左旋转字符串
    穷举子集合
    求S=a+aa+aaa+aaaa+aa...a的值
    数组元素去重
    找最长等差数列的长度
    Git pull and push
    Google 开发console查找元素或方法
  • 原文地址:https://www.cnblogs.com/FengZeng666/p/13924773.html
Copyright © 2011-2022 走看看