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

如何找到降序一维数组中累加和≥目标值的索引?

查找降序数组中累加和≥目标值的最小索引

假设有一个按降序排列的一维数组,示例如下:
arr = np.array([10, 10, 8, 5, 4, 4, 3, 2, 2, 2])

需求是找到最小的索引,使得从数组起始位置到该索引的累加和大于或等于指定目标值。例如目标值为40时:

index=0(范围0)=> sum=10(10)
index=1(范围0,1)=> sum=20(10+10)
index=2(范围0,1,2)=> sum=28(10+10+8)
index=3(范围0,1,2,3)=> sum=33(10+10+8+5)
index=4(范围0,1,2,3,4)=> sum=37(10+10+8+5+4)
index=5(范围0,1,2,3,4,5)=> sum=41(10+10+8+5+4+4)

最终应返回索引5,因为此时累加和首次≥目标值40。以下是适配大数和大型数组的高效Python实现方案:


高效实现思路

数组是降序排列,但前缀累加和必然是非递减的(假设数组元素均为非负数),因此可以结合前缀和计算+二分查找的组合,将时间复杂度从逐一遍历的O(n)优化为O(n)(计算前缀和)+ O(logn)(二分查找),大幅提升大型数组的处理效率。

方案1:基于Numpy实现(适合超大型数值数组)

Numpy的向量化操作计算前缀和效率极高,配合searchsorted方法实现二分查找:

import numpy as np

def find_min_index(arr, target):
    # 计算前缀和数组,prefix_sum[i]对应arr[0..i]的累加和
    prefix_sum = np.cumsum(arr)
    # 查找第一个≥target的元素索引
    index = np.searchsorted(prefix_sum, target, side='left')
    # 处理所有元素累加和仍小于目标值的边界情况
    return index if prefix_sum[-1] >= target else -1

# 测试示例
arr = np.array([10, 10, 8, 5, 4, 4, 3, 2, 2, 2])
target = 40
print(find_min_index(arr, target))  # 输出5

方案2:纯Python实现(无需第三方库)

借助bisect模块,配合手动计算前缀和,适合非Numpy场景:

import bisect

def find_min_index(arr, target):
    prefix_sum = []
    current_sum = 0
    for num in arr:
        current_sum += num
        prefix_sum.append(current_sum)
        # 提前终止:当前和已达标时无需继续计算后续前缀和
        if current_sum >= target:
            break
    # 二分查找第一个≥target的位置
    index = bisect.bisect_left(prefix_sum, target)
    # 处理边界情况
    return index if (prefix_sum and prefix_sum[-1] >= target) else -1

# 测试示例
arr = [10, 10, 8, 5, 4, 4, 3, 2, 2, 2]
target = 40
print(find_min_index(arr, target))  # 输出5

效率说明

  • 两种方法的时间复杂度均为O(n)+O(logn),对于百万级以上的大型数组,比逐一遍历的O(n)方法效率更高;纯Python版本在目标值对应的位置靠前时,还能通过提前终止进一步节省计算资源。
  • Numpy版本利用底层C实现的向量化操作,计算前缀和的速度远快于纯Python循环,是超大型数值数组的最优选择。

内容的提问来源于stack exchange,提问作者Mert Can Basut

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 20:20:34