【剑指Offer】39. 数组中出现次数超过一半的数字

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;
    }    
}

你可能感兴趣的:(#,刷题)