小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
多数元素
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
-
示例 1:
输入:[3,2,3]
输出:3
-
示例 2:
输入:[2,2,1,1,1,2,2]
输出:2
【进阶】:
尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。
来源:LeetCode
【暴力法】
// java
public static int majorityElement(int[] nums) {
if(nums.length==1){
return nums[0];
}
// 使用map来记录每个元素出现的次数
// 当元素出现的次数大于所有元素的一半时就返回该元素
// 否则没有满足题意的,返回-1
Map<Integer, Integer> map= new HashMap<>();
for(int i = 0;i<nums.length;i++){
if (map.containsKey(nums[i])){
map.put(nums[i],map.get(nums[i])+1);
}else{
map.put(nums[i],1);
}
if(map.get(nums[i])>nums.length / 2){
return nums[i];
}
}
return -1;
}
【摩尔投票法】
摩尔投票:找出一组数字序列中出现次数大于总数1/2的数字(假设这个数字一定存在),所以这个数字只能有一个。
核心思想:一抵一同归于尽。
每次从序列中选择两个不同的数字相互抵消掉,最后剩余的一个数字或者几个相同的数字就是出现次数大于一半的数字。
public static int majorityElement(int[] nums){
int major = nums[0];
int count = 1;
for (int i = 1; i < nums.length; i++) {
if (count == 0) {
//前面都消完了,再重新赋值
count++;
major = nums[i];
} else if (major == nums[i]) {
//自己人,count就加1
count++;
} else {
//不是自己人就同归于尽,消掉一个
count--;
}
}
return major;
}
【双指针+摩尔投票思想】
public static int majorityElement(int[] nums) {
int left = 0,right = nums.length-1;
// 排序之后方便进行首尾的抵消
Arrays.sort(nums);
// 双指针 + 摩尔投票思想
while(left<=right){
// 首尾两个数字不相同的话就抵消掉,
// 首尾指针分别进行自加自减
if (nums[left]!=nums[right]) {
left++;
right--;
}
if(nums[left] == nums[right]){
return nums[left];
}
}
return -1;
}