题目描述:
给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋
的元素。
你可以假设数组是非空的,并且给定的数组总是存在众数。
示例 1: 输入: [3,2,3] 输出: 3 示例 2: 输入: [2,2,1,1,1,2,2] 输出: 2
思路分析:
思路一:暴力枚举
class Solution { public static int majorityElement(int[] nums) { if (nums == null || nums.length == 0) { return Integer.MIN_VALUE; } for (int i = 0; i < nums.length; i++) { int res = nums[i]; int count = 0; for (int j = 0; j < nums.length; j++) { if (nums[j] == res) { count++; } } if (count > nums.length / 2) { return res; } } return Integer.MIN_VALUE; } }
时间复杂度:O(n^2)
空间复杂度:O(1)
思路二:Hash,用空间换时间
class Solution { //用hash,空间换时间,时间复杂度O(n),空间复杂度 public static int majorityElement(int[] nums) { if (nums == null || nums.length == 0) { return Integer.MIN_VALUE; } Map<Integer, Integer> map = new HashMap<>(nums.length); for (int i = 0; i < nums.length; i++) { Integer count = map.get(nums[i]); if (count != null) { count++; map.put(nums[i], count); } else { map.put(nums[i], 1); } } for (Integer key : map.keySet()) { if (map.get(key) > nums.length / 2) { return key; } } return Integer.MIN_VALUE; } }
时间复杂度:O(n)
空间复杂度:O(n)
思路三:排序法:因为是众数,所以排序过后,数组中间的数就是众数
class Solution { public static int majorityElement(int[] nums) { if (nums == null || nums.length == 0) { return Integer.MIN_VALUE; } Arrays.sort(nums); return nums[nums.length / 2]; } }
时间复杂度:O(NlogN)
空间复杂度:O(1)
思路四:摩尔投票法
其核心思想就是:抵消
最差的情况就是其他所有的数都跟众数做了抵消,但是由于众数出现的次数大于1/2,所以最终剩下的还是众数。
class Solution { //摩尔投票算法 public static int majorityElement(int[] nums) { if (nums == null || nums.length == 0) { return Integer.MIN_VALUE; } int target = nums[0]; int count = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] == target) { count++; } else { if (count >= 1) { count -= 1; } else { target = nums[i]; } } } return target; } }
时间复杂度:O(N)
空间复杂度:O(1)