• 剑指 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 };
  • 相关阅读:
    免费云盘,为什么不用?
    把握linux内核设计思想系列
    volley基本使用方法
    金朝阳——软件測试试题11道题目分享
    可编辑ztree节点的增删改功能图标控制---已解决
    POJ 3370 Halloween treats 鸽巢原理 解题
    Axure RP一个专业的高速原型设计工具
    Linux内核剖析 之 进程简单介绍
    [iOS]怎样在iOS开发中切换显示语言实现国际化
    scp and tar
  • 原文地址:https://www.cnblogs.com/FengZeng666/p/13924773.html
Copyright © 2020-2023  润新知