You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用二分查找获取特定结构数组的最大值(C语言)

实现O(log n)时间复杂度的C语言函数

嘿,这个需求很明确,咱们可以用二分查找来搞定O(log n)的时间复杂度,毕竟数组的结构是前半段非递减的非零元素,后半段全是0,天生就适合二分法来定位边界。

核心思路

我们的目标是找到数组中第一个出现的0的位置:

  • 如果第一个0的位置是0,说明整个数组都是0,直接返回0;
  • 如果第一个0的位置是n(超出数组范围),说明数组里没有0,返回最后一个元素;
  • 其他情况,第一个0的前一个位置就是最后一个非零元素,返回它的值就行。

为什么用这个思路?因为二分查找找边界的时间复杂度正好是O(log n),完美符合要求。

代码实现

#include <stdio.h>

int findMax(int a[], int n) {
    if (n == 0) {
        return 0; // 处理空数组的情况
    }
    
    int left = 0;
    int right = n; // right初始化为n,覆盖数组无0的情况
    
    while (left < right) {
        int mid = left + (right - left) / 2; // 避免left+right溢出
        if (a[mid] == 0) {
            right = mid; // 第一个0在mid左边,缩小右边界
        } else {
            left = mid + 1; // 第一个0在mid右边,缩小左边界
        }
    }
    
    if (left == 0) {
        return 0; // 全0数组
    } else {
        return a[left - 1];
    }
}

// 测试用例
int main() {
    int arr1[] = {1,5,5,7,8,0,0,0};
    printf("Test 1: %d\n", findMax(arr1, 8)); // 输出8
    
    int arr2[] = {2,4,5,6,6,8,9,9};
    printf("Test 2: %d\n", findMax(arr2, 8)); // 输出9
    
    int arr3[] = {0,0,0};
    printf("Test 3: %d\n", findMax(arr3, 3)); // 输出0
    
    int arr4[] = {5};
    printf("Test 4: %d\n", findMax(arr4, 1)); // 输出5
    
    int arr5[] = {0};
    printf("Test 5: %d\n", findMax(arr5, 1)); // 输出0
    
    return 0;
}

关键细节解释

  • 边界处理:right初始化为n而不是n-1,是为了处理数组中没有0的情况(比如第二个测试用例),此时循环结束后left会等于n,我们直接取a[left-1]也就是最后一个元素。
  • 避免溢出:计算mid时用left + (right - left)/2而不是(left+right)/2,防止当left和right都是很大的整数时相加溢出。
  • 全0数组判断:当left最终等于0时,说明从第一个元素开始就是0,直接返回0即可。

这样写出来的函数完全符合O(log n)的时间复杂度要求,而且覆盖了所有可能的边界情况。

内容的提问来源于stack exchange,提问作者Ofek Pintok

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:52:49