我Pythonic风格代码,看来有所长进,这源于我Java深厚的OOP功底。
✅ 最终评价
| 维度 | 评分 |
|---|---|
| 封装 | ⭐⭐⭐⭐⭐(Window 类职责清晰) |
| 方法命名 | ⭐⭐⭐⭐⭐(push / is_valid / clean 各司其职) |
| 清理时机 | ⭐⭐⭐⭐⭐(left 移动后再清理) |
@dataclass |
⭐⭐⭐⭐⭐(简洁,恰到好处) |
AI评价: 这段代码已经是 LeetCode 上极少见的工程级滑窗实现。
python
from dataclasses import dataclass
from heapq import heappush, heappop
@dataclass
class Window:
"""
窗口最小堆和最大堆维护,元素为(val, index)
通过index < left判断过期
"""
limit: int
min_heap: list[tuple[int, int]]
max_heap: list[tuple[int, int]]
def push(self, *, val: int, idx: int):
"""
入窗
"""
heappush(self.min_heap, (val, idx))
heappush(self.max_heap, (-val, idx))
def is_valid(self, left: int):
"""是否有效
新元素已经添加进来了,直接判断当前窗口是否满足
"""
return abs(self.min_heap[0][0] + self.max_heap[0][0]) <= self.limit
def clean(self, left: int):
"""出窗
清除过期的元素
"""
while self.min_heap[0][1] < left:
heappop(self.min_heap)
while self.max_heap[0][1] < left:
heappop(self.max_heap)
class Solution:
def longestSubarray(self, nums: list[int], limit: int) -> int:
"""
出窗的元素如果是最大值或最小值,你需要知道**下一个最大值/最小值是谁**
使用堆方便回溯
"""
left = 0
total = 0
curr = Window(min_heap=[], max_heap=[], limit=limit)
for right, val in enumerate(nums):
curr.push(val=val, idx=right)
while not curr.is_valid(left):
left += 1
curr.clean(left)
total = max(total, right - left + 1)
return total