消除法解决寻找数组主元素问题

130 阅读1分钟

[本文主要参考]

寻找数组主元素(Majority Element)) - 代码先锋网 (codeleading.com)

【算法】寻找数组主元素_数组的主元素查询-CSDN博客 对一个小点做了优化,但代码是错的

本文作为笔记只对参考内容进行补充,请结合参考内容食用!

寻找数组主元素问题算是一个比较经典的题目,最普遍的复杂度为O(n)的解法是“消除法”(有的不用这个名字,甚至都不给这个解法起名字)。但是能清晰解释这个解法的思想原理的少之又少,第一篇参考文章算一个,给人茅塞顿开的感觉。对于一些小问题,参考另一篇可以解答。

问题

假设给出一个长度为n的数组,数组中的元素为整型类型的数字,其中一个数字出现的概率 > n/2,即出现超过一半,如何找出这个数字呢?

思路

这里我们将使用“消除法”来解这个问题。假设我们有数组[0, 5, 5, 3, 5, 1, 5, 7],我们从数组中逐一找出不同的一对数字进行消除:

这样的话,由于主元素的个数 > n/2,因此在逐对消除的过后,主元素必将留存下来。但是可能没有主元素,那就要判断一下。

#include <stdio.h>

int mainElem(int[], int); 
int main(){
	
	int A[] = {0, 5, 5, 3, 5, 1, 5, 7};
	printf("%d\n", mainElem(A, 8));
	
	return 0;
} 
int mainElem(int A[], int n){
	int i, c, count=1;
	c=A[0];
	for(i=1; i<n; i++){
		if(A[i] == c){
			count++;
		}else{
			if(count>0){
				count--;
			}else{
				c=A[i];
				count=1;
			}
		}
	}
	if(count>0){
		for(i=count=0; i<n; i++){
			if(A[i]==c){
				count++;
			}
		}
	}
	if(count>n/2) return c;
	else return -1;
}