多数元素
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
方法一:hash表法
这是一个最容易想到的方法,利用hash表,遍历数组,遇到相同的key则key对应的value+1,遍历结束后找到value大于n/2的key就是多数元素。
public int majorityElement(int[] nums) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i : nums) {
if (map.containsKey(i)) {
map.put(i, map.get(i) + 1);
} else {
map.put(i, 1);
}
}
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if (entry.getValue() > nums.length / 2) {
return entry.getKey();
}
}
return 0;
}
- 时间复杂度:
O(n)
- 空间复杂度:
O(n)
方法二:排序法
这个方法就显得很简洁。
题中说每个所给数组总是存在多数元素,那可以将数组排序,那无论如何nums[n/2]出都会使多数元素。
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length / 2];
}
- java提供的数组排序方法时间复杂度:
O(nlogn)
- java的排序算法所需空间复杂度:
O(logn)
方法三:Boyer-Moore 投票法
这是官方提供的一个很有意思的算法。
可以理解为相同元素为支持者,不同元素为反对者,支持者会将该元素票数+1,反对者会将该元素票数-1
顺序遍历数组,先选举第一个元素作为候选人,遇到相同元素就投它一票,遇到不同元素就减少一票,当这个候选人没有票了,则下台,换当前的元素作为候选人,到最后,仍然有票的为多数元素。
public int majorityElement(int[] nums) {
int num = 0;
int count = 0;
for (int i : nums) {
if (count == 0) {
num = i;
}
if (num == i) {
count++;
}else {
count--;
}
}
return num;
}
由于这道题总是存在多数元素,所以你不必担心当前元素是否有资格当候选人,因为等遍历完成后,其他元素的票与多数元素的票相互抵消,必然只有多数元素手里有票。
- 时间复杂度:
O(n)
- 空间复杂度:
O(1)