Likou-Analysis of the number of ideas that appear more than half of the number of times in the array

Title description:

The number of occurrences of a number in the array exceeds half of the length of the array. Please find out this number.

You can assume that the array is non-empty, and there will always be a majority of elements in a given array.

Example 1:

Input: [1, 2, 3, 2, 2, 2, 5, 4, 2]
Output: 2

limit:

1 <= array length <= 50000

Problem-solving idea 1 : For this method of finding the mode, of course, the first thing that comes to mind is to use an array to count. Every time a number is read, add 1 to the corresponding position, and finally only need to find that the cumulative number is more than half of the array. The value of is returned, and then I thought of the idea of ​​sorting by buckets, subtracting the minimum value from each value as the number of his records. (In fact, you can find the maximum value directly, then create the length array of the maximum value, and then directly record the number of occurrences at the position corresponding to each value)
Desirable question 1 : This idea is well understood, but there will definitely be waste A lot of array space. Secondly, in a test case, a numerical value reached more than 200 million. Obviously, to create an array in this way, memory space is definitely not allowed, so the first attempt ended in failure.

    public int majorityElement(int[] nums) {
    
    
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        int temp = nums.length/2;
        int res = 0;
        //寻找出最大最小值
        for (int num:nums) {
    
    
            if(num < min)  min = num;
            if(num > max)  max = num;
        }
        //根据值创建记录数组
        int[] arr = new int[max-min+1];
        for (int num:nums) {
    
    
            arr[num-min] += 1;
        }
        //然后遍历记录数组,以找出众数
        for (int num:nums) {
    
    
            if(arr[num - min] > temp){
    
    
                res = num;
                break;
            }
        }
        return res;
    }

Problem-solving idea 2 : The first time I tried, I felt that I was dead because the space occupancy rate was too large, so I thought, or I would sacrifice time complexity to remedy it, so I thought of sorting the array first. Then traverse the array and record the number of occurrences of each value. Once the number of occurrences exceeds half of the array, you can stop searching and return the result. The advantage is that the space complexity will definitely be O(1) , And then the best case of the loop is that the mode appears in the smallest position, and the worst case is that the mode appears in the largest position, and the time complexity of the code is not too high.
Encountered problem 2 : The result was very unexpected. All the test cases were passed, and the space utilization exceeded 100% of the java submitted users, but the time complexity only exceeded 30%.


	import java.util.Arrays;
    public int majorityElement(int[] nums) {
    
    
        int temp = Integer.MAX_VALUE;
        int add = 1;
        int l = nums.length/2;
        Arrays.sort(nums);
        for (int num:nums) {
    
    
            if (num != temp){
    
    
                temp = num;
                add = 1;
            }else {
    
    
                add++;
            }
            if(add > l)
                break;
        }
        return temp;
    }

Problem-solving idea 3 : Finally, I found a super-optimized problem-solving idea in the comment area of ​​browsing the problem-solving. The original author explained his idea like this: Detailed code explanation

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

Code understanding : The author said that he used the Moore voting method, which can ensure that the time and space complexity are O(N) and O(1) respectively; the algorithm idea is:

  • Sum of votes: Since the number of occurrences of the mode exceeds half of the length of the array; if the number of votes for the mode is +1 and the number of votes for the non-mode is −1, the sum of votes for all numbers must be >0.
  • Cancellation of positive and negative votes: Let the mode in the array nums be x and the length of the array be n. If the sum of votes of the first a digits of nums=0, the sum of votes of the (n−a) digits after the array must still be> 0 (that is, the mode of the next (n−a) digits is still x).

Guess you like

Origin blog.csdn.net/baldicoot_/article/details/107333763