📜  门|门CS 2008 |第 79 题(1)

📅  最后修改于: 2023-12-03 15:12:47.135000             🧑  作者: Mango

题目介绍:门|门CS 2008 |第 79 题

这是一道来自门门CS 2008年题库中的第79题,考察的是程序员对数组、循环、分支语句等基本知识点的掌握情况,是一道入门级别的算法题。

题目描述

请编写一个程序,找出一个整型数组中的最大值和最小值。要求程序既能够在正序数组中运行,也能适应逆序数组的情况,且具有时间复杂度 O(n)。

int main() {
    int a[] = {1, 3, 5, 7, 9};
    int b[] = {9, 7, 5, 3, 1};
    int c[] = {2, 3, 1, 5, 4, 9, 8, 7, 6};

    int max_a = -1, min_a = -1;
    int max_b = -1, min_b = -1;
    int max_c = -1, min_c = -1;

    // 在正序数组中查找最大值和最小值
    for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
        if (max_a == -1 || a[i] > max_a) {
            max_a = a[i];
        }
        if (min_a == -1 || a[i] < min_a) {
            min_a = a[i];
        }
    }

    // 在逆序数组中查找最大值和最小值
    for (int i = sizeof(b) / sizeof(b[0]) - 1; i >= 0; i--) {
        if (max_b == -1 || b[i] > max_b) {
            max_b = b[i];
        }
        if (min_b == -1 || b[i] < min_b) {
            min_b = b[i];
        }
    }

    // 在非有序数组中查找最大值和最小值
    max_c = min_c = c[0];
    for (int i = 1; i < sizeof(c) / sizeof(c[0]); i++) {
        if (c[i] > max_c) {
            max_c = c[i];
        }
        if (c[i] < min_c) {
            min_c = c[i];
        }
    }

    // 输出结果
    cout << "正序数组最大值:" << max_a << ", 最小值:" << min_a << endl;
    cout << "逆序数组最大值:" << max_b << ", 最小值:" << min_b << endl;
    cout << "非有序数组最大值:" << max_c << ", 最小值:" << min_c << endl;

    return 0;
}
解题思路

首先,我们需要在正序数组和逆序数组中找到最大值和最小值。这可以通过循环遍历数组实现,对于正序数组,我们可以从头到尾进行扫描,对于逆序数组,我们可以从尾到头进行扫描,其中需要记录当前遍历过的最大值和最小值,如果新找到的数比当前最大值大或比当前最小值小,则更新记录。

对于非有序数组,考虑通过拆分问题为子问题进行求解。即,将数组拆分为多个子数组,每个子数组中的最大值和最小值均能用前文的方法求解,再将每个子数组的获取到的最大值和最小值分别与已获取的全局最大值和最小值进行比较,更新记录即可。

因此,我们通过循环遍历以及分治的思想,就可以在时间复杂度为 O(n) 的情况下,完成对数组中最大值和最小值的查找。

程序说明

以上述方法实现的代码已在主函数中给出,程序通过先定义三个不同的数组,然后分别在这三个数组中查找最大值和最小值,最后输出结果的方式来验证程序的正确性。

实现细节方面,需要注意的是对于空数组的情况以及未对数组元素进行初始化的情况,需要进行相应的处理。此外,在循环遍历时数组大小的计算可通过 sizeof(a) / sizeof(a[0]) 的方式获得,后者可以确保计算结果为数组元素的个数。

更多代码细节及注释详见代码实现部分。