LintCode:46. 主元素I VS 47. 主元素 II VS 48. 主元素 III

题目:

主元素I:给定一个整型数组,找出主元素,它在数组中的出现次数严格大于数组元素个数的二分之一。

主元素II:给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的三分之一。

主元素III:给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的1/k。


分析:

对于第一题,采用抵消法,一旦发现数组中存在两个不同的数,就都删除,直到剩下的数都一样,此时剩下的元素就是主元素,因为每次抵消操作之后,剩下来的数种,主元素一定也还是超过一半的。具体实现的时候,记录一个candidate和其出现的次数count,遍历每个数,如果count==0,则把candidate置为遍历到的数,否则看遍历到的数和candidate是否相等,如果相等,则count++,否则count--(抵消),遍历结束后,candidate就是主元素。

public class Solution {
    /*
     * @param nums: a list of integers
     * @return: find a  majority number
     */
    public int majorityNumber(List<Integer> nums) {
        // write your code here
        int count=1;
        int temp=nums.get(0);
        for(int i=1;i<nums.size();i++){
            if(count==0){
                temp=nums.get(i);
                count=1;
            }else if(temp==nums.get(i)){
                count++;
            }else{
                count--;
            }
        }
        return temp;
    }
}

对于第二题,依然采用抵消法,如果三个数不同,就三个数都去除,因此记录2个数,及其各自出现的次数即可。

public class Solution {
    /*
     * @param nums: a list of integers
     * @return: The majority number that occurs more than 1/3
     */
    public int majorityNumber(List<Integer> nums) {
        // write your code here
        int  candidate1=0,candidate2=0;
        int count1,count2;
        count1=count2=0;
        for(int i=0;i<nums.size();i++){
            if(candidate1==nums.get(i)){
                count1++;
            }else if(candidate2==nums.get(i)){
                count2++;
            }else if(count1==0){
                candidate1=nums.get(i);
                count1=1;
            }else if(count2==0){
                candidate2=nums.get(i);
                count2=1;
            }else{
                count1--;
                count2--;
            }
        }
        count1=0;count2=0;
        for(int i=0;i<nums.size();i++){
            if(nums.get(i)==candidate1) count1++;
            else if(nums.get(i)==candidate2)    count2++;
        }
        return (count1>count2)?candidate1:candidate2;
    }
}

第三题也可以采用相同的方法,除此之外,还可以通过hashmap实现,需要O(n)的空间复杂度和O(n)的时间复杂度,而之前用的抵消法只需要O(1)的空间复杂度。

首先计算出阈值,然后用hashmap存放值以及出现的次数,一旦等于阈值就返回该数。

public class Solution {
    /**
     * @param nums: A list of integers
     * @param k: An integer
     * @return: The majority number
     */
    public int majorityNumber(List<Integer> nums, int k) {
        // write your code here
        int count=(int)Math.ceil(nums.size()/k);
        HashMap<Integer,Integer> hashMap=new HashMap<>();
        for(int i=0;i<nums.size();i++){
            if(!hashMap.containsKey(nums.get(i))){
                hashMap.put(nums.get(i),1);
            }else{
                int val=hashMap.get(nums.get(i));
                if(val+1>count){
                    return nums.get(i);
                }
                hashMap.put(nums.get(i),++val);
            }
        }
        return 0;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_27139155/article/details/79776591