引言
算法篇:209.长度最小的子数组(滑动窗口)
- 题目描述:给定一个含有==n==个正整数的数组和一个正整数==target==,找出该数组中满足其和==>=target==的长度最小的连续子数组,并放回其长度。如果不存在符合条件的子数组,返回0.
- 测试场景映射:
- 应用场景:
- 监控系统日志中连续时间窗口内的错误码频率(如5分钟内错误码出现次数>=10次)。
- 性能测试中定位系统响应时间超过阈值的连续时间段。
- 解题思路:
- **滑动窗口:**维护一个可变的滑动窗口来找出最小值,通过left/right指针来调整窗口的大小
- 时间复杂度:O(n),适合实时流数据处理。
- 代码实现
def min_subarrary_len(target:int,nums:list[int])->int:
"""
209,长度最小的子数组--滑动窗口的解法:
:param target:目标和
:param nums:正整数数组
:return:最小数组的长度
"""
left=0
min_len=float('inf')
current_sum=0
for right in range(len(nums)):
current_sum+=nums[right]
while current_sum>=target:
min_len=min(min_len,right-left+1)
current_sum-=nums[left]
left+=1
return min_len if min_len!=float('inf') else 0
测试场景应用示例
- 场景:在系统文件中,每条日志都包含一个错误码(正整数)。需要检测是否存在连续时间窗口内的错误码总数是否超过阈值(如五分钟内错误码综合>=100),并返回满足条件的最小时间窗口长度。
- 代码改造:
from datetime import datetime, timedelta
def min_error_window(logs: list[tuple[str, int]], target: int) -> int:
"""
检测日志中连续时间窗口内错误码总和≥target的最小窗口长度
:param logs: 日志列表,格式为 [(时间戳, 错误码), ...]
:param target: 错误码总和阈值
:return: 最小窗口长度(秒),若无满足条件的窗口返回0
"""
left = 0
min_len = float('inf')
current_sum = 0
for right in range(len(logs)):
timestamp_str, error_code = logs[right]
timestamp = datetime.strptime(timestamp_str, "%Y-%m-%d %H:%M:%S").timestamp()
current_sum += error_code
while current_sum >= target:
window_start = datetime.strptime(logs[left][0], "%Y-%m-%d %H:%M:%S").timestamp()
window_len = timestamp - window_start
min_len = min(min_len, window_len)
current_sum -= logs[left][1]
left += 1
return int(min_len) if min_len != float('inf') else 0
logs = [
("2024-02-01 12:00:00", 20),
("2024-02-01 12:01:00", 30),
("2024-02-01 12:02:00", 50),
("2024-02-01 12:03:00", 10),
("2024-02-01 12:04:00", 40),
]
target = 100
result = min_error_window(logs, target)
print(f"最小窗口长度: {result}秒")
测试场景应用示例
- 场景:在性能测试中,需要定位系统响应时间超过阈值(如≥500ms)的连续时间段,并返回满足条件的最小时间窗口长度。
- 代码改造:
def min_response_time_window(response_times: list[tuple[str, int]], threshold: int) -> int:
"""
检测响应时间超过阈值的最小连续时间窗口
:param response_times: 响应时间列表,格式为 [(时间戳, 响应时间), ...]
:param threshold: 响应时间阈值(ms)
:return: 最小窗口长度(秒),若无满足条件的窗口返回0
"""
left = 0
min_len = float('inf')
current_count = 0
for right in range(len(response_times)):
timestamp_str, response_time = response_times[right]
timestamp = datetime.strptime(timestamp_str, "%Y-%m-%d %H:%M:%S").timestamp()
if response_time >= threshold:
current_count += 1
while current_count > 0:
window_start = datetime.strptime(response_times[left][0], "%Y-%m-%d %H:%M:%S").timestamp()
window_len = timestamp - window_start
min_len = min(min_len, window_len)
if response_times[left][1] >= threshold:
current_count -= 1
left += 1
return int(min_len) if min_len != float('inf') else 0
response_times = [
("2024-02-01 12:00:00", 300),
("2024-02-01 12:01:00", 600),
("2024-02-01 12:02:00", 400),
("2024-02-01 12:03:00", 700),
("2024-02-01 12:04:00", 200),
]
threshold = 500
result = min_response_time_window(response_times, threshold)
print(f"最小窗口长度: {result}秒")