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.