Short Notes on Two Pointer and Sliding Window

Last Updated : 9 Sep, 2025

Basics of Two Pointer

The two-pointer technique uses two indices that move towards each other or in the same direction to process data efficiently.
It is commonly used when:

  • Data is sorted or the problem has sequential properties.
  • We need to find pairs/triplets or process subarrays without restarting from scratch.
  • It works in O(n) for many problems that would otherwise require O(n²).

Common patterns:

  • Opposite Direction: Pointers at start and end, moving toward each other (e.g., 2-Sum, Container with Most Water).
  • Same Direction: Both pointers move forward, where one lags behind the other to form a range (e.g., Remove Duplicates from Sorted Array).

Two Pointer Algorithm – O(n) Time, O(1) Space

Example: 2 - Sum in Sorted Array

You are given an integer array arr[] sorted in non-decreasing order, and an integer target. Find two elements in the array whose sum equals target.

  • If such a pair exists, return their indices in increasing order.
  • If no such pair exists, return [-1, -1].

Approach - Using Two Pointers - O(n) Time and O(1) Space

We can maintain two pointers, left = 0 and right = n - 1, and calculate their sum S = arr[left] + arr[right].

  • If S = target, then return left and right.
  • If S < target, then we need to increase sum S, so we will increment left = left + 1.
  • If S > target, then we need to decrease sum S, so we will decrement right = right - 1.

If at any point left >= right, then no pair with sum = target is found.

Algorithm:

Initialize left = 0 and right = n-1.
While left < right:

  • If arr[left] + arr[right] == target, return the pair.
  • If sum is smaller, move left++.
  • If sum is larger, move right--.

Repeat until pointers meet.

C++
vector<int> twoSumSorted(vector<int>& arr, int target) {
    int left = 0, right = arr.size() - 1;
    while (left < right) {
        int sum = arr[left] + arr[right];
        if (sum == target)
            return {arr[left], arr[right]};
        else if (sum < target)
            left++;
        else
            right--;
    }
    return {};
}
Java
import java.util.ArrayList;

class GfG {

    public ArrayList<Integer> twoSumSorted(int[] arr, int target) {
        int left = 0;
        int right = arr.length - 1;

        while (left < right) {
            int sum = arr[left] + arr[right];

            if (sum == target) {
                ArrayList<Integer> result = new ArrayList<>();
                result.add(arr[left]);
                result.add(arr[right]);
                return result;
            } else if (sum < target) {
                left++;
            } else {
                right--;
            }
        }

        return new ArrayList<>(); 
    }
}
Python
def twoSumSorted(self, arr, target):
    left = 0
    right = len(arr) - 1

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

        if sum_val == target:
            result = [arr[left], arr[right]]
            return result
        elif sum_val < target:
            left += 1
        else:
            right -= 1

    return []
C#
using System;
using System.Collections.Generic;

class GfG{
    public List<int> twoSumSorted(int[] arr, int target){
        int left = 0;
        int right = arr.Length - 1;

        while (left < right){
            int sum = arr[left] + arr[right];

            if (sum == target){
                List<int> result = new List<int>();
                result.Add(arr[left]);
                result.Add(arr[right]);
                return result;
            }
            else if (sum < target){
                left++;
            }
            else{
                right--;
            }
        }

        return new List<int>();
    }
}
JavaScript
twoSumSorted(arr, target) {
    let left = 0;
    let right = arr.length - 1;

    while (left < right) {
        let sum = arr[left] + arr[right];

        if (sum === target) {
            return [arr[left], arr[right]];
        } else if (sum < target) {
            left++;
        } else {
            right--;
        }
    }

    return [];
}

Example: Merge Two Sorted Arrays (No Extra Space)

Given two sorted arrays a[] and b[] of size and m respectively, merge both the arrays and rearrange the elements such that the smallest elements are in a[] and the remaining m elements are in b[]. All elements in a[] and b[] should be in sorted order.

