每日力扣刷题与测试工作集合想法(2)

155 阅读4分钟

引言

算法篇: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),
]

# 检测5分钟内错误码总和≥100的最小窗口
target = 100
result = min_error_window(logs, target)
print(f"最小窗口长度: {result}秒")  # 输出: 120(2分钟)

测试场景应用示例

  • 场景:在性能测试中,需要定位系统响应时间超过阈值(如≥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),  # 时间戳 + 响应时间(ms)
    ("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),
]

# 检测响应时间≥500ms的最小窗口
threshold = 500
result = min_response_time_window(response_times, threshold)
print(f"最小窗口长度: {result}秒")  # 输出: 60(1分钟)