Efficiently find the mode in the array-Moore voting method

Question: Find the number with the number of repetitions exceeding n/2 in an array of length n (assuming it must exist)

The Moore voting method is based on the fact that when the number of repetitions of a number exceeds half of the length of the array, two different numbers are deleted each time, and what is left in the end is the number you are looking for.

The code implementation of the Moore voting method does not really delete the numbers in the array, but treats the traversal process as a deletion process.

Use a virtual array to store the numbers that have not been deleted together with different numbers. This array can only have a number of the same numbers, and there can be no different numbers, because if there are different numbers, they will be deleted and will not be placed here. Array.

When the array traverses to the current element, if the virtual array is empty, add the current element; if the virtual array is not empty, compare whether the current element is the same as the element in the virtual array, and delete one of the virtual arrays if they are different The element is also deleted as the current element, and then the next element is traversed, which is equivalent to deleting a pair of different numbers. If they are the same, the current element is added to the virtual array. Finally, after traversing the array, the elements in the virtual array are the elements you are looking for.

Since there will only be several identical elements in the virtual array, the virtual array can be represented by only two variables, one variable stores the value and the other variable stores the number.

Leetcode interview questions 17.10. Main elements

leetcode 169 most elements

class Solution {
    
    
public:
	int majorityElement(vector<int>& nums) 
	{
    
    
		int temp = nums[0], count =1;//虚拟数组为空,加入当前元素
		int nums_size = nums.size();
		for (int i = 1; i < nums_size; i++)
		{
    
    
			if (nums[i] == temp)
				count++;
				//数组非空,当前元素与虚拟数组元素相同,加入当前元素
			else
			//数组非空,当前元素与虚拟数组元素不同,删除一对不相同的元素
				count--;
			if (count == 0)
			{
    
    //虚拟数组为空,加入当前元素
				temp = nums[i];
				count++;
			}
		}
		count = 0;
		int t = (nums_size) / 2 + 1;
		for (int i = 0; i < nums_size; ++i)
		{
    
    //要验证答案
			if (nums[i] == temp)
				count++;
			if (count == t) return temp;
		}
		return -1;
	}

};

A similar problem: Find the number with the number of repetitions exceeding n/3 in an array of length n (not necessarily there).

It is easy to know that there are at most two numbers whose number of repetitions exceeds 1/3 of the array length. The same idea is to use two virtual arrays and delete three different numbers each time. In the end, the two numbers in the virtual array are the possible answers. At this time, traverse the array again and do a verification.

class Solution {
    
    
public:
	int majorityElement(vector<int>& nums) 
	{
    
    
		int x, y, x_count=0, y_count=0;
		int nums_size = nums.size();
		for (int i = 0; i < nums_size; i++)
		{
    
    
			if (x == nums[i])x_count++;
			else if (y == nums[i])y_count++;
			else if (x_count == 0) x = nums[i], x_count = 1;
			else if (y_count == 0) y = nums[i], y_count = 1;
			else x_count--, y_count--;
		}
		x_count = 0, y_count = 0;
		for (int i = 0; i < nums_size; ++i)
		{
    
    
			if (x == nums[i])
				x_count++;
			else if (y == nums[i])
				y_count++;
		}
		if (x_count > nums_size / 3)
			cout << x << endl;//输出
		if (y_count > nums_size / 3)
			cout << y << endl; //输出
	}

};

Guess you like

Origin blog.csdn.net/weixin_45605341/article/details/108315663