子数组和的最大值问题解析 | 豆包MarsCode AI刷题

47 阅读3分钟

题目描述

小U手上有一个整数数组,他想知道如果从数组中删除任意一个元素后,能得到的长度为 k 的子数组和的最大值。你能帮小U计算出这个结果吗?
如果数组恰好为 k 个元素,那么不进行删除操作。

样例1:

输入:n = 5,k = 3,nums = [2, 1, 3, -1, 4]
输出:8

题目解析

这个题目中我们要注意几个点:

  1. 子数组和 --> 数组中连续的数据的和,可以用滑动窗口求解
  2. 在这其中会删除一个数得到长度为k的子数组和的最大值 --> 滑动窗口
  3. 由题意中的能得到可知,数组的长度肯定是大于等于k的。而且如果n恰好为K则子数组就是原数组

根据条件2,我们可以分为两种情况,一种是数组长度大小刚好等于k,即n=k,一种是数组长度大于K即n>k

  • 当n=k时,子数组就是这个数组,子数组和的最大值就是数组中所有元素的和,那么我们进行累加就可以了。
   if n ==k : 
       for num in nums:
           s +=num
       ans = s
  • 当n不等于k时,给出的这个整数数组就是长度大于k的情况下,我们要对该数组进行操作,对其求子数组的最大值。

    那使用滑动窗口求最大值,也就是求滑动窗口中的最大值。如何求滑动窗口呢?

    我们可以定义一个双指针,不过这次的双指针是头尾指针,而头尾指针中包含K个数据,看上去就像一个“窗口”,而我们根据条件2的要求,要求窗口内的数和的最大值。

具体步骤为:

  1. 定义一个s变量求滑动窗口中数的和,一个ans记录窗口中长度为k的数字和的最大值(初始化为很小的值)
  s,start = 0,0
  ans= -float("inf")
  1. 定义首尾指针,一个指向数组索引为0的位置的首指针start,一个尾指针end,但是这个end放在for循环中,每一次循环加1,指向下一个数。

  2. end在for循环中遍历每个元素,当end-start+1(窗口的长度)大于k的时候(此时窗口长度应为k+1),我们再遍历窗口中的值,然后删除其中任意一个数(每个数都删除一遍),然后比较s(当前滑动窗口的总值)和ans(历史窗口最大值)

  3. 然后再将删除的数加回来,此时我们已经完成了一遍长度为k的窗口内的最大值查找,(因为我们仍要保持s是窗口中的所有值的和,所以我们要将删除的数加回来)

  4. 移除窗口起始位置的元素,即将 nums[start] 从 s 中减去,并将 start 向后移动一位,因为我们的窗口要向右移动一位了,同时我们要保证窗口值为k+1,因为在for循环中,end稍后会+1

  5. 然后start+1,窗口滑动(此时end+1,start也+1,相当于窗口向后滑动了一次),然后继续查找窗口内的最大值,直到遍历完毕,也就是直到end==n-1为止

   for end in range(len(nums)):
           s +=nums[end]
           if end-start+1==k+1:
               for i in range(start,end+1):
                   s-=nums[i] 
                   ans = max(ans,s)
                   s+=nums[i]
               s -= nums[start]
               start  +=1

完整代码

ef solution(n, k, nums):
    # Edit your code here
    s,start = 0,0
    ans= -float("inf")
    if n ==k : 
        for num in nums:
            s +=num
        ans = s
    else:
        for end in range(len(nums)):
            s +=nums[end]
            if end-start+1==k+1:
                for i in range(start,end+1):
                    s-=nums[i] 
                    ans = max(ans,s)
                    s+=nums[i]
                s -= nums[start]
                start  +=1
        print("ans:",ans)
    return ans