数组3个非相邻元素最大和问题:寻求更优高效解法
优化从数组中选取3个非相邻元素的最大和解法
问题描述
给定一个长度≥5的整数数组,返回其中3个非相邻元素的最大和(非相邻定义为任意两个元素的索引差至少为2)。
测试示例
- 输入
[8, -4, -7, -5, -5, -4, 8, 8],预期结果12(对应索引0、5、7的元素和:8 + (-4) + 8 = 12) - 输入
[-2, -8, 1, 5, -8, 4, 7, 6],预期结果15(对应索引3、5、7的元素和:5 + 4 + 6 = 15) - 输入
[-3, 0, -6, -7, -9, -5, -2, -6],预期结果-9(对应索引1、3、6的元素和:0 + (-7) + (-2) = -9) - 输入
[-10, -10, -10, -10, -10],预期结果-30(对应索引0、2、4的元素和:-10 + (-10) + (-10) = -30)
现有暴力解法分析
你提供的暴力解法通过三重循环枚举所有符合条件的三元组(i,j,k)(满足i+2≤j,j+2≤k),时间复杂度为O(n³),当数组长度n较大时(比如n=1000),计算量会呈立方级增长,完全无法满足效率要求。
def solution(A): max_sum = -float('inf') n = len(A) for i in range(n): for j in range(i + 2, n): for k in range(j + 2, n): temp_sum = A[i] + A[j] + A[k] if temp_sum >= max_sum: max_sum = temp_sum return max_sum
更优的O(n)时间复杂度解法
我们可以通过预处理数组的左右最大前缀,将问题拆解为:对于每个中间元素A[j],找到它左边(索引≤j-2)的最大单个元素,以及右边(索引≥j+2)的最大单个元素,计算这三个值的和,最终取所有可能和的最大值。这种方法的时间复杂度为O(n),空间复杂度可优化至O(1)。
基础实现(O(n)空间)
def solution(A): n = len(A) if n < 5: return -float('inf') # 符合题目长度≥5的约束,做防御性检查 # 构建left_max数组:left_max[j]是A[0..j-2]中的最大值 left_max = [0] * n left_max[2] = A[0] # j=2时,左边只有A[0] for j in range(3, n): left_max[j] = max(left_max[j-1], A[j-2]) # 构建right_max数组:right_max[j]是A[j+2..n-1]中的最大值 right_max = [0] * n right_max[n-3] = A[n-1] # j=n-3时,右边只有A[n-1] for j in range(n-4, -1, -1): right_max[j] = max(right_max[j+1], A[j+2]) max_sum = -float('inf') # 遍历所有可能的中间位置j for j in range(2, n-2): current_sum = left_max[j] + A[j] + right_max[j] if current_sum > max_sum: max_sum = current_sum return max_sum
空间优化版本(O(1)空间)
不需要存储完整的左右最大数组,用变量跟踪左边最大值即可:
def solution(A): n = len(A) if n < 5: return -float('inf') # 预先计算右边的最大值数组 right_max = [0] * n right_max[n-3] = A[n-1] for j in range(n-4, -1, -1): right_max[j] = max(right_max[j+1], A[j+2]) max_sum = -float('inf') left_current_max = A[0] # 初始时,j=2的左边最大值是A[0] # 遍历中间位置j for j in range(2, n-2): current_sum = left_current_max + A[j] + right_max[j] if current_sum > max_sum: max_sum = current_sum # 更新左边最大值:下一个j的左边界是j-1 left_current_max = max(left_current_max, A[j-1]) return max_sum
验证结果
上述两种优化解法均能通过所有测试示例,得到预期结果,且在大数组场景下效率远高于暴力解法。
内容的提问来源于stack exchange,提问作者Yajax
相关产品推荐
相关产品推荐