Approach - Using Swap and Sort

We swap the rightmost element of a[] with the leftmost element of b[], then the second rightmost element of a[] with the second leftmost element of b[], and so on. This process continues until the selected element from a[] becomes larger than the selected element from b[]. At this point, the condition fails automatically and the process stops. Finally, sort both arrays to maintain the order.

Algorithm:

  • Start from the end of both arrays.
  • Compare and shift larger elements to the end of merged space.
  • Fill remaining from other array if needed.


C++
void mergeArrays(vector<int>& arr1, vector<int>& arr2) {
    int n = arr1.size(), m = arr2.size();
    int i = n - 1, j = 0;
    
    // Swap elements if needed
    while (i >= 0 && j < m) {
        if (arr1[i] > arr2[j])
            swap(arr1[i], arr2[j]);
        i--;
        j++;
    }
    // Sort both arrays
    sort(arr1.begin(), arr1.end());
    sort(arr2.begin(), arr2.end());
}
Java
import java.util.Arrays;

public class Solution {

    public void mergeArrays(int[] arr1, int[] arr2) {
        int n = arr1.length, m = arr2.length;
        int i = n - 1, j = 0;

        // Swap elements if needed
        while (i >= 0 && j < m) {
            if (arr1[i] > arr2[j]) {
                int temp = arr1[i];
                arr1[i] = arr2[j];
                arr2[j] = temp;
            }
            i--;
            j++;
        }

        // Sort both arrays
        Arrays.sort(arr1);
        Arrays.sort(arr2);
    }
}
Python
def mergeArrays(arr1, arr2):
    n = len(arr1)
    m = len(arr2)
    i = n - 1
    j = 0

    # Swap elements if needed
    while i >= 0 and j < m:
        if arr1[i] > arr2[j]:
            arr1[i], arr2[j] = arr2[j], arr1[i]
        i -= 1
        j += 1

    # Sort both arrays
    arr1.sort()
    arr2.sort()
C#
using System;

class GfG {
    public void mergeArrays(int[] arr1, int[] arr2){
        int n = arr1.Length, m = arr2.Length;
        int i = n - 1, j = 0;

        // Swap elements if needed
        while (i >= 0 && j < m){
            if (arr1[i] > arr2[j]){
                int temp = arr1[i];
                arr1[i] = arr2[j];
                arr2[j] = temp;
            }
            i--;
            j++;
        }

        // Sort both arrays
        Array.Sort(arr1);
        Array.Sort(arr2);
    }
}
JavaScript
function mergeArrays(arr1, arr2) {
    let n = arr1.length;
    let m = arr2.length;
    let i = n - 1;
    let j = 0;

    // Swap elements if needed
    while (i >= 0 && j < m) {
        if (arr1[i] > arr2[j]) {
            let temp = arr1[i];
            arr1[i] = arr2[j];
            arr2[j] = temp;
        }
        i--;
        j++;
    }

    // Sort both arrays
    arr1.sort((a, b) => a - b);
    arr2.sort((a, b) => a - b);
}

Classical Problems on Two Pointer:

  • Check if a string is Palindrome
  • Reverse an array
  • Dutch National Flag (DNF) Algorithm
  • 2-Sum (sorted array / count all distinct pairs / closest to target)
  • Check subsequence of a string
  • Move zeros to end
  • 3-Sum / Count distinct triplets / Closest to target
  • Count possible triangles
  • 4-Sum
  • Trapping Rainwater Problem

Basics of Sliding Window

Sliding Window is a technique for problems involving contiguous subarrays or substrings.
Instead of recalculating the result from scratch for each window, we:

  • Add the incoming element
  • Remove the outgoing element
  • Update our answer in O(1) time per shift

Types:

  • Fixed Window — Window size k (e.g., Maximum sum in size-k subarray)
  • Variable Window — Window expands/contracts to meet conditions (e.g., Longest Substring Without Repeating Characters)

