众数
多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋
的元素,也可以称为众数,即:数字序列中某个数字的数量超过一般的数字。
原题参考:力扣
方案
入参:int [] nums
1. Map统计每个的个数。 如果元素在一定的范围内,可以使用地址寻址的方式。
2. 排序,超过一般的绝对是最大数
3. 随机拿一个元素,大概率是众数,如果不是继续获取
4. 如果众数标记为1,非众数标记为-1,Sum(众数)+Sum(非众数)>0,默认拿第一个作为候选
HashMap统计
/**
* 1. HashMap统计
* @param nums
* @return
*/
public int majorityElement1(int[] nums) {
Map<String,Integer> countMap = new HashMap<>();
// 最多数字的字符和数量
int count1 = 0;
int count2 = 0;
Integer count = null;
for(int i = 0 ; i< nums.length ;i++){
count = countMap.get(nums[i] +"");
if(count == null){
countMap.put(nums[i] +"", count = 1);
}else{
countMap.put(nums[i] +"",++count);
}
if(count > count1){
count1 = count;
count2 = nums[i] ;
}
}
return count2;
}
排序
/**
* 2. 排序
* @param nums
* @return
*/
public int majorityElement2(int[] nums) {
int temp = 0;
for(int i = 0 ; i < nums.length -1;i++ ){
for(int j = i +1; j < nums.length;j++){
if(nums[i] > nums[j]){
temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}
return nums[nums.length /2];
}
随机法
/**
* 3.随机法
* 众数 是超过1/2 的数字,随机拿一个数字很可能就是众数
*
* 1. 随机获取一个数字
* 2. 判断是不是众数
* 3. 如果是返回,如果不是继续随机获取一个数字
*
* @param nums
* @return
*/
public int majorityElement3(int[] nums) {
Random random = new Random();
int i = 0;
while(true){
i = Math.abs(random.nextInt()) % nums.length;
if(isMode(nums,nums[i])){
break;
}
}
return nums[i];
}
public boolean isMode(int[] nums,int candidate) {
int count = 0 ;
for(int i = 0 ; i < nums.length;i++ ){
if(candidate == nums[i]){
count ++;
}
}
return count > nums.length / 2;
}
Boyer-Moore 投票算法
/**
* 4. Boyer-Moore 投票算法
* 思路:如果众数是1,非众数是-1,那么求和一定 >0
* 问题:那么谁是众数呢,默认第一个。假如遍历了5个元素,sum<0,那么说明 所选这个可能不是众数,由于可能是aabbb场景,其实第五个就需要变更预选的众数了。
即sum=0的时候,重新选第一个作为众数。
*
* @param nums
* @return
*/
public int majorityElement(int[] nums) {
int sum = 0;
int candidate = 0;
for(int i = 0 ; i < nums.length;i++ ){
if(sum == 0){
candidate = nums[i];
}
if(candidate == nums[i]){
sum ++;
}else{
sum --;
}
}
return candidate;
}
学习
1. 随机算法给我新的思路,其他应用还在摸索中
2. 投票算法,会在分布式中应用多一点