NowCoder
解题思路
Hash法
import java.lang.Integer;
import java.util.HashMap;
import java.util.*;
import java.lang.*;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array.length == 0)
return 0;
HashMap map = new HashMap<>();
for(int sum: array) {
map.put(sum,map.containsKey(sum) ? (int)map.get(sum)+1 : 1);
if((int)map.get(sum) > (array.length / 2))
return sum;
}
return 0;
}
}
众数法
import java.util.*;
import java.lang.*;
public class Solution {
public int MoreThanHalfNum_Solution(int[] nums) {
Arrays.sort(nums);
// 众数一定在符合条件的中间
int val = nums[nums.length / 2];
int count = 0;
for(int i : nums) {
if(i == val)
count++;
}
if(count > nums.length / 2) return val;
return 0;
}
}
多数投票法
多数投票问题,可以利用 Boyer-Moore Majority Vote Algorithm 来解决这个问题,使得时间复杂度为 O(N)。
使用 cnt 来统计一个元素出现的次数,当遍历到的元素和统计元素相等时,令 cnt++,否则令 cnt–。如果前面查找了 i 个元素,且 cnt == 0,说明前 i 个元素没有 majority,或者有 majority,但是出现的次数少于 i / 2 ,因为如果多于 i / 2 的话 cnt 就一定不会为 0 。此时剩下的 n - i 个元素中,majority 的数目依然多于 (n - i) / 2,因此继续查找就能找出 majority。
加入数组中存在众数,那么众数一定大于数组的长度的一半。
思想就是:如果两个数不相等,就消去这两个数,最坏情况下,每次消去一个众数和一个非众数,那么如果存在众数,最后留下的数肯定是众数。
具体做法:
初始化:候选人cond = -1, 候选人的投票次数cnt = 0
遍历数组,如果cnt=0, 表示没有候选人,则选取当前数为候选人,++cnt
否则,如果cnt > 0, 表示有候选人,如果当前数=cond,则++cnt,否则–cnt
直到数组遍历完毕,最后检查cond是否为众数
import java.lang.Integer;
import java.util.HashMap;
import java.util.*;
import java.lang.*;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array.length == 0)
return 0;
int val = -1, count = 0;
for(int sum : array) {
if(count == 0) {
val = sum;
count++;
}else {
if(val == sum) count++;
else count--;
}
}
count = 0;
for(int sum : array) {
if(val == sum) count++;
}
if(count > array.length / 2) return val;
return 0;
}
}