1.实践题目名称

7-1 maximum number in a unimodal array

 

2.问题描述

You are a given a unimodal array of n distinct elements, meaning that its entries are in increasing order up until its maximum element, after which its elements are in decreasing order.
Give an algorithm to compute the maximum element that runs in O(log n) time.
给定了一个由n个不同元素组成的单峰数组,按递增顺序排列,直到它的最大元素为止,之后它的元素按递减顺序排列。
在 O(logn)时间内运行给出一个算法来计算的最大元素。

3.算法描述
复制代码
#include <iostream>
using namespace std;

int SearchMax(int a[], int n){
int lef = 0;
int rig = n-1;
while(lef<=rig){
int mid = (lef+rig)/2;
if(a[mid]>a[mid-1] && a[mid]>a[mid+1]){
return a[mid];
}
if(a[mid]>a[mid+1] ){
rig = mid - 1;
}
else{
lef = mid + 1;
}
}
}

int main(){
int n;
cin>>n;
int a[n];
for(int i=0; i<n; i++){
cin>>a[i];
}
cout<<SearchMax(a, n);
return 0;
}

因为数组排序先增大在遇到最大值后减小,因此可使用二分法将数组划分为递增与递减的两部分,而最大值便存在于两个部分的重合处。

可设置两个指针分别从前半部分和后半部分进行对最大值的查找,从而可以减少查找所花的时间,提高查找效率。

当 a[mid]>a[mid-1] && a[mid]>a[mid+1] 时,说明此时a[mid]大于左侧和右侧的两个数,而在该数组中符合条件的只有最大值,最大值既是a[mid];

当 a[mid]>a[mid+1] 时,说明此时a[mid]大于右侧的数,但小于左侧的数,此时a[mid]仍处于递减数列中,则需要指针右移;

同上,当情况相反时则需要指针左移。

 

4.算法时间及空间复杂度分析

时间复杂度:因为使用了二分搜索法,所以对数组的查找时间规模减半,时间复杂度为O(log n)。

空间复杂度:因为没有其他的数组,所以空间复杂度为O(1)。

 

5.心得体会

在这次实验课上和搭档进行了讨论,因为对这道题的思路都一致但是打出来的代码截然不同,所以对两个代码共同讨论了些许时间,了解对方每一行代码所代表的含义。

这样能让我们对题目和代码的了解更加清晰,同时能互相讨论不同的思路想法。

6.分治法的个人体会和思考

1.实践题目名称

7-1 maximum number in a unimodal array

 

2.问题描述

You are a given a unimodal array of n distinct elements, meaning that its entries are in increasing order up until its maximum element, after which its elements are in decreasing order.
Give an algorithm to compute the maximum element that runs in O(log n) time.
给定了一个由n个不同元素组成的单峰数组,按递增顺序排列,直到它的最大元素为止,之后它的元素按递减顺序排列。
在 O(logn)时间内运行给出一个算法来计算的最大元素。

3.算法描述
复制代码
#include<iostream>
using namespace std;
int main(){
int n, a[10000], m;
cin >> n;
int left = 0;
int right = n - 1;
for(int i=0; i<n; i++)
cin >> a[i];
m = (left + right) / 2;
while(left <= right){
m = (left + right) / 2;
if(m == 0 || m == n-1) break;
if(a[m-1] < a[m] && a[m+1] < a[m]){
cout << a[m];
return 0;
}
else if(a[m-1] > a[m])
right = m - 1;
else
left = m + 1;
}
cout << a[m];
}

 

4.算法时间及空间复杂度分析

时间复杂度:因为使用了二分搜索法,所以对数组的查找时间规模减半,时间复杂度为O(log n)。

空间复杂度:因为没有其他的数组,所以空间复杂度为O(1)。

 

5.心得体会

在这次实验课上和搭档进行了讨论,因为对这道题的思路都一致但是打出来的代码截然不同,所以对两个代码共同讨论了些许时间,了解对方每一行代码所代表的含义。

这样能让我们对题目和代码的了解更加清晰,同时能互相讨论不同的思路想法。

 

6.分治法的个人体会和思考

分治法基本思想是:对一个原规模为n的问题,将其分解为多个规模较小的子问题,再将这些子问题的解合并求得原问题的解。
但分治法并不对于所有问题来说都是最佳选择,只有在问题规模较大时适用分治法。