问题
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.
Example 1:
Input: [3,2,3]
Output: 3
Example 2:
Input: [2,2,1,1,1,2,2]
Output: 2
方法1
用map来统计每个数字的出现次数.
时间复杂度
O
(
n
)
O(n)
O(n).
空间复杂度
O
(
n
)
O(n)
O(n).
class Solution {
public int majorityElement(int[] nums) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int num : nums){
map.put(num, map.getOrDefault(num, 0) + 1);
if(map.get(num) > nums.length/2)
return num;
}
return 0;
}
}
方法2
排序后取最中间的值.
时间复杂度
O
(
n
l
o
g
n
)
O(n logn)
O(nlogn).
空间复杂度
O
(
1
)
O(1)
O(1).
class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length / 2];
}
}
方法3
有更取巧的方法. 因为Majority Element 一定存在, 所以一定有一个数字的存在个数是大于 n/2 的, 也就是说肯定存在一个数, 它出现的次数是大于其他所有数字出现的个数的和. 那么考虑以下算法.
- 选取第一个数字为备选答案, 计数器设为1.
- 如果计数器为0,那么重新选取备选答案.
- 如果后续的数字等译备选答案, 那么计数器加1, 否则计数器减1.
对于每一个备选答案都有两种情况
- 如果最终答案是它, 那么它能留到最后, 因为它的数量是大于其他所有数字的和
- 如果最终答案不是它, 那么这里又有两种情况 A) 消耗掉其他非正确答案的个数, 对于最终结果没有影响. B)消耗掉最终答案的个数, 因为最终答案的个数是大于n/2 ,所以对最终答案也没有影响.
时间复杂度
O
(
n
)
O(n)
O(n).
空间复杂度
O
(
1
)
O(1)
O(1).
class Solution {
public int majorityElement(int[] nums) {
int count = 1, cand = nums[0];
for (int i = 1; i < nums.length; i++) {
int num = nums[i];
if (count == 0)
cand = num;
count += (cand == num ? +1 : -1);
}
return cand;
}
}