• majority element(数组中找出出现次数最多的元素)


    Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

    You may assume that the array is non-empty and the majority element always exist in the array.

    这里题目要求找出出现次数超过n/2的元素。

    可以先排序,出现次数超过一半的元素会出现在数组中间。时间O(nlogn)空间O(1)

    无论找出出现次数多于多少的元素,都可以使用HashMap来找,在往map中添加的时候就可以判断了。O(n)时间复杂度和空间复杂度

     public int majorityElement(int[] nums) {
            if(nums.length==1) return nums[0];
            HashMap<Integer,Integer> map=new HashMap<>();
            for(int i=0;i<nums.length;i++){
                if(map.get(nums[i])==null)
                    map.put(nums[i],1);
                else{
                    int num=map.get(nums[i]);
                    if(num+1>nums.length/2) return nums[i];
                    map.put(nums[i],num+1);
                }
            }
            return 0;
        }

    多数投票算法。。

    该算法时间复杂度为O(n),空间复杂度为O(1),只需要对原数组进行两趟扫描,并且简单易实现。第一趟扫描我们得到一个候选节点candidate,第二趟扫描我们判断candidate出现的次数是否大于⌊ n/2 ⌋。这里题目说元素必然存在,所以第二趟就省略了。先看代码.

       public int majorityElement(int[] nums) {
            int candidate=0;int count=0;
            for(int i=0;i<nums.length;i++){
                if(count==0){
                    count++;
                    candidate=nums[i];
                }else if(candidate==nums[i]) count++;
                else count--;
            }
            return candidate;
        }

    我们来看看原理。(参考http://blog.csdn.net/kimixuchen/article/details/52787307)

    因为存在超过一半次数的元素,上面算法中,该元素会去抵消其他的元素(抵消一个count就变为0)。然后该元素还有剩余,所以最后的candidate就是该元素了。

    为了解析算法的原理,我们只要考虑存在多数元素的情况即可,因为第二趟扫描可以检测出不存在多数元素的情况。

    举个例子,我们的输入数组为[1,1,0,0,0,1,0],那么0就是多数元素。 
    首先,candidate被设置为第一个元素1,count也变成1,由于1不是多数元素,所以当扫描到数组某个位置时,count一定会减为0。在我们的例子中,当扫描到第四个位置时,count变成0.

    count 值变化过程: 
    [1,2,1,0……

    当count变成0时,对于每一个出现的1,我们都用一个0与其进行抵消所以我们消耗掉了与其一样多的0,而0是多数元素,这意味着当扫描到第四个位置时,我们已经最大程度的消耗掉了多数元素。然而,对于数组从第五个位置开始的剩余部分,0依然是其中的多数元素(注意,多数元素出现次数大于⌊ n/2 ⌋,而我们扫描过的部分中多数元素只占一般,那剩余部分中多数元素必然还是那个数字)。如果之前用于抵消的元素中存在非多数元素,那么数组剩余部分包含的多数元素就更多了。

    类似的,假设第一个数字就是多数元素,那么当count减为0时,我们消耗掉了与多数元素一样多的非多数元素,那么同样道理,数组剩余部分中的多数元素数值不变。

    这两种情况证明了关键的一点:数组中从candidate被赋值到count减到0的那一段可以被去除,余下部分的多数元素依然是原数组的多数元素。我们可以不断重复这个过程,直到扫描到数组尾部,那么count必然会大于0,而且这个count对应的candinate就是原数组的多数元素。

    对于其他求不是超过n/2的,而是n/k的,可以使用map。

  • 相关阅读:
    ES6常用语法简介
    webpack核心概念
    前端模块化规范详解
    使用Node.js原生代码实现静态服务器
    Node.js脚手架express与前段通信【socket】
    临门一脚- Node.js
    redis缓存穿透和雪崩
    redis哨兵模式
    redis主从复制
    redis发布订阅
  • 原文地址:https://www.cnblogs.com/xiaolovewei/p/8085969.html
Copyright © 2020-2023  润新知