给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:[3,2,3]
输出:3
示例 2:输入:[2,2,1,1,1,2,2]
输出:2
进阶:
尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/majority-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
使用哈希表:
public int majorityElement(int[] nums) { //时间复杂度O(n) //空间复杂度O(n) //找到n为几,这个就是次数 int n = nums.length / 2; Map<Integer,Integer> size = new HashMap<>(); for(int i = 0; i < nums.length ; i++){ int temp = size.getOrDefault(nums[i],0); if(temp > n){ return nums[i]; } size.put(nums[i],temp+1); } for (Integer key : size.keySet()) { if(size.get(key) > n){ return key; } } return 0; }
排序:
public int majorityElement(int[] nums) { //时间复杂度O(nlogn) //空间复杂度O(logn) //找到n为几,这个就是次数 Arrays.sort(nums); return nums[nums.length / 2]; }
Boyer-Moore 投票算法
Boyer-Moore 算法的详细步骤:
我们维护一个候选众数 candidate 和它出现的次数 count。初始时 candidate 可以为任意值,count 为 0;
我们遍历数组 nums 中的所有元素,对于每个元素 x,在判断 x 之前,如果 count 的值为 0,我们先将 x 的值赋予 candidate,随后我们判断 x:
如果 x 与 candidate 相等,那么计数器 count 的值增加 1;
如果 x 与 candidate 不等,那么计数器 count 的值减少 1。
在遍历完成后,candidate 即为整个数组的众数
public int majorityElement(int[] nums) { // /** * Boyer-Moore 投票算法”可以分两种情况考虑: * * 如果候选众数c都是真正的众数maj,根据众数的定义,众数的数量要比其它数的数量和还要多,因此,如果每一个候选众数c都消除掉一个其它数(不等于c的数),那最后剩下的必定是众数。 * 如果候选众数c中存在非众数,同样,由于每一个候选众数c都消除掉一个其它数(!=c),可能会有真正众数maj或者除c以外的其他非众数被消掉,最后剩下的数必然还是众数,而且剩余众数数量>第一种情况剩余众数数量。 * 综上,最后剩下的一定是众数。 */ //时间复杂度O(n) //空间复杂度O(n) Integer candidate = null; int count = 0; for(int i = 0; i < nums.length ; i++){ if(count == 0){ candidate = nums[i]; } count += (nums[i] == candidate ? 1 : -1); } return candidate; }