主元素问题
问题描述
主元素的定义为:数组中出现次数超过数组长度一半以上的元素。
输入一个无序数组,输出主元素(不能保证一定存在主元素)。
解决思路
经典的芯片测试问题:
1. 首先将数组的首元素置为主元素候选,并附加一个计数器,初始为1;
2. 遍历数组之后的元素,如果元素与候选元素相等,计数器加1;否则计数器减1;途中如果计数器为0,则将当前遍历元素设为候选元素。
因为不能保证最后得到的候选元素一定是主元素,例如[1, 2, 3]。
所以最后要对该候选元素进行验证,验证方式为重新遍历一遍数组,对该候选元素进行计数,最后判断该次数是否超过数组长度的一半。
程序
public class MajorityElem {
public int getMajorityElem(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
int candidate = nums[0];
int count = 1;
for (int i = 1; i < nums.length; i++) {
if (count == 0 || candidate == nums[i]) {
candidate = nums[i];
++count;
} else {
--count;
}
}
if (verify(nums, candidate)) {
return candidate;
}
return -1;
}
private boolean verify(int[] nums, int candidate) {
int count = 0;
for (int n : nums) {
if (n == candidate) {
++count;
}
}
return count > nums.length / 2;
}
}
Follow Up
Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.
解决思路
思路与主元素问题相似,不同的在于需要设置两个candidates(数组中满足如上定义的元素个数最多为2个)。
程序
public class MajorityElem2 {
public List<Integer> majorityElement(int[] nums) {
List<Integer> res = new ArrayList<Integer>();
if (nums == null || nums.length == 0) {
return res;
}
int candicate1 = 0, candicate2 = 0;
int count1 = 0, count2 = 0;
for (int i = 0; i < nums.length; i++) {
if (count1 == 0 || candicate1 == nums[i]) {
++count1;
candicate1 = nums[i];
} else if (count2 == 0 || candicate2 == nums[i]) {
++count2;
candicate2 = nums[i];
} else {
--count1;
--count2;
}
}
verify(nums, candicate1, candicate2, res);
return res;
}
private void verify(int[] nums, int candicate1, int candicate2,
List<Integer> res) {
int len = nums.length;
int count1 = 0, count2 = 0;
for (int n : nums) {
if (n == candicate1) {
++count1;
}
if (n == candicate2) {
++count2;
}
}
if (count1 > len / 3) {
res.add(candicate1);
}
if (candicate1 == candicate2) {
return ;
}
if (count2 > len / 3) {
res.add(candicate2);
}
}
}
Bugs:
Case:[0, 0, 0], output: 0, 0
candidate1和candidate2有可能相同,如果都满足,只需要输出一个即可。
leetcode题目链接
https://leetcode.com/problems/majority-element/
https://leetcode.com/problems/majority-element-ii/

浙公网安备 33010602011771号