返回
滑过有难度的算法面试题:滑过窗口
见解分享
2024-01-14 07:44:58
滑动窗口算法简介
滑动窗口算法是一种在输入数据流上应用计算的通用技术。它通过在数据流上移动一个固定大小的窗口,并对窗口内的元素进行计算来工作。滑动窗口算法通常用于在线处理数据,例如实时分析、数据挖掘和机器学习。
滑动窗口算法的优点在于它能够在有限的内存空间内处理大量数据,并且具有较低的计算复杂度。这使得它非常适合处理实时数据或大规模数据集。
滑动窗口算法面试题
1. 最大子数组和
给定一个整数数组,找到连续子数组的最大和。
示例:
输入:[−2, 1, −3, 4, −1, 2, 1, −5, 4]
输出:6
解释:连续子数组 [4, -1, 2, 1] 的和最大,为 6。
解决方案:
def max_subarray_sum(nums):
"""
找到连续子数组的最大和。
参数:
nums:一个整数数组。
返回:
连续子数组的最大和。
"""
# 初始化最大和和当前和
max_sum = float('-inf')
current_sum = 0
# 遍历数组
for num in nums:
# 更新当前和
current_sum = max(num, current_sum + num)
# 更新最大和
max_sum = max(max_sum, current_sum)
# 返回最大和
return max_sum
# 测试
nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
print(max_subarray_sum(nums)) # 输出:6
2. 最长无重复子字符串
给定一个字符串,找到最长不包含重复字符的子字符串的长度。
示例:
输入:"abcabcbb"
输出:3
解释:最长不包含重复字符的子字符串是 "abc"。
解决方案:
def longest_substring_without_repeating_characters(s):
"""
找到最长不包含重复字符的子字符串的长度。
参数:
s:一个字符串。
返回:
最长不包含重复字符的子字符串的长度。
"""
# 初始化最长子字符串长度和当前子字符串长度
max_length = 0
current_length = 0
# 初始化一个字典来存储字符及其最后出现的位置
char_index_map = {}
# 遍历字符串
for i, char in enumerate(s):
# 如果字符在字典中,并且其最后出现的位置在当前子字符串中,则更新当前子字符串的长度
if char in char_index_map and char_index_map[char] >= i - current_length:
current_length = i - char_index_map[char]
# 更新字符的最后出现位置
char_index_map[char] = i
# 更新最长子字符串长度
max_length = max(max_length, current_length + 1)
# 返回最长子字符串长度
return max_length
# 测试
s = "abcabcbb"
print(longest_substring_without_repeating_characters(s)) # 输出:3
3. 最小覆盖子字符串
给定一个字符串和一个目标字符串,找到包含目标字符串的最小覆盖子字符串。
示例:
输入:"abcabcbb", "abc"
输出:"abc"
解释:包含目标字符串 "abc" 的最小覆盖子字符串是 "abc"。
解决方案:
def minimum_window_substring(s, t):
"""
找到包含目标字符串的最小覆盖子字符串。
参数:
s:一个字符串。
t:一个目标字符串。
返回:
包含目标字符串的最小覆盖子字符串。
"""
# 初始化目标字符串中的字符及其频率
char_freq = {}
for char in t:
if char not in char_freq:
char_freq[char] = 0
char_freq[char] += 1
# 初始化滑动窗口的左右边界和最小覆盖子字符串的长度
left = 0
right = 0
min_length = float('inf')
min_substring = ""
# 初始化满足条件的字符数
satisfied_char_count = 0
# 遍历字符串
while right < len(s):
# 如果当前字符在目标字符串中,并且其频率小于目标字符串中的频率,则更新满足条件的字符数
if s[right] in char_freq and char_freq[s[right]] > 0:
satisfied_char_count += 1
# 更新目标字符串中的字符频率
if s[right] in char_freq:
char_freq[s[right]] -= 1
# 如果满足条件的字符数等于目标字符串中的字符数,则更新最小覆盖子字符串的长度和子字符串
while satisfied_char_count == len(char_freq):
# 更新最小覆盖子字符串的长度和子字符串
current_length = right - left + 1
if current_length < min_length:
min_length = current_length
min_substring = s[left:right+1]
# 更新目标字符串中的字符频率
if s[left] in char_freq:
char_freq[s[left]] += 1
# 如果当前字符在目标字符串中,并且其频率大于 0,则更新满足条件的字符数
if s[left] in char_freq and char_freq[s[left]] > 0:
satisfied_char_count -= 1
# 移动左边界
left += 1
# 移动右边界
right += 1
# 返回最小覆盖子字符串
return min_substring
# 测试
s = "abcabcbb"
t = "abc"
print(minimum_window_substring(s, t)) # 输出:"abc"