美文网首页
找出数组中重复超过一半的数(LeetCode Offer 39.

找出数组中重复超过一半的数(LeetCode Offer 39.

作者: 雁阵惊寒_zhn | 来源:发表于2020-11-14 11:01 被阅读0次

    题目

    找出数组中重复超过一半的数。
    例如:数组[1, 2, 3, 2, 2, 2, 5, 4, 2],重复超过一半的数是2。

    解析

    1. 排序思想。对数组进行排序,重复超过一半的数一定在数组中间下标的位置上。时间复杂度为O(n*logn)。
    2. 空间换时间。利用map结构存储统计每一个数字出现的次数,找到重复超过一半的数字。时间复杂度O(n),空间复杂度O(n)。
    3. 快速排序partition思想。借鉴快速排序的思想,每次都找到一个哨兵,然后数组会被分为两部分,一部分小于哨兵,一部分大于等于哨兵。如果哨兵处于中心位置就是最终的结果,否则只需要根据哨兵的位置,在两部分中的一部分继续寻找即可。时间复杂度O(n)。

    代码

    public int majorityElement(int[] nums) {
        return partition(nums, 0, nums.length - 1, nums.length / 2);
    }
    
    private int partition(int[] nums, int s, int e, int mid){
        int s0 = s; int e0 = e;
        int temp = nums[e];//标兵值
        while(s < e){
            //低位遍历
            while(nums[s] < temp && s < e){
                s++;
            }
            if(s < e){
                nums[e] = nums[s];
            }
            //高位遍历
            while(nums[e] >= temp && s < e){
                e--;
            }
            if(s < e){
                nums[s] = nums[e];
            }
        }
        //把哨兵放回数组
        nums[s] = temp;
        if(mid == s){//如果哨兵就处于中间位置,直接返回
            return temp;
        } else if(mid < s){//如果哨兵大于中间位置,递归小于哨兵的数组部分
            return partition(nums, s0, s - 1, mid);
        } else {//如果哨兵小于中间位置,递归大于等于哨兵的数组部分
            return partition(nums, s + 1, e0, mid);
        }
    }
    

    相关文章

      网友评论

          本文标题:找出数组中重复超过一半的数(LeetCode Offer 39.

          本文链接:https://www.haomeiwen.com/subject/peslvktx.html