[剑指Offer] 三种方法求解找出数组中出现次数超过一半的数字

  • 题目描述:给一个长度为 n 的数组,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
    例如,输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。

1)利用map

  • 依次把数组中的元素插入到map中,元素的值为key,元素的个数为value,然后使其value与数组的一半大小做对比,若大于,则该元素就是我们要找的数字。
void test1_1(){
	vector<int> v1 = {1, 2, 3, 2, 2, 2, 5, 4, 2 };
	int half = v1.size() / 2;
	
	unordered_map<int, int> map;
	for (auto& e : v1){
		map[e]++;
		if (map[e] > half){
			printf("%d\n", e);
			break;
		}
	}
}

2)利用库函数sort

  • 使用库函数sort对数组元素进行排序,出现次数超过一半的数字一定会出现在排序后的中间位置上。
    注意:sort()函数的头文件为< algorithm >
void test1_2(){
	vector<int> v1 = { 1, 2, 3, 2, 2, 2, 5, 4, 2 };
	int half = v1.size() / 2;
	sort(v1.begin(), v1.end());
	printf("%d\n", v1[half]);
}

3) 采取不同的数字进行抵消的思想

  • 采取不同的数字进行抵消的思想,若下一个数与当前数相等,count++,否则count- -,当count为0时,重新设置当前数为我们的结果数字。
void test1_3(){
	vector<int> v1 = { 1, 2, 3, 2, 2, 2, 5, 4, 2 };
	int count = 0;
	int ret = 0;
	for (auto& e : v1){
		if (count == 0){
			ret = e;
			count++;
		}
		else{
			if (ret == e)
				count++;
			else
				count--;
		}
	}
	printf("%d\n", ret);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值