子数组和的最大问题

57 阅读2分钟

def solution(n, k, nums): if n == k : return sum(nums) nums = [0]+nums print(nums) pre_sum = [0]*(n+1) pre_sum[0] = nums[0] ans = -float('inf') for i in range(0,n): pre_sum[i + 1] = nums[i + 1] +pre_sum[i] if i >= k: min_index = i - k + 1 max_index = i + 2 # print(min_index,max_index,i +1,i-k) ans = max(ans,pre_sum[i +1]-pre_sum[i-k]- min(nums[min_index:max_index])) return ans if name == "main": # Add your test cases here print(solution(5, 3, [2, 1, 3, -1, 4]) == 8) 这个solution函数的目的是解决一个特定的问题,即给定一个数组nums、一个整数n(数组的长度)和一个整数k,找到数组的一个长度为k的子数组,使得从这个子数组中去掉一个元素后的剩余元素之和最大化,并且这个最大化和减去去掉的元素值之间的差也是最大的。下面是对这个函数的详细思路分析: 特殊情况处理: 如果n == k,意味着整个数组就是我们要考虑的子数组,此时没有元素可以移除,所以直接返回数组的总和。 数组扩展: 为了方便处理边界情况,函数首先将nums数组前面添加一个0,变为[0] + nums。这样做是为了让前缀和数组pre_sum能够正确计算从数组起始位置开始的任意子数组的和。 前缀和数组构建: 创建一个长度为n+1的前缀和数组pre_sum,其中pre_sum[i]表示nums数组中从索引0到i-1的元素之和(因为数组扩展了,所以实际上计算的是原数组从索引0到i-2的和,但这里为了统一处理边界,采用了这种方式)。 初始化答案: 将答案ans初始化为负无穷大,因为我们是要找最大值。 遍历数组: 遍历数组nums(实际上是遍历索引从0到n-1),对于每个索引i,计算到当前位置的前缀和pre_sum[i+1]。 当i >= k时,意味着我们可以从当前位置向前取长度为k的子数组。 计算这个子数组的和(pre_sum[i+1] - pre_sum[i-k+1])。 在这个子数组中,找到要移除的最小元素的值。这里通过取子数组nums[i-k+1:i+2](注意这里的范围是为了包括当前元素的后一个位置作为边界,但因为要取最小值,所以实际不会影响结果)中的最小值来实现。注意这里的i+2是超出了子数组范围的,但由于nums前面加了0,这实际上不会改变结果,只是为了简化索引处理。 更新答案ans为当前子数组和减去最小元素后的最大值与之前的ans的较大值。 返回结果: 返回计算得到的ans。