Majority Element


遍历一次,保存一个长度为k - 1数组:

  • 如果数组中包括这个数,则该数count + 1

  • 如果数组中有空位,则放入该数,count置为1

  • 如果数组中有数字count为0,则替换该数,count置为1

  • 所有数字count减一

最后数组中剩下的数,就是candidate,每个统计一下就可以了。

这个方法可以解决任意1 / k的majority number


Majority Element

Brute Force, O(n ^ 2) time, O(1) space

public class Solution {
    public int majorityElement(int[] nums) {
        int max = 0;
        for (int i = 0; i < nums.length; i++) {
            int num = nums[i], count = 0;
            for (int j = 0; j < nums.length; j++) {
                if (num == nums[j]) {
                    count++;
                }
            }
            if (count * 2 > nums.length) {
                return num;
            }
        }
        return -1;
    }
}

Hash Table, O(n) time, O(n) space

public class Solution {
    public int majorityElement(int[] nums) {
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int num: nums) {
            if (!map.containsKey(num)) {
                map.put(num, 1);
            } else {
                map.put(num, map.get(num) + 1);
            }

            if (map.get(num) * 2 > nums.length) {
                return num;
            }
        }
        return -1;
    }
}

Sort, O(nlogn) time, O(1) space

public class Solution {
    public int majorityElement(int[] nums) {
        Arrays.sort(nums);
        return nums[nums.length / 2];
    }
}

Moore's Voting, O(n) time, O(1) space

public class Solution {
    public int majorityElement(int[] nums) {
        int candidate = 0, count = 0;
        for (int num: nums) {
            if (count == 0) {
                count = 1;
                candidate = num;
            } else if (num == candidate) {
                count++;
            } else {
                count--;
            }
        }
        return candidate;
    }
}

Bit, O(n) time, O(1) space

public class Solution {
    public int majorityElement(int[] nums) {
        int answer = 0;
        for (int i = 0; i < 32; i++) {
            int count = 0;
            for (int num: nums) {
                if ((num >> i & 1) == 1) {
                    count++;
                }
            }
            if (count * 2 > nums.length) {
                answer |= 1 << i;
            }
        }
        return answer;
    }
}

Majority Element II

这题的题干里没有确保一定存在major element,所以最后得出candidate以后还要再扫一遍算一下count。

public class Solution {
    public List<Integer> majorityElement(int[] nums) {
        int candidate1 = 0, candidate2 = 0, count1 = 0, count2 = 0;
        for (int num: nums) {
            if (candidate1 == num) {
                count1++;
            } else if (candidate2 == num) {
                count2++;
            } else if (count1 == 0) {
                count1 = 1;
                candidate1 = num;
            } else if (count2 == 0) {
                count2 = 1;
                candidate2 = num;
            } else {
                count1--;
                count2--;
            }
        }

        count1 = 0;
        count2 = 0;
        for (int num: nums) {
            if (num == candidate1) {
                count1++;
            } else if (num == candidate2) {
                count2++;
            }
        }

        List<Integer> result = new ArrayList<Integer>();
        if (count1 * 3 > nums.length) {
            result.add(candidate1);
        }
        if (count2 * 3 > nums.length) {
            result.add(candidate2);
        }

        return result;
    }
}

Majority Element III

如果要求element的chuxian次数是大于1/k的话,那最多会有k - 1个结果

public class Solution {
    /**
     * @param nums: A list of integers
     * @param k: As described
     * @return: The majority number
     */
    public int majorityNumber(ArrayList<Integer> nums, int k) {
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int num: nums) {
            if (map.containsKey(num)) {
                map.put(num, map.get(num) + 1);
            } else if (map.size() < k - 1) {
                map.put(num, 1);
            } else {
                boolean found = false;
                for (int key: map.keySet()) {
                    if (map.get(key) == 1) {
                        found = true;
                        map.remove(key);
                        map.put(num, 1);
                        break;
                    }
                }

                if (!found) {
                    for (int key: map.keySet()) {
                        map.put(key, map.get(key) - 1);
                    }
                }
            }
        }

        for (int key: map.keySet()) {
            map.put(key, 0);
        }
        for (int num: nums) {
            if (map.containsKey(num)) {
                map.put(num, map.get(num) + 1);
            }
        }
        for (int key: map.keySet()) {
            if (map.get(key) * k > nums.size()) {
                return key;
            }
        }
        return -1;
    }
}

(Google) Majority Element

注意这题跟之前三题的不同点是input array是排好序的。

http://www.1point3acres.com/bbs/forum.php?mod=viewthread&tid=191900

之前google面经里有的关于majority element的题,就是一个排序数组有n个值,求所有出现次数等于或者超过n / k的值。 比如[1 1 2 2 2 2 3 4 5 5 5 5] k = 3 return [2,5]

解决办法就是一次检查所有可能的出现majority element的位置[n / k, 2n / k, ..., n], 在每个位置上根据当前元素做search for range, O(logn), 如此重复最多k次即可。时间复杂度是O(klogn), O(1)的空间。

public class MajorityElementInSortedArray {
    public static List<Integer> majorityElement(int[] array, int k) {
        List<Integer> result = new ArrayList<Integer>();

        List<Integer> index = new ArrayList<Integer>();
        int n = array.length;
        for (int i = 1; i <= k; i++) {
            index.add(i * n / k - 1);
        }

        for (int i: index) {
            int element = array[i];
            int count = searchRange(array, element);
            if (count * k >= n) {
                result.add(element);
            }
        }

        return result;
    }

    private static int searchRange(int[] array, int target) {
        int start = 0, end = array.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (array[mid] >= target) {
                end = mid;
            } else {
                start = mid;
            }
        }
        int left = -1;
        if (array[start] == target) {
            left = start;
        } else {
            left = end;
        }

        start = 0;
        end = array.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (array[mid] <= target) {
                start = mid;
            } else {
                end = mid;
            }
        }
        int right = -1;
        if (array[end] == target) {
            right = end;
        } else {
            right = start;
        }

        return right - left + 1;
    }

    public static void main(String[] args) {
        int[] array = {1, 1, 2, 2, 2, 2, 3, 4, 5, 5, 5, 5};
        int k = 3;
        List<Integer> result = majorityElement(array, k);
        System.out.println(result);

        int[] array2 = {1, 2, 2, 3, 4, 4};
        int k2 = 3;
        List<Integer> result2 = majorityElement(array2, k2);
        System.out.println(result2);
    }
}

results matching ""

    No results matching ""