您的位置:首页 > 其它

主元素问题

2015-06-30 11:49 239 查看
问题描述

主元素的定义为:数组中出现次数超过数组长度一半以上的元素。

输入一个无序数组,输出主元素(不能保证一定存在主元素)。

解决思路

经典的芯片测试问题:

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/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: