[Leetcode学习-java]Majority Element(找主要元素)

问题:

难度:easy

说明:

输入一个数组,里面有一个元素出现次数,是占了数组长度一半以及以上的(nums.length / 2或者以上),然后就称这个元素是主要元素,找到并返回它

输入范围:

输入数组不为空

输入案例:

Example 1:
// 3出现两次,数组长度3,所以3是主要元素
Input: [3,2,3]
Output: 3
Example 2:

// 同理,2出现4次是主要元素
Input: [2,2,1,1,1,2,2]
Output: 2

我的代码:

哇,这个就很爽了,秒题,用javaApi就搞定,当然效率低了点

class Solution {
    public int majorityElement(int[] nums) {
        // 拿系统快排一遍,就能得出中间元素必定是主要元素
        Arrays.sort(nums);
        // 位运算,意思是除以2
        return nums[nums.length >> 1];
    }
}

再修改一下,时间复杂度改为n,代码多了,但是效率提升了不是?

class Solution {
    public int majorityElement(int[] nums) {
        // 先指向末尾元素
        int m = nums[nums.length - 1];
        int c = 0;
        
        // 因为主要元素占了一半以上,进行统计的话主要元素的计数c 必定是0以及以上
        // 倒过来遍历
        for(int i = nums.length - 1;i -- > 0;) {
            // 遇到一样的元素 + 1,不然 - 1
            c += nums[i] == m ? 1 : -1;
            // 如果小于0就更换m
            if(c < 0) {
                m = nums[i];
                c = 0;
            }
        }
        return m;
    }
}

其它代码:

甚至有老哥用很繁琐的方法拿了榜一,大概是二分递归里面做处理

class Solution {
    //20200509 topk find 因为linear + in space 只有这个选择
    // majority 无论怎么移动,一定会在median上面。
    public int majorityElement(int[] nums) {
        if(nums == null){
            return Integer.MIN_VALUE;
        }
        int len = nums.length;
        
        //len 特值思考:len = 3, k = 2, len = 4, k = 2 or 3 
        return findTopK(nums, 0, len - 1, len/2 + 1);
    }
    private int findTopK(int[] nums, int start, int end, int k){
        if(start >= end && k == 1){
            return nums[start];
        }
        int left = start;
        int right = end;
        int pivot = nums[left + (right - left)/2];
        while(left <= right){
            while(left <= right && nums[left] < pivot){
                left++;
            }
            while(left <= right && nums[right] > pivot){
                right--;
            }
            if(left <= right){
                int tmp = nums[left];
                nums[left] = nums[right];
                nums[right] = tmp;
                left++;
                right--;
            }
        }
        if(start + k - 1 <=right){
            return findTopK(nums, start, right, k);
        } else if (start + k - 1 >= left){
            // s - r - l - e
            return findTopK(nums, left, end, k - (left - start));
        } else {
            return nums[right + 1];
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值