在我们系列的第二部分中,我们深入研究解决编码面试问题的最通用的模式之一:滑动窗口。此技术对于优化涉及连续元素的子数组或子字符串的问题非常有用,例如最大化总和、查找序列中的特定条件或处理字符串中的子字符串。
在我们开始之前,如果您正在寻找准备编码面试的全面指南,请考虑查看《破解编码面试》,这是任何认真想在顶级科技公司找到工作的人的必备书籍。
滑动窗口模式是一种技术,可让您有效地解决需要考虑较大数据集中的数据子集(例如数组的子数组或字符串的子字符串)的问题。这种技术不是每次移动窗口时都重新计算子集,而是维护一个运行总计或条件,在数据之间滑动以最大程度地减少不必要的工作。
示例问题:给定一个整数数组和一个数字 k,找到大小为 k 的任何子数组的最大和。
def max_sum_subarray(arr, k): # Initialize variables to store the maximum sum and the current window sum. max_sum = 0 window_sum = 0 # First, calculate the sum of the initial window (first 'k' elements). for i in range(k): window_sum += arr[i] # Set the max_sum to the initial window's sum. max_sum = window_sum # Now, slide the window across the array. # Start from the kth element and move until the end of the array. for i in range(k, len(arr)): # Slide the window by subtracting the element that is no longer in the window # (arr[i - k]) and adding the new element (arr[i]). window_sum += arr[i] - arr[i - k] # Update max_sum if the current window sum is greater than the previous max_sum. max_sum = max(max_sum, window_sum) # Return the maximum sum found. return max_sum
说明:
示例问题:给定一个整数数组和一个数字 S,找到总和大于或等于 S 的最小连续子数组。
def smallest_subarray_with_sum(arr, S): # Initialize variables: # window_sum: to store the sum of the current window. # min_length: to store the length of the smallest subarray found. # window_start: the starting index of the sliding window. window_sum = 0 min_length = float('inf') # Start with a large number to compare minimum lengths. window_start = 0 # Iterate over the array with window_end being the right boundary of the window. for window_end in range(len(arr)): # Add the current element to the window_sum. window_sum += arr[window_end] # While the current window's sum is greater than or equal to S: while window_sum >= S: # Calculate the current window size and update min_length if smaller. min_length = min(min_length, window_end - window_start + 1) # Shrink the window from the left by removing the element at window_start. window_sum -= arr[window_start] # Move the start of the window to the right. window_start += 1 # If min_length was updated, return it; otherwise, return 0 (meaning no valid subarray was found). return min_length if min_length != float('inf') else 0
说明:
定义窗口边界:您需要定义窗口的开始和结束。
设置初始条件:对于固定窗口,初始化第一个窗口的和/乘积/条件。对于动态窗口,初始条件取决于问题的目标。
滑动窗口:
检查并更新结果:每次窗口移动后,根据需要更新结果(例如最大总和、最小长度等)。
最长无重复字符的子串
大小为 K 的最大和子数组
给定总和的最小子数组
考虑窗口边界:首先考虑窗口应该从哪里开始和结束。这可以帮助您确定正在使用的确切范围。
对动态窗口使用哈希图或集合:处理子字符串或唯一元素时,使用集合来跟踪窗口中的元素。
从暴力开始,然后优化:在某些问题中,从暴力方法开始(例如检查每个可能的子数组)可以帮助您想象滑动窗口如何减少不必要的工作。
寻找最佳条件:如果问题具有优化成分(例如最小化或最大化总和或长度),则滑动窗口可能是一个不错的选择。
滑动窗口模式是解决许多编码面试问题的强大工具,尤其是涉及数组或字符串等序列的问题。通过掌握固定大小和动态滑动窗口,您可以更有效地解决各种问题。
在下一篇文章中,我们将探讨双指针技术,这是另一种高效的策略,通常在涉及元素之间配对或比较的问题中补充滑动窗口方法。
敬请期待第三部分!
以上是破解编码面试:滑动窗口模式的一部分的详细内容。更多信息请关注PHP中文网其他相关文章!