编程之美:第二章 数字之魅 2.10寻找数组中的最大值和最小值
2015-08-03 01:03
453 查看
/* 寻找数组中的最大值和最小值: 对于一个由N个整数组成的数组,需要比较多少次才能把最大和最小的数找出来呢? 例如给出数组{5,6,8,3,7,9} 分析: 解法1: 可以把寻找数组中的最大值和最小值看成两个独立的问题,分别求解即可。最直接的做法是先扫描一次数组,找出最大的数和最小的数。需要比较2*N次才能求解。 不需要用排序做,设定一个最大值和一个最小值即可 解法2: 最大的数和最小的数一半不是同一个数,(除非N=1,或者所有整数都是一样的大小)。先把数组分成两部分,然后再从这两部分中分别找出最大的数和最小的数。 首先按照顺序将数组中相邻的两个数分在同一组。若数组为{5,6,8,3,7,9},接着比较同一组中奇数位数字和偶数位数字,将较大的数放在偶数位上,较小的数放在奇数 位上。经过N/2次比较,较大的数都放到了偶数位置上,最后从奇偶数位上分别求出Max = 9,Min = 3,各需要比较N/2次。 总共需要比较1.5*N次。 解法3: 解法2破坏了原数组。如果可以在遍历的过程中进行比较,且不对数组中的元素进行交换,就不会破坏原数组。仍然按照顺序将数组中相邻的两个数分在同一组 ,然后可以利用两个变量来Max和Min来存储当前的最大值和最小值。同一组的两个数比较之后,不再调整顺序,而是将其中较大的数与当前Max比较。如果该数 大于当前Max,则更新Max 解法4: 分治思想。在N个数中求最小值Min和最大值Max,我们只需分别求出前后N/2个数的Min和Max,然后取较小的Min,较大的Max即可 输入: 6 5 6 8 3 7 9 输出: 3 9 */ /* 1 if(pArr[i] < pArr[i+1])//前面小于后面,则交换,确保较大的数在偶数位上 { swap(&pArr[i],&pArr[i+1]); } 2 if(pArr[j] < iMin)//接下来在奇数位上寻找最小数, { iMin = pArr[j]; } 3 if(pArr[i] < pArr[i+1])//保持原来数组中的顺序,采用记录初始化的Max和Min的做法 { iMin = min(pArr[i],iMin); iMax = max(pArr[i+1],iMax); } 4 if(high - low <= 1) { if(pArr[low] < pArr[high]) { return make_pair<int,int>(pArr[low],pArr[high]); 5 pair<int,int> pairLeft = findMinMax_recursion(pArr,low,low + (high - low)/2); pair<int,int> pairRight = findMinMax_recursion(pArr,low + (high - low)/2 + 1,high); */ #include <stdio.h> #include <iostream> using namespace std; const int MAXSIZE = 10000; void swap(int* pNum1,int* pNum2) { int iTemp = *pNum1; *pNum1 = *pNum2; *pNum2 = iTemp; } pair<int,int> findMinMax_divide(int* pArr,int iLen)//采用较大数放在偶数位上的方法,共需要比较1.5*N次 { int i,j; for(i = 0 ; i < iLen; i += 2) { if(pArr[i] < pArr[i+1])//前面小于后面,则交换,确保较大的数在偶数位上 { swap(&pArr[i],&pArr[i+1]); } } int iMin = pArr[1],iMax = pArr[0]; for(i = 0,j = i + 1; i < iLen ; i += 2, j += 2) { if(pArr[i] > iMax) { iMax = pArr[i]; } if(pArr[j] < iMin)//接下来在奇数位上寻找最小数, { iMin = pArr[j]; } } return make_pair<int,int>(iMin,iMax); } pair<int,int> findMinMax_recursion(int* pArr,int low,int high) { if(high - low <= 1) { if(pArr[low] < pArr[high]) { return make_pair<int,int>(pArr[low],pArr[high]); } else { return make_pair<int,int>(pArr[high],pArr[low]); } } else { int iMin,iMax; pair<int,int> pairLeft = findMinMax_recursion(pArr,low,low + (high - low)/2); pair<int,int> pairRight = findMinMax_recursion(pArr,low + (high - low)/2 + 1,high); if(pairLeft.first < pairRight.first) { iMin = pairLeft.first; } else { iMin = pairRight.first; } if(pairLeft.second > pairRight.second) { iMax = pairLeft.second; } else { iMax = pairRight.second; } return make_pair<int,int>(iMin,iMax); } } int min(int a,int b) { return a < b ? a : b; } int max(int a,int b) { return a > b ? a : b; } pair<int,int> findMinMax_keppSeq(int* pArr,int iLen) { int i,j,iMin,iMax; iMin = min(pArr[0],pArr[1]); iMax = max(pArr[0],pArr[1]); for(i = 2 ; i < iLen ; i += 2) { if(pArr[i] < pArr[i+1])//保持原来数组中的顺序,采用记录初始化的Max和Min的做法 { iMin = min(pArr[i],iMin); iMax = max(pArr[i+1],iMax); } else { iMin = min(pArr[i+1],iMin); iMax = max(pArr[i],iMax); } } return make_pair<int,int>(iMin,iMax); } void process() { int n; while(EOF != scanf("%d",&n)) { int iArr[MAXSIZE]; for(int i = 0 ; i < n; i++) { scanf("%d",&iArr[i]); } //pair<int,int> pairRes = findMinMax_divide(iArr,n); //pair<int,int> pairRes = findMinMax_keppSeq(iArr,n); pair<int,int> pairRes = findMinMax_recursion(iArr,0,n-1);//shi printf("%d %d\n",pairRes.first,pairRes.second); } } int main(int argc,char* argv[]) { process(); getchar(); return 0; }
相关文章推荐
- 编程之美: 第二章 数字之魅 2.14求数组的子数组之和的最大值
- Struts2开发环境搭建
- 编程之美: 第二章 数字之魅 2.11寻找最近点对
- 编程之美:第三章 结构之法 3.11程序改错
- 编程之美:第二章 数字之魅 2.13子数组的最大乘积
- 编程之美: 第二章 数字之魅 2.16求数组中最长递增子序列
- 编程之美:第二章 数字之魅 2.15子数组之和的最大值(二维)
- 编程之美:第二章 数字之魅 2.19区间重合判断
- 编程之美:第二章 数字之魅 2.17数组循环移位
- 编程之美:第二章 数字之魅 2.20程序理解和时间分析
- 编程之美:第三章 结构之法 3.9重建二叉树
- Java_链表实现
- 编程之美:第三章 结构之法 3.10分层遍历二叉树
- 编程之美: 第三章 结构之法 3.2电话号码对应英语单词
- 编程之美:第三章 结构之法 3.8求二叉树中结点的最大距离
- 编程之美:第三章 结构之法 3.3计算字符串的相似度
- 编程之美:第三章 结构之法 3.4从无头单链表中删除节点
- 编程之美:第三章 结构之法 3.7队列中取最大值操作问题
- Python操作Excel实践总结
- google 笔试题: 丑数