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

    数组中出现次数超过一半的数字

    数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

    你可以假设数组是非空的,并且给定的数组总是存在多数元素。

    示例 1:

    输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
    输出: 2

     

    #include<iostream>
    #include<bits/stdc++.h>
    #include<cstring>
    #include<vector>
    #include<map>
    using namespace std;
    
    int cmp(pair<int,int>&a,pair<int,int>&b){
        return a.second<b.second;
    }
    int main(){
        int num;
        vector<pair<int,int> >vec;
        cin>>num;
        map<int,int> mymap;
        mymap[num]++;
        while (cin.get()!='
    ')
        {
            cin>>num;
            mymap[num]++;
        }
        for (map<int,int>::iterator it=mymap.begin(); it != mymap.end(); it++)
        {
            vec.push_back(*it);
        }
        sort(vec.begin(),vec.end(),cmp);
        // for (int i = 0; i < vec.size(); i++)
        // {
        //     cout<<vec[i].first<<" "<<vec[i].second<<endl;
        // }
        cout<<vec[vec.size()-1].first<<endl;
    }

     

     

    解题思路:
    本题常见解法如下:

    哈希表统计法: 遍历数组 nums ,用 HashMap 统计各数字的数量,最终超过数组长度一半的数字则为众数。此方法时间和空间复杂度均为 O(N) 。

    数组排序法: 将数组 nums 排序,由于众数的数量超过数组长度一半,因此 数组中点的元素 一定为众数。此方法时间复杂度 O(Nlog 2N)。

    摩尔投票法: 核心理念为 “正负抵消” ;时间和空间复杂度分别为 O(N) 和 O(1) ;是本题的最佳解法

    摩尔投票法:

    票数和: 由于众数出现的次数超过数组长度的一半;若记 众数 的票数为 +1 ,非众数 的票数为 -1 ,则一定有所有数字的 票数和 > 0 。

    票数正负抵消: 设数组 nums 中的众数为 x ,数组长度为 n 。若 nums 的前 a 个数字的 票数和 = 0x,则 数组后 (n-a)个数字的 票数和一定仍 >0 (即后 (n-a)个数字的 众数仍为 x)。

     

     

     

     

    class Solution {
        public int majorityElement(int[] nums) {
            int x = 0, votes = 0;
            for(int num : nums){
                if(votes == 0) x = num;
                votes += num == x ? 1 : -1;
            }
            return x;
        }
    }

    题目拓展:
    由于题目明确给定 给定的数组总是存在多数元素 ,因此本题不用考虑 数组中不存在众数 的情况。
    若考虑,则需要加入一个 “验证环节” ,遍历数组 nums 统计 x 的数量。
    若 x 的数量超过数组长度一半,则返回 x ;
    否则,返回 0 (这里根据不同题目的要求而定)。
    时间复杂度仍为 O(N),空间复杂度仍为 O(1) 。

    class Solution {
        public int majorityElement(int[] nums) {
            int x = 0, votes = 0, count = 0;
            for(int num : nums){
                if(votes == 0) x = num;
                votes += num == x ? 1 : -1;
            }
            // 验证 x 是否为众数
            for(int num : nums)
                if(num == x) count++;
            return count > nums.length / 2 ? x : 0; // 当无众数时返回 0
        }
    }

     

    因上求缘,果上努力~~~~ 作者:每天卷学习,转载请注明原文链接:https://www.cnblogs.com/BlairGrowing/p/13549147.html

  • 相关阅读:
    powerdesigner得使用放法
    sql sever连接名忘记了该怎么办
    算法第四版 1.2.10
    算法第四版 1.2.8
    算法第四版 1.2.6
    算法第四版 1.2.2
    二分查找递归实现
    关于斐波那契数列和递归
    编写一段代码,打印一个M行N列的二维数组转置。(交换行和列)
    基础实验2-2.1 整数的分类处理 (20分)
  • 原文地址:https://www.cnblogs.com/BlairGrowing/p/13549147.html
Copyright © 2011-2022 走看看