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


    思路分析

    大于数组长度的数字有多少个?
    很明显只有一个.
    因为如果有多个就矛盾了.

    哈希表

    哈希表的思路就很简单了,就是每个数的出现次数,然后找出超过一半的那个数.
    cpp

    class Solution {
    public:
        int majorityElement(vector<int>& nums) {
            unordered_map<int,int> d;
            for(auto x:nums)
                if(d.count(x))d[x]+=1;
                else d[x]=1;
            int n = nums.size()/2;
            for(unordered_map<int,int>::iterator i=d.begin();i!=d.end();i++)
                if(i->second>n)return i->first;
    
            return 0;
        }
    };
    

    python

    class Solution:
        def majorityElement(self, nums: List[int]) -> int:
            d = dict()
            n = len(nums)//2
            for x in nums:
                if x not in d:d[x]=1
                else: d[x]+=1
            for k,v in d.items():
                if v>n:return k
            return 0
    

    排序

    排序就是超过一半数一点在中间位置.

    cpp

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

    python

    class Solution:
        def majorityElement(self, nums: List[int]) -> int:
            nums.sort()
            return nums[len(nums)//2]
    

    摩尔投票

    如何证明是对的?
    用"消耗"的角度来看, 如果要消灭一个"众数",那么就必须要一个非"众数",那么最后"众数"肯定是有剩余的

    value: 
    count:
    
    遍历数组,
    如果count=0,那么将value换为x
    如果count!=0,
    1) value!=x,则count--
    2) value==x,则count++
    
    最后的value就是答案
    

    cpp

    class Solution {
    public:
        int majorityElement(vector<int>& nums) {
            int value,count=0;
            for(auto x:nums){
                if(!count)value=x,count=1;
                else{
                    if(value==x)count++;
                    else count--;
                }
            }
            return value;
        }
    };
    

    python

    class Solution:
        def majorityElement(self, nums: List[int]) -> int:
            value,count=None,0
            for x in nums:
                if not count:
                    value=x
                    count=1
                else:
                    if x==value:count+=1
                    else: count-=1
            return value
    

    延申情景: 好人和坏人/好软件和坏软件
    就是有超过n/2的都是好人,剩下都是坏人.
    你可以询问每一个人,每个人都是知道直接和其他人的身份.
    但是,好人会实话实说,坏人就不会实话实说,如何找出坏人?

    从"消耗对"的角度来看,好人-坏人是一对的.
    但是好人是一定比坏人多的,所以最后剩下的一定是好人
    现在要把所有的坏蛋找出来.
    
    value: 某人
    count: 信任值
    
    如果信任值为0,那么说明这个人就是坏人,就把这个人删除
    然后从头开始,直到循环遍历结束.
    
    
    
  • 相关阅读:
    java 11 值得关注的新特性
    MessageDigest来实现数据加密
    LinkedList(JDK1.8)源码分析
    gradle配置统一管理
    Android 新架构组件 -- WorkManager
    RF使用ie浏览器访问页面,浏览器启动只显示This is the initial start page for the WebDriver server,页面访问失败
    jenkins配置RF构建结果显示
    jenkins配置QQ邮箱自动发送RF测试构建结果通知邮件
    RF变量列表类型@{}和${}列表类型的关系
    jekins构建通知邮件配置及邮件附件设置,jenkins构建通知邮件没有RF的log和report文件
  • 原文地址:https://www.cnblogs.com/Rowry/p/14309976.html
Copyright © 2011-2022 走看看