青训营X豆包MarsCode 技术训练营 - 第二篇刷题笔记-滑窗No.2| 豆包MarsCode AI 刷题

117 阅读3分钟

青训营X豆包MarsCode - 第二篇滑窗- 370| 豆包MarsCode AI 刷题

氦嗨氦,让我们继续滑!上期写了个中等的sharing,这次挑了个Hard,让

“各位提瓦特大陆的探索者,今天我们将扮演不同角色,一起来解决一个关于数组子区间平均值的有趣问题,逐步揭开MarsCode刷题的真相!”

不说俏皮话了,题号 370-Hard-子区间平均值问题

题目原文

小U有一个长度为n的整数数组,并且选择了一个有理数 u/v。他现在想知道这个数组中有多少个连续的子区间,其平均值恰好等于 u/v。数组的子区间是指数组中一段连续的元素。

例如,给定数组 [2, 4, 1, 3, 2, 3] 和有理数 5/2,我们需要找出所有平均值等于 5/2 的子区间。

题目抽象分析

“我们要找出数组中所有连续子区间的平均值等于给定的有理数 u/v 的个数”:

  • 连续子区间

    • 还要是所有
  • 约束条件 = 平均值blabla

题目类型

这个问题属于数组与滑动窗口类型,因为我们需要在数组中滑动一个窗口来计算不同子区间的平均值。

整体思路

既然是所有符合条件的子区间,那mo,为了实现这一点,我们可以采用滑动窗口的方法,遍历数组中的每一个可能的子区间,并计算其平均值。

  • 如果平均值等于 u/v,计数器加一,然后return即可。

代码分块解析

  1. 初始化计数器count 用于记录符合条件的子区间数量。

  2. 遍历数组:双层循环needed

    • 使用外层循环来确定子区间的起始位置。
    • 滑动窗口:使用内层循环来扩展窗口,计算当前窗口的平均值。
  3. 计算平均值

    • window_avg 用于存储当前窗口的平均值。
    • 条件约束判断并++ :如果 window_avg 等于 u/v,则将 count 加一。
  4. 窗口移动

    • 移除窗口最开始的元素,并移动窗口的起始位置。

解题步骤

  1. 初始化计数器 count 为 0。
  2. 使用外层循环遍历数组的每一个元素,作为子区间的起始位置。
  3. 对于每个起始位置,使用内层循环扩展窗口,计算当前窗口的平均值。
  4. 如果当前窗口的平均值等于 u/v,则将 count 加一。
  5. 移除窗口最开始的元素,并移动窗口的起始位置。
  6. 重复步骤3-5,直到窗口扩展到数组末尾。
  7. 返回 count 作为最终结果。

代码

def solution(n: int, u: int, v: int, arr: list) -> int:
    # 初始化计数器
    count = 0
    
    # 遍历数组,每次遍历计算窗口的平均值
    for i in range(n):
        # 窗口的起始位置
        start = i
        # 窗口的结束位置
        end = i
        # 窗口内元素的总和
        total = 0
        
        # 计算窗口内元素的总和
        while end < n:
            total += arr[end]
            end += 1
            
            # 计算窗口的平均值
            window_avg = total / (end - start)
            
            # 如果窗口的平均值等于 u/v,则计数器加1
            if window_avg == u / v:
                count += 1
        
        # 窗口移除最开始的元素
        total -= arr[start]
        start += 1
        
    return count
​
# 测试
if __name__ == '__main__':
    print(solution(6, 5, 2, [2, 4, 1, 3, 2, 3]) == 6)
    print(solution(5, 1, 1, [1, 1, 1, 1, 1]) == 15)
    print(solution(4, 2, 1, [2, 2, 2, 2]) == 10)
​

复杂度分析

参考了别的老哥的写法环节,我也来试试复杂度分析

  • 时间复杂度:O(n2)O(n^2),、我们有两层循环来确定子区间的起始和结束位置,虽然可能应该或许没有到n2n^2,但是最坏就是(?)
  • 空间复杂度:O(1)O(1) ,和n没啥关系。

总结

虽然是Hard,但依旧是直观且易于理解的Solution。

打油诗已无灵感,环节pass,继续前进,朋友们,让我们一起在代码的世界中遨游!