169.多数元素
思路一:
适用哈希映射(HashMap)来实现,key表示数组的元素,value表示各元素出现的次数,然后找到出现次数最大的一个或者,找到第一次超过n/2次的元素。
class Solution {
public int majorityElement(int[] nums) {
int mid = nums.length / 2;
Map<Integer, Integer> count = new HashMap<>();
for (int num : nums) {
if (count.containsKey(num)) {
if (count.get(num) + 1 > mid) {
return num;
} else {
count.put(num, count.get(num) + 1);
}
} else {
count.put(num, 1);
}
}
for (int num : count.keySet()) {
return num;
}
return 0;
}
}
思路二:
因为考虑到多数元素的定义是出现次数超过n/2次的元素,那么考虑排序后取n/2下标的值就是多数元素;
假如长度为奇数的数组(例如7),出现次数大于n/2(例如3.5,即最少出现4次)的元素,那么排序后位于中间位置(4)元素肯定是属于那个最多的。
假如长度为偶数的数组(例如6),出现次数大于n/2(例如3,即最少出现4次)的元素,那么排序后位于第3、4都应该是最大的,所以取第3、4都可以。
class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length/2];
}
}
适用java的排序,使用的是双轴快速排序;
考虑到我们取的是中间位置的数,那么可以采用快速排序,然后根据每次分割后的下标
若下标刚好是中间位置,那么就是这个数为众数;
后面的排序只需要排中间位置存在的的那一个分组
这样就不用全部排序;
class Solution {
public int majorityElement(int[] nums) {
return quickSort(nums, 0, nums.length - 1, nums.length / 2);
}
private int quickSort(int[] nums, int low, int high, int mid) {
int index = getIndex(nums, low, high);
if (index == mid) {
return nums[mid];
}
if (index > mid) {
return quickSort(nums, low, index - 1, mid);
} else {
return quickSort(nums, index + 1, high, mid);
}
}
private int getIndex(int[] nums, int low, int high) {
int temp = nums[low];
int i = low;
int j = high;
while (i != j) {
while (nums[j] >= temp && i < j)
j--;
//再找右边的
while (nums[i] <= temp && i < j)
i++;
//交换两个数在数组中的位置
if (i < j) {
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
}
//最终将基准数归位
nums[low] = nums[i];
nums[i] = temp;
return i;
}
}
思路三:
在解题思路中找到的方法—Boyer-Moore 算法:
- Boyer-Moore 算法
- 维护一个候选众数 candidate 和它出现的次数 count。初始时 candidate 可以为任意值,count 为 0;
- 遍历数组中的所有元素,对于每个元素 x
- 在判断 x 之前,如果 count 的值为 0,我们先将 x 的值赋予 candidate,随后我们判断 x:
- 如果 x 与 candidate 相等,那么计数器 count 的值增加 1;
- 如果 x 与 candidate 不等,那么计数器 count 的值减少 1。
- 在遍历完成后,candidate 即为整个数组的众数。
class Solution {
public int majorityElement(int[] nums) {
int count = 0;
Integer candidate = null;
for (int num : nums) {
if (count == 0) {
candidate = num;
}
count += (num == candidate) ? 1 : -1;
}
return candidate;
}
}