主元素问题 Majority Element

2018-09-23 13:25:40

主元素问题是一个非常经典的问题,一般来说,主元素问题指的是数组中元素个数大于一半的数字,显然这个问题可以通过遍历计数解决,时间复杂度为O(n),空间复杂度为O(n)。这样的算法有两个弊端,一是空间复杂度较高,二是没法处理数据流问题。

因此就有了Boyer-Moore Majority Vote algorithm,这个算法可以用来高效的解决主元素问题,并且空间复杂度降到了O(1),时间复杂度保持不变。

算法的思路就是将不同的元素进行抵消,最后剩余的就是最终的结果。

如果说题目中没有明确说明一定存在主元素,那么还需要额外一次遍历来确认当前的解为主元素。

一、主元素问题

问题描述:

问题求解:

    public int majorityElement(int[] nums) {
        int candidate = 0;
        int count = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == candidate) count++;
            else if (count == 0) {
                candidate = nums[i];
                count = 1;
            }
            else count--;
        }
        return candidate;
    }

 

二、Follow Up

问题描述:

问题求解:

    public List<Integer> majorityElement(int[] nums) {
        if (nums == null || nums.length == 0) return new ArrayList<>();
        int candidate1 = 0;
        int candidate2 = 0;
        int count1 = 0;
        int count2 = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == candidate1) count1++;
            else if (nums[i] == candidate2) count2++;
            else if (count1 == 0) {
                candidate1 = nums[i];
                count1 = 1;
            }
            else if (count2 == 0) {
                candidate2 = nums[i];
                count2 = 1;
            }
            else {
                count1--;
                count2--;
            }
        }
        List<Integer> res = new ArrayList<>();
        count1 = 0;
        count2 = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == candidate1) count1++;
            else if (nums[i] == candidate2) count2++;
        }
        if (count1 > nums.length / 3) res.add(candidate1);
        if (count2 > nums.length / 3) res.add(candidate2);
        return res;
    }

 

posted @ 2018-09-23 13:46  hyserendipity  阅读(632)  评论(0编辑  收藏  举报