本文已参与「新人创作礼」活动,一起开启掘金创作之路。
Leetcode 169题 多数元素
题目描述:
Problem Describe
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
题目分析:
Problem Analysis
提炼出本题的关键点,总结如下:
1、数组存在多个整数元素
2、其中某个数值在这个数组中出现的次数大于 ⌊ n/2 ⌋次
常规的思路:牺牲空间代价,创建一个可以保存每个数值出现次数的集合。最好的选择是HashMap数组,能够使用键值对将数值和次数关联在一起。格式为:<数值: 次数>
按照元素统计次数,可定义式子如下:
常规思路代码:
class Solution {
public int majorityElement(int[] nums) {
Map<Integer, Integer> map = new HashMap();
for(int i = 0; i < nums.length; i++) {
int val = map.get(nums[i]) == null ? 0 : map.get(nums[i]);
if(val != 0) {
val++;
} else {
val = 1;
}
map.put(nums[i], val);
if(val > nums.length / 2) {
return nums[i];
}
}
return 0;
}
}
是否能够在不申请HashMap空间的情况下,把这个在数组中占有 ⌊ n/2 ⌋ 的元素找到?
答案是肯定可以的。可以定义一个元素,用于保存这个重复值,定义count用于计算该元素出现的次数。遍历取出数组的元素,进行下面的比较:
(1)当出现的是临时空间(哨兵)所保存的数值时,就将count值加1;
(2)若不是这个元素值,且计数的count值为0,则这个哨兵保存从数组取出的这个新值,且将count值置为1
(3)若不是哨兵所保存的元素值,且计数的count值大于0,则将count值减1,以表示两个数之间产生了抵消(比较两个元素哪个次数多,可以对他们)
完整代码:
class Solution {
public int majorityElement(int[] nums) {
int count = 1;
int replica = nums[0];
for(int i = 1; i < nums.length; i++) {
if(replica == nums[i]) {
count++;
} else if(count <= 0) {
count++;
replica = nums[i];
} else {
count--;
}
}
return replica;
}
}