算法第二章上机实践报告

算法第二章《递归与分治策略》上机实践报告

一.实践题目名称

maximum number in a unimodal array 单峰数组中的最大数

 

二.问题描述

给定一个具有 n 个不同元素的单峰数组,这意味着它其中的元素先按递增顺序排列直到它的最大元素,然后它的元素按降序排列。请设计一个时间复杂度为 O(log n) 的算法来寻找数组中的最大元素。

输入格式: 第一行输入一个整数n(1<= n <= 10000)。第二行输入用空格隔开的N个整数,是一个单峰数组。

输出格式: 一个整数,它是数组中的最大整数

输入样例:

7

1 2 3 9 8 6 5

输出样例:

9

 

三.算法描述

本题采用二分搜索方法检索已知数组,若mid指向的数比右边数字大,则它可能为山峰数也可能处于右半坡,进而将mid值赋给right继续向左查找;若mid指向的数比右边数字小,则它处于左半坡,进而将mid+1值赋给left继续向右查找;查找直至left等于right时即为山峰值。

#include <iostream>

using namespace std;

int FindMax(int a[],int left,int right)

{

    if (left > right)

        return -1;

    if (left == right)

        return a[right];

    int mid = (left + right) / 2;

    if (a[mid] > a[mid + 1])  //mid处山峰或右半坡

        return FindMax(a, left, mid);

    else  //mid处于左半坡

        return FindMax(a, mid + 1, right);

}

 

int main() {

    int n, num[10000] = { 0 };

    cin >> n;

    for (int i = 0; i < n; i++)

        cin >> num[i];

    cout << FindMax(num, 0, n - 1);

    return 0;

}

 

四.算法时间及空间复杂度分析(要有分析过程)

  1. 时间复杂度:本题采用二分法,时间复杂度为O (log n)
  2. 空间复杂度:函数递归调用m随次数产生不同的值,空间复杂度也为O (log n)

 

五.心得体会(对本次实践收获及疑惑进行总结)

  1. 刚开始分析题目后想到要使用二分法递归搜索,将mid指向的数字与前后两个数字对比判断它处于数组山坡的什么位置,但是在pta上提交时部分正确。接着与同学讨论后将函数返回值从直接返回峰值数改成峰值下标倒是可以全部通过,百思不得其解下请教了老师,老师解答算法本身已经有问题,即使是通过也是侥幸。因为将mid值与前一个数字比较时若mid是数组第一个元素,[mid-1]会造成数组越界。故算法应修改为mid只与右边的数字比较,规避了不可预期的风险。
  2. 开始没有想到会有末位元素即峰值和首位元素即峰值的情况,以为给定的数据都是按照小大小排列的,虽然本题不需要单独判断特殊情况,但感觉自己思考着实是狭隘了。

 

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

  1. 分治法的基本思想是:将一个难以直接解决的大问题分割成规模较小的相同子问题,这些子问题互相独立且与原问题相同,利用递归各个击破,然后将各问题合并得到原问题的解。
  2. mid还未查找到所需值时,边界指向是改变成mid还是mid±1呢,需要我仔细分析,对我来说凭空想象不如动笔画画,降低错误率。
posted @ 2021-10-02 23:13  布小林  阅读(69)  评论(0编辑  收藏  举报