剑指Offer - 九度1370 - 数组中出现次数超过一半的数字
2013-11-23 04:06
274 查看
剑指Offer - 九度1370 - 数组中出现次数超过一半的数字 2013-11-23 03:55
题目描述:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
输入:
每个测试案例包括2行:
第一行输入一个整数n(1<=n<=100000),表示数组中元素的个数。
第二行输入n个整数,表示数组中的每个元素,这n个整数的范围是[1,1000000000]。
输出:
对应每个测试案例,输出出现的次数超过数组长度的一半的数,如果没有输出-1。
样例输入:
9 1 2 3 2 2 2 5 4 2
样例输出:
2
题意分析: 一个数组中可能有一个数字出现次数超过一半,如果确实有的话,参考《编程之美》上的经典做法。为每个值设置一个“可信度”,当同一个数字连续重复出现时,可信度加1;遇到不同的数时,可信度减1;可信度减到0了就丢弃这个数,换成当前比较的元素。最后剩下的元素就是出现次数超过一半的那个。扫描时间复杂度O(n),空间复杂度O(1)。 如果没有一个元素出现超过一半,则上面的结果变得不可预测,跟数据顺序、各数据个数有关,因此必须统计每个元素出现的次数,我用了map。时间复杂度O(n * log(n)),空间复杂度O(n)。最终得到的结果元素如果出现次数大于则是有效结果,输出之。否则表示没有元素超过一半,输出-1。
// 652983 zhuli19901106 1370 Accepted 点击此处查看所有case的执行结果 3272KB 619B 80MS // 201311180033 #include <cstdio> #include <map> using namespace std; int main() { int tmp, ans; int c; int i, n; map<int, int> mm; // must count the number of appearances of every element while(scanf("%d", &n) == 1){ mm.clear(); scanf("%d", &ans); mm[ans] = 1; c = 1; for(i = 1; i < n; ++i){ scanf("%d", &tmp); ++mm[tmp]; if(tmp == ans){ ++c; }else{ if(c > 0){ --c; }else{ ans = tmp; c = 1; } } } if(mm[ans] > n / 2){ printf("%d\n", ans); }else{ printf("-1\n"); } } return 0; }
相关文章推荐
- 【剑指Offer面试题】 九度OJ1370:数组中出现次数超过一半的数字
- 剑指OFFER之数组中出现次数超过一半的数字(九度OJ1370)
- 【剑指Offer面试编程题】题目1370:数组中出现次数超过一半的数字--九度OJ
- 【剑指Offer面试编程题】题目1370:数组中出现次数超过一半的数字--九度OJ
- 剑指Offer 29 数组中出现次数超过一半的数字
- 【剑指offer】面试题39 数组中出现次数超过一半的数字
- 剑指offer之面试题29:数组中出现次数超过一半的数字
- 剑指offer-题29:数组中出现次数超过一半的数字
- 剑指offer 29. 数组中出现次数超过一半的数字
- 剑指Offer之面试题29:数组中出现次数超过一半的数字
- 剑指Offer29数组中出现次数超过一半的数字
- 剑指offer 数组中出现次数超过一半的数字
- 剑指offer之二十二---数组中出现次数超过一半的数字
- 九度OJ-题目1370:数组中出现次数超过一半的数字
- 剑指Offer_28_数组中出现次数超过一半的数字
- 剑指offer-28.数组中出现次数超过一半的数字
- 剑指offer — 数组中出现次数超过一半的数字
- 剑指offer-数组中出现次数超过一半的数字
- [剑指offer][面试题29]数组中出现次数超过一半的数字
- 剑指offer——数组中出现次数超过一半的数字_(待写最优法分治)