Two Pointer and sliding window pattern

WHAT TO KNOW - Sep 10 - - Dev Community

<!DOCTYPE html>





Two Pointer and Sliding Window Techniques: A Comprehensive Guide

<br> body {<br> font-family: sans-serif;<br> margin: 20px;<br> }</p> <div class="highlight"><pre class="highlight plaintext"><code> h1, h2, h3 { color: #333; } pre { background-color: #f5f5f5; padding: 10px; border-radius: 5px; overflow-x: auto; } img { max-width: 100%; height: auto; display: block; margin: 10px auto; } </code></pre></div> <p>



Two Pointer and Sliding Window Techniques: A Comprehensive Guide



In the realm of algorithms and data structures, efficient problem-solving is paramount. Two Pointer and Sliding Window techniques are powerful tools that offer elegant solutions for a wide range of problems, particularly those involving arrays or strings. These techniques leverage the concept of pointers and windows to traverse data structures effectively, optimize time complexity, and simplify code implementation.


  1. Two Pointer Technique

1.1 Introduction

The Two Pointer technique utilizes two pointers, usually named left and right, to traverse a sorted array or a linked list. These pointers are initialized at specific positions and move towards each other (or in the same direction, depending on the problem) while processing elements.

The key idea is to use the relative positions of the pointers to perform comparisons and make decisions. This technique is particularly effective for problems involving:

  • Finding pairs of elements that satisfy a certain condition.
  • Sorting or merging arrays efficiently.
  • Searching for specific elements in a sorted sequence.

1.2 Example: Find the pair with a given sum in a sorted array

Let's illustrate with a classic example: finding a pair of elements in a sorted array that add up to a target sum.


def find_pair_with_sum(arr, target):
left = 0
right = len(arr) - 1


while left < right:
current_sum = arr[left] + arr[right]

if current_sum == target:
  return (left, right)
elif current_sum &lt; target:
  left += 1
else:
  right -= 1

return None

Example Usage

arr = [1, 2, 3, 4, 5]
target = 7
result = find_pair_with_sum(arr, target)

if result:
print(f"Pair found at indices: {result}")
else:
print("No pair found.")



In this example, the left pointer starts at the beginning, and the right pointer starts at the end. We iteratively compare the sum of the elements pointed to by left and right. If the sum equals the target, we have found the pair. If the sum is less than the target, we move left one step to the right. If the sum is greater than the target, we move right one step to the left. The loop continues until the pointers cross each other.


Two Pointer Technique Illustration


1.3 Time Complexity Analysis



The Two Pointer technique typically achieves a time complexity of O(n), where n is the size of the input array or linked list. This is because each pointer traverses the array only once, resulting in a linear time complexity.



1.4 Applications



Two Pointer techniques find applications in numerous algorithms, including:


  • Merge Sort: Efficiently merging two sorted arrays.
  • Binary Search: Finding a specific element in a sorted array.
  • Three Sum Problem: Finding triplets in an array that sum to zero.
  • Trapping Rain Water: Calculating the amount of water that can be trapped between vertical bars.

  1. Sliding Window Technique

2.1 Introduction

The Sliding Window technique involves using a window of fixed or variable size to traverse a sequence of data, typically an array or string. The window slides across the sequence, processing elements within its boundaries.

This technique is particularly useful for problems involving:

  • Finding the maximum or minimum sum of a subarray within a given window size.
  • Counting the occurrences of a specific pattern within a string.
  • Identifying substrings with specific properties.

2.2 Example: Find the maximum sum of a subarray of size k

Let's consider the problem of finding the maximum sum of a subarray of size k within an array.


def max_sum_subarray(arr, k):
if len(arr) < k:
return -1


max_sum = float('-inf')
current_sum = 0
window_start = 0

for window_end in range(len(arr)):
current_sum += arr[window_end]

if window_end &gt;= k - 1:
  max_sum = max(max_sum, current_sum)
  current_sum -= arr[window_start]
  window_start += 1

return max_sum

Example Usage

arr = [2, 1, 5, 1, 3, 2]
k = 3
result = max_sum_subarray(arr, k)
print(f"Maximum sum of subarray of size {k}: {result}")



In this example, the window size is k. We initialize window_start to 0, and current_sum to 0. As the window slides, we add the new element to current_sum and update the maximum sum. When the window reaches its full size, we remove the element at window_start from current_sum and slide the window forward.


Sliding Window Technique Illustration


2.3 Time Complexity Analysis



The Sliding Window technique generally achieves a time complexity of O(n), where n is the size of the input sequence. This is because the window traverses the sequence only once, resulting in a linear time complexity.



2.4 Applications



Sliding Window techniques are employed in a wide range of algorithms, including:


  • Longest Substring Without Repeating Characters: Finding the longest substring without repeating characters within a string.
  • Minimum Window Substring: Finding the smallest substring that contains all characters from a given pattern.
  • Fruit Into Baskets: Finding the maximum number of fruits you can pick from a basket with a constraint on the types of fruits.
  • Permutations in a String: Identifying all permutations of a given pattern within a string.

  1. Combining Two Pointer and Sliding Window Techniques

Sometimes, it is advantageous to combine the Two Pointer and Sliding Window techniques to solve more complex problems. For instance, you might use two pointers to maintain the boundaries of a sliding window or use a sliding window to find pairs of elements within a given range.

3.1 Example: Find the maximum sum of a subarray with a given difference

Suppose we want to find the maximum sum of a subarray where the difference between the maximum and minimum elements within the subarray is less than or equal to a given difference k. We can utilize both techniques:


def max_sum_subarray_difference(arr, k):
if len(arr) == 0:
return 0


max_sum = float('-inf')
window_start = 0
window_end = 0

while window_end < len(arr):
current_max = max(arr[window_start:window_end + 1])
current_min = min(arr[window_start:window_end + 1])

if current_max - current_min &lt;= k:
  max_sum = max(max_sum, sum(arr[window_start:window_end + 1]))
  window_end += 1
else:
  window_start += 1

return max_sum

Example Usage

arr = [1, 4, 2, 3, 5, 2, 1]
k = 3
result = max_sum_subarray_difference(arr, k)
print(f"Maximum sum of subarray with difference <= {k}: {result}")



Here, we use two pointers, window_start and window_end, to define a sliding window. Inside the window, we calculate the maximum and minimum values. If the difference between them is less than or equal to k, we update the maximum sum. Otherwise, we slide the window by increasing window_start.


  1. Conclusion

Two Pointer and Sliding Window techniques are powerful tools that can significantly enhance the efficiency and elegance of algorithms. By leveraging pointers and windows to traverse data structures effectively, we can achieve linear time complexity for a wide range of problems involving arrays, strings, and other sequences.

These techniques are highly versatile and can be combined to address more complex scenarios. Understanding their principles and applications will equip you with valuable tools for tackling algorithmic challenges and optimizing code performance.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player