• 剑指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,那么说明这个人就是坏人,就把这个人删除
    然后从头开始,直到循环遍历结束.
    
    
    
  • 相关阅读:
    【DOM】如何给div的placeholder传参
    【nvm】使用nvm将node升级到指定版本
    【Worktile】升级业务组件库后,http的数据返回整个response而不是data问题及解决方案
    js获取上传文件内容
    【正则】正则表达式-零宽断言(?=,?<=,?!,?<!)及常见报错
    【Angular】动态组件
    【扩展】div获取焦点或可编辑
    【CSS】position新增属性sticky
    thinkphp写接口返回固定的形式方法
    thinkphp5计算文件大小
  • 原文地址:https://www.cnblogs.com/Rowry/p/14309976.html
Copyright © 2020-2023  润新知