分治法解决寻找数组中最大最小值的问题

输入: 数组A[i,…,j]

输出:数组A[i,…,j]中的max和min

1. If  j-i+1 =1   Then 输出A[i],A[i],算法结束

2. If  j-i+1 =2   Then

3.      If  A[i]< A[j]  Then输出A[i],A[j];算法结束

4. k<--(j-i+1)/2

5. m1,M1<--MaxMin(A[i:k]);

6. m2,M2 <--MaxMin(A[k+1:j]);

7. m <--min(m1,m2);

8. M <--min(M1,M2);

9. 输出m,M

复杂度为3/2n-1

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4
 5 double num[100];
 6 int n = 0;
 7
 8 // 用一个结构体来记录最大最小值
 9 struct Res
10 {
11     double maxs;
12     double mins;
13 };
14
15 struct Res MaxAndMin(int left,int right)
16 {
17     Res res,a,b;
18
19     if(left +1 >= right) //判断是否递归到底部
20     {
21         res.maxs = max(num[left],num[right]);
22         res.mins = min(num[left],num[right]);
23         return res;
24     }
25
26     int middle = (right + left) / 2;
27     a = MaxAndMin(left,middle);
28     b = MaxAndMin(middle+1,right);
29     res.maxs = max(a.maxs,b.maxs);
30     res.mins = min(a.mins,b.mins);
31     return res;
32 }
33 int main()
34 {
35     while(cin>>n)
36     {
37         //输入n个数
38         for(int i = 0; i < n; i++)
39         {
40             cin>>num[i];
41         }
42
43         //只有一个数时,直接输出
44         if(n == 1)
45         {
46             cout<<"最大值:"<<num[0]<<" 最小值:"<<num[0]<<endl;
47             continue;
48         }
49         //只有两个数时,比较这两个数,然后输出
50         if(n == 2)
51         {
52             if(num[0] > num[1])
53             {
54                 cout<<"最大值:"<<num[0]<<" 最小值:"<<num[1]<<endl;
55             }
56             else
57             {
58                 cout<<"最大值:"<<num[1]<<" 最小值:"<<num[0]<<endl;
59             }
60             continue;
61         }
62         //多个数时,分治的思想,将数组二分
63         int left = 0,right = n-1;
64         Res result;
65         result = MaxAndMin(left,right);
66         cout<<"最大值:"<<result.maxs<<" 最小值:"<<result.mins<<endl;
67     }
68
69     return 0;
70 }

 1 void FindMaxAndMinMethod4(int *pArr, int nStart, int nEnd, int &nMax, int &nMin)
 2 {
 3     if (nEnd - nStart <= 1)
 4     {
 5         if (pArr[nStart] > pArr[nEnd])
 6         {
 7             nMax = pArr[nStart];
 8             nMin = pArr[nEnd];
 9         }
10         else
11         {
12             nMax = pArr[nEnd];
13             nMin = pArr[nStart];
14         }
15         return;
16     }
17
18     int nLeftMax = 0;
19     int nLeftMin = 0;
20     int nRightMax = 0;
21     int nRightMin = 0;
22     FindMaxAndMinMethod4(pArr, nStart, nStart+(nEnd-nStart)/2, nLeftMax, nLeftMin);
23     FindMaxAndMinMethod4(pArr, nStart+(nEnd-nStart)/2+1, nEnd, nRightMax, nRightMin);
24
25     nMax = nLeftMax > nRightMax ? nLeftMax : nRightMax;
26     nMin = nLeftMin < nRightMin ? nLeftMin : nRightMin;
27 }  

时间: 2024-10-17 17:41:28

分治法解决寻找数组中最大最小值的问题的相关文章

分治法求一个数组中最大最小值

分治法:将一个复杂的一分为二,然后对这两部分递归调用该函数,直到找到函数出口,求解出最简单的情况 需要注意的是分治时开始和结束位置参数的选择,一开始写的是s到mid-1,另一个是mid到e,然后就会数组为奇数个时结果对,为偶数个时结果错,后面改为s到mid,另一个是mid+1到e 结果就对了. #include<iostream> using namespace std; #define N 10 #define MAX(a,b)(a>b?a:b) #define MIN(a,b)(a&

3.分治法研究-搜索数组中的最长连续递增子集

