寻找超过一半的数字(编程之美)
2016-03-21 16:29
381 查看
寻找超过一半的数字
问题一:
给定一个数组,该数组中存在一个数字的出现次数超过整个数组的一半,比如{1, 2, 2, 3, 2}中的2,要求这个数字。解法一:
基本思路就是排序,然后arr[n / 2]即为所求,复杂度O(nlgn)。#define FOR(i, x, y) for(int i = x; i <= y; i ++) int main() { #ifndef ONLINE_JUDGE freopen("data.txt", "r", stdin); #endif // ONLINE_JUDGE int n; cin >> n; FOR(i, 0, n - 1) scanf("%d", &arr[i]); sort(arr, arr + n); printf("%d\n", arr[n / 2]); }
解法二:
充分利用超过一半这个条件,将不同的数字“配对”删除,最后剩余的数字一定为所求,复杂度O(n)。void solve(int n) { int cnt = 0, t = -1; FOR(i, 0, n){ if(!cnt) t = arr[i], cnt++; else { if(t == arr[i]) cnt++; else cnt--; } } printf("%d\n", t); }
扩展问题:
题目改成:给定一个数组,该数组中存在3个数字的出现次数超过整个数组的1/4,比如{1, 2, 2, 3, 3, 4, 4}中的2, 3, 4,要求这3个数字。其实思想主要也是一样的,只不过两两配对改成了4个一次配对惹,代码如下:
void solve(int n) /** n >= 3 **/ { int time[3][2]; mset(time, 0); FOR(i, 0, n - 1){ int flag = 1; FOR(j, 0, 3){ if(time[j][1] == 0){ time[j][0] = arr[i], time[j][1]++, flag = 0; break; }else if(time[j][0] == arr[i]){ time[j][1]++, flag = 0; break; } } if(flag) FOR(j, 0, 2) time[j][1]--; } FOR(j, 0, 2) printf("%d ", time[j][0]); }
相关文章推荐
- java 实现md5
- 第一次JAVA基础考试后的反思
- Java 读取xlsx
- Java对象表示方式1:序列化、反序列化和transient关键字的作用
- [LeetCode]题解(python):121-Best Time to Buy and Sell Stock
- .NET/ASP.NET 4.5 Bundle组件(捆绑、缩小静态文件)
- 网易在线编程题 奖学金问题
- Nutch搜索引擎(第4期)_ Eclipse开发配置
- Spring Security3 - MVC 整合教程 (初识Spring Security3)
- Java SE 第十二、十三讲 Java基础知识回顾
- SpringMVC学习记录3
- Python 入门
- PHP的array_merge、array_diff与null
- Java类集框架
- PHP针对二维数组无限遍历变形研究
- 如何对DataTable进行动态分组和动态统计[C#]
- QT中QMainWindow、QWidget、QDialog的区别
- 《CLR Via C#》使用CSC.exe将module组合成assembly
- XCode代码上跳,左移、右移快捷键
- php中遍历二维数组并以表格的形式输出