每日一题:求众数

每日一题:求众数(摩尔投票算法)

求众数1

给定一个大小为n的数组,找出其中的众数。
众数是指在数组中出现次数大于(n/2)取下界的元素。

示例1:
输入:[3,2,3]
输出:3

示例2:
输入:[2,2,1,1,1,2,2]
输出:2

#include

/*
	摩尔投票算法思想:
	1、选取序列中第一个元素为当前序列出现次数较多的元素
	2、选取一个变量来“计分”,初始为1,
	3、依次遍历第一个元素后面的元素,遍历的当前元素与前一个元素不同时,得分减一,相同时,得分加一
	4、当得分小于0时,改变当前序列中出现次数较多的元素

	时间复杂度O(n)
	
	缺点:只适用于序列元素中出现次数大于(n/2)取下界的元素

*/
int majorityElement(int* nums, int numsSize) {
	//定义一个变量res用于存储当前出现次数最多的数
	//定义一个变量cnt来计算得分。
	int res = 0, cnt = 0;
	for (int i = 0; i < numsSize; i++) {
		if (cnt == 0) {
			res = nums[i];
			++cnt;
		}
		else
			(nums[i] == res) ? ++cnt : --cnt;
	}
	return res;
}


int main()
{
	int nums[6] = { 2,2,1,1,2,2 };
	int numslength = sizeof(nums) / sizeof(nums[0]);
	printf("众数为:%d\n", majorityElement(nums, numslength));

	return 0;

}

求众数2

给定一个大小为n的数组,找出其中所有出现次数超过(n/3)取下界的元素。

示例1:
输入:[3,2,3]
输出:3

示例2:
输入:[1,1,1,3,3,2,2,2]
输出:[1,2]

#include
#include 

/*
	找出数组中元素出现次数大于(n/3)取下界的所有元素,
	由数学关系式易得,一个数组中最多有两个这样的元素。
	仍然采用摩尔投票算法

*/

//nums:待查找的数组;numsSize:数组大小;*returnSize:满足条件的元素个数
int* majorityElement(int* nums, int numsSize, int* returnSize) {
	int cm = 0, cn = 0, m=0, n=0;	//变量cm、cn用来记录计算得分,变量m、n用来存储数组中出现次数较多的两个元素
	int* res = (int*)malloc(sizeof(int) * 3);
	*returnSize = 0;

	//找出出现次数较多的数
	for (int i = 0; i < numsSize; i++) {
		if (m == nums[i])
			cm++;
		else if (n == nums[i])
			cn++;
		else if (cm == 0)
			m = nums[i], cm++;
		else if (cn == 0)
			n = nums[i], cn++;
		else
			cm--, cn--;
	
	}
	
	cm = 0;
	cn = 0;
	
	//清空计分变量,统计出现次数,看是否满足出现次数大于(n/3)取下界的条件
	for (int i = 0; i < numsSize; i++) {
		if (m == nums[i])
			cm++;
		else if (n == nums[i])
			cn++;
	}
	
	if (cm > (numsSize / 3))
		res[(*returnSize)++] = m;
	if (cn > (numsSize / 3))
		res[(*returnSize)++] = n;
	
	return res;

}


int main()
{
	int returnSize;
	int nums[10] = { 2,2,1,3,3,3,3,1,2,2 };
	int numslength = sizeof(nums) / sizeof(nums[0]);
	int* res = majorityElement(nums, numslength, &returnSize);
	printf("数组中众数的个数为:%d\n", returnSize);
	printf("众数为: ");
	for (int i = 0; i < returnSize; i++) {
		printf("%d ", res[i]);
	}
	printf("\n");
	return 0;
}

注:只是单纯的用来记录题目和解法,以便自己能方便的复习巩固,若不慎存在侵权行为,请私信联系删除,邮箱:[email protected]

你可能感兴趣的:(刷题,C++,众数,数据结构,算法,c语言)