//分治算法研究 搜索数组中的最长连续递增子集var cc=consolefunction find_max_crossing_lenarray(A,low,mid,high){    var max_left=mid,max_right=mid    var left_sum=1    var sum=0    for(var i=mid;i>low;i--){        sum=A[i]-A[i-1]        if(sum==1){            left_sum++   

算法题|-分治法解决最大子数组问题

分治法就是将一个复杂难解决问题拆成一些容易解决的小问题,再依次解决而最终解决整个问题 new int[] { 2, -3, 4, 67, 6 } 这样一个下标为0到4的数组,要找最大子数组,需要将其拆分成两个子数组,mid=(0+4)/2 即为0~mid的左数组和mid+1~4的右数组 最大子数组可能会出现在以下三个地方 左数组中的某个最大子数组 右数组中的某个最大子数组 以mid为界,向左找到一个最大数组,向右找到一个最大数组,将两个数组合并 第三种情况非常容易得到,通过遍历查找就可以解决,而

编程之美3:寻找数组中的最大值和最小值以及最大值和次大值

很开心,这是今天的第三篇文章啦!下午健身也感觉非常过瘾,托付宿舍妹子从日本代购的护肤品也到了.耳边漂浮着Hebe田馥甄的<魔鬼中的天使>文艺的声线,一切都好棒,O(∩_∩)O哈哈~.爱生活,爱音乐,爱运动,额,当然还有要爱学习啦!加油(^ω^) 额,扯远了.第三篇是关于寻找数组中的最大值和最小值.第一次看到这个题目的时候,楼主稍微鄙视了一下,因为觉得这个题目有什么好做的.但是楼主还是看了看<编程之美>上的写的,发现还是有必要记录一下,不一样的思考方式.很赞!大家和楼主一起哦,Are

2.10 用最少次数寻找数组中的最大值和最小值[find min max of array]

[本文链接] http://www.cnblogs.com/hellogiser/p/find-min-max-of-array.html [题目] 对于一个由N个整数组成的数组,需要比较多少次才能把最大和最小的数找出来呢? [分析] 1. 遍历两次数组,分别找出最大值和最小值,需要进行 2N 次比较. 2. 将数组中的元素分组,按顺序将数组中相邻的两个数分在同一组,用Max和Min来存储最大值和最小值.同一组比较完之后,较小的数与当前的最小值比较,如该数小于当前最小值,更新Min:较大的数与当

分治法解决最大子数组问题

利用分治法解决最大子数组问题(对给定的数组得到该数组中具有最大和的子数组) /* * 对于给定的整数数组A,求出数组中具有最大和的子数组,最大和以及左右下标 * 思路:采用分治的方法,将数组分为两部分,则有最大和的子数组共有三种情况 * 在数组左边,在数组右边,跨越数组中点 */ #include <iostream> using namespace std; //存放左右边界值以及sum值的结构体 /*特别注意结构体的使用!!!!!!!!!!!*/ struct SumBorder { in

编程之美2.10 寻找数组中的最大值和最小值

这个问题其实很容易解决,就是循环遍历一遍数组,然后找到数组中存在的最大值和最小值就可以了,书中主要讨论的问题是比较次数较小的方法,不过,书中已经证明了,无论用什么方法最少的比较次数也就是循环遍历一遍的比较,结果是O(1.5N)的,所以,很容易的可以解决这个问题. 第一种方法: 函数声明: void DutFindMaxAndMinInArray_1(int*, int, int&, int&); 源代码如下: /*基本的解法寻找最大值和最小值*/ bool _DutFindMaxAndMi

lintcode:寻找旋转排序数组中的最小值 II

寻找旋转排序数组中的最小值 II 假设一个旋转排序的数组其起始位置是未知的(比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2). 你需要找到其中最小的元素. 数组中可能存在重复的元素. 解题 暴力直接线性查找 或者,线性找到第一个开始降序的位置对应的数 应该考虑二分法 递归 + 二分 public class Solution { /** * @param num: a rotated sorted array * @return: the minimum number in

寻找旋转排序数组中的最小值

寻找旋转排序数组中的最小值 假设一个旋转排序的数组其起始位置是未知的(比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2). 你需要找到其中最小的元素. 你可以假设数组中不存在重复的元素. 注意事项 You may assume no duplicate exists in the array. 样例 给出[4,5,6,7,0,1,2]  返回 0 标签 二分法 1 class Solution { 2 public: 3 /** 4 * @param nums: a rota