问题描述
小U手上有一个整数数组,他想知道如果从数组中删除任意一个元素后,能得到的长度为 k 的子数组和的最大值。你能帮小U计算出这个结果吗?
如果数组恰好为 k 个元素,那么不进行删除操作。
测试样例
样例1:
输入:
n = 5,k = 3,nums = [2, 1, 3, -1, 4]
输出:8
样例2:
输入:
n = 6,k = 2,nums = [-1, -1, 5, -2, 3, 4]
输出:8
样例3:
输入:
n = 4,k = 2,nums = [-5, -3, 2, 1]
输出:3
题目分析
删除数组的一个数,使其连续的长度为 k 的子数组和有最大值,如果数组恰好为 k 个元素,那么不进行删除操作。首先我能想到的就是直接删除数组中最小的数字,利用贪心算法的思想这样子数组和只可能比原来的大而不会小。同时利用前缀和,这样后面再比较长度为k的子数组和就比较简单了就是pre_nums[i] -pre_nums[i -k],然后输出最大值
于是我就写下了第一版代码:
def solution(n, k, nums):
if n == k :
return sum(nums)
min_index = nums.index(min((nums)))
nums.pop(min_index)
pre_sum = [0]*(n - 1)
pre_sum[0] = nums[0]
for i in range(0,n-2):
pre_sum[i + 1] = nums[i + 1] +pre_sum[i]
res = []
res.append(pre_sum[k-1])
for i in range(k,n-1):
res.append(pre_sum[i]-pre_sum[i-k])
return max(res)
if __name__ == "__main__":
# Add your test cases here
print(solution(5, 3, [2, 1, 3, -1, 4]) == 8)
但是第四个样例报错:
输入
n= 11
k=2
nums=[-16,-20,-18,-4,-20,4,7,9,7,25,-10]
你的输出=32
预期输出=34
经过思考,我发现不能单纯删除整个数组的最小值,于是我尝试再将子数组长度+1,然后删除这个区间里面的最小值。于是就有了我的第二版代码,带debug版
def solution(n, k, nums):
if n == k :
return sum(nums)
pre_sum = [0]*(n)
pre_sum[0] = nums[0]
for i in range(0,n-1):
pre_sum[i + 1] = nums[i + 1] +pre_sum[i]
# print(pre_sum)
res = []
res.append(pre_sum[k])
for i in range(k+1,n):
res.append(pre_sum[i]-pre_sum[i-k-1])
# print(res)
ans = max(res)
# print(ans)
max_index = res.index(max((res)))
min_index = max_index + k + 1
# print(max_index,min_index)
res_range = nums[max_index:min_index]
# print(res_range)
max_num = min(res_range)
# print(max_num)
ans -=max_num
return ans
if __name__ == "__main__":
# Add your test cases here
print(solution(5, 3, [2, 1, 3, -1, 4]) == 8)
但是我发现贪心的思想会陷入局部最优解的情况,因为这一步ans = max(res),所以我就上网查找了求子数组和的几种方式:连续子数组的最大和问题(五种解法)-CSDN博客受此博客启发,修改了我的代码,实现时间复杂度为Q(n)的正确思路,同时要注意边界问题。
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(7,5,[-13,-10,9,-15,-25,17,-15]) == -12)