OJ -- 169. Majority Element

Problem description: Find the number with the most occurrences in an array, (the maximum number of occurrences is defined in this question as: the number of occurrences is more than N / 2 times)

1. Analysis:
After reading the question, there will be several solutions to the problem:
(1) Directly use the index of the array to solve this problem:

input : nums(arr of int)
let arr be a new arr:
    for num in nums:
        arr[num]++
    return max_element_in_arr

This method is easy to think of, but it is impractical, because the numbers in the array cannot all be positive numbers, and I don't know what the maximum value is. If the maximum value is INT_MAX, it is impossible to open such a large number on the stack or heap. array to use.

(2) Use the red-black tree data structure:

input : nums(arr of int)
let map be a new map:
    for num in nums:
        map[nums]++;
    return key_has_max_value_in_map

Using a key-value data structure can help us solve this problem very well, and can get a decent time complexity (O(N)), but uses extra space, and the space complexity is O(N).
For this topic, we can use the following method to reduce the space complexity to O(1):
We first randomly select an element in an array: count the number of occurrences of this element, if the number of occurrences is greater than N / 2, then this element is Answer. :

input : nums(arr of int)
count = 0;
while 1:
    count = 0;
    let current be a random element in arr:
        for num in arr:
            if num == current:
                count++
        if count > N / 2
            return current

This way we can reduce the space complexity to O(1), and the average time complexity is also O(N).
Specific C++ code:

int majorityElement(vector<int>& nums) {
        int size = nums.size();
        int count = 0;
        while (1) {
            count = 0;
            int index = rand() % size;
            int target = nums[index];
            for (int i = 0; i < size; ++i) {
                if (target == nums[i]) {
                    count++;
                }
            }
            if (count > size / 2) {
                return target;
            }
        }
    }

(3) The value of the number of pivots minus the number of non-pivots must be greater than 0:

int majorityElement(vector<int>& nums) {
        int major = nums[0];
        int count = 1;
        int size = nums.size();
        for (int i = 1; i < size; ++i) {
            major == nums[i] ? count++ : count--;
            if (count == 0) {
                major = nums[i];
                count = 1;
            }
        }
        return major;
    }

2. Several questions:
(1) Why randomness is needed:
because the number of pivots is greater than N/2, in the worst case: none of the previous N/2 elements are pivots, then the time complexity will rise to O (N^2).
(2) Why not use the Map data structure directly:
Map can be used, and it is very stable (time complexity of O(N) can be obtained for any input). Finally, this method is a bit face-to-face, and time will fluctuate. The last method just optimizes in space and uses randomness to "randomly guarantee" the time complexity.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325898549&siteId=291194637