Sliding Window Algorithm – O(n) Time

Example: Maximum Sum in K Size Subarray

Consider an array arr[] = [5, 2, -1, 0, 3] and value of k = 3 and n = 5
This is the initial phase where we have calculated the initial window sum starting from index 0 . At this stage the window sum is 6. Now, we set the maximum_sum as current_window i.e 6.

1

Now, we slide our window by a unit index. Therefore, now it discards 5 from the window and adds 0 to the window. Hence, we will get our new window sum by subtracting 5 and then adding 0 to it. So, our window sum now becomes 1. Now, we will compare this window sum with the maximum_sum. As it is smaller, we won't change the maximum_sum.

2

Similarly, now once again we slide our window by a unit index and obtain the new window sum to be 2. Again we check if this current window sum is greater than the maximum_sum till now. Once, again it is smaller so we don't change the maximum_sum.

Therefore, for the above array our maximum_sum is 6.

3
000

Algorithm:

  • Compute sum of first k elements.
  • Slide the window: subtract outgoing element, add incoming element.
  • Track maximum sum.
C++
int maxSubarraySum(vector<int>& arr, int k) {
    int n = arr.size();
    if (n < k) return -1;

    // compute sum of first window
    int windowSum = 0;
    for (int i = 0; i < k; i++) {
        windowSum += arr[i];
    }

    int maxSum = windowSum;

    // slide the window
    for (int i = k; i < n; i++) {
        windowSum += arr[i] - arr[i - k];
        maxSum = max(maxSum, windowSum);
    }

    return maxSum;
}
Java
class GfG {
    static int maxSubarraySum(int[] arr, int k) {
        int n = arr.length;
        if (n < k) return -1;

        // compute sum of first window
        int windowSum = 0;
        for (int i = 0; i < k; i++) {
            windowSum += arr[i];
        }

        int maxSum = windowSum;

        // slide the window
        for (int i = k; i < n; i++) {
            windowSum += arr[i] - arr[i - k];
            maxSum = Math.max(maxSum, windowSum);
        }

        return maxSum;
    }

}
Python
def maxSubarraySum(arr, k):
    n = len(arr)
    if n < k:
        return -1

    # compute sum of first window
    windowSum = sum(arr[:k])
    maxSum = windowSum

    # slide the window
    for i in range(k, n):
        windowSum += arr[i] - arr[i - k]
        maxSum = max(maxSum, windowSum)

    return maxSum
C#
class GfG {
    static int maxSubarraySum(int[] arr, int k) {
        int n = arr.Length;
        if (n < k) return -1;

        // compute sum of first window
        int windowSum = 0;
        for (int i = 0; i < k; i++) {
            windowSum += arr[i];
        }

        int maxSum = windowSum;

        // slide the window
        for (int i = k; i < n; i++) {
            windowSum += arr[i] - arr[i - k];
            maxSum = Math.Max(maxSum, windowSum);
        }

        return maxSum;
    }
}
JavaScript
function maxSubarraySum(arr, k) {
    let n = arr.length;
    if (n < k) return -1;

    // compute sum of first window
    let windowSum = 0;
    for (let i = 0; i < k; i++) {
        windowSum += arr[i];
    }

    let maxSum = windowSum;

    // slide the window
    for (let i = k; i < n; i++) {
        windowSum += arr[i] - arr[i - k];
        maxSum = Math.max(maxSum, windowSum);
    }

    return maxSum;
}

Classical Problems on Sliding Window:

  • Maximum sum in k size subarray
  • XOR of every k size subarray
  • Number of distinct elements in window size k
  • Longest subarray with at most two distinct integers
  • Count subarrays with sum = X (positive a[i])
  • Maximum consecutive ones after at most k flips
  • Count subarrays with k odd numbers
  • Count subarrays with at most k distinct elements
  • Minimum removals to make target sum
  • Smallest window containing all characters of another string
  • Count substrings with exactly k distinct characters
Comment