Everyone Can Learn Program
中文 Start learning
Core · AlgorithmsLesson 2 of 8Free to read

Two pointers and sliding windows · Data Structures and Algorithms

How do you solve list problems in one pass?

Course contents

Why you need it

A big share of interview problems are about lists (arrays): pairs that add up to a target, reversing, removing duplicates from a sorted list. Two patterns, two pointers and the sliding window, turn many O(n²) brute-force answers into O(n).

The intuition

Two pointers: put one index at each end of a sorted list. If the pair's sum is too small, move the left one right; too big, move the right one left. Each step throws away one candidate, so it takes n steps at most.

Sliding window: to look at every run of k neighbours, don't re-add all k numbers each time. Slide: add the number that enters, subtract the one that leaves.

Definition

Two pointers

Two indexes that move toward each other (or in the same direction) so each element is visited once.

Sliding window

A range [left, right) over the list that moves forward, updating a running total instead of recomputing it.

Examples

Pair with a target sum

Try it yourself

The list is sorted, so we can squeeze from both ends.

def pair_sum(xs, target):
    left, right = 0, len(xs) - 1
    while left < right:
        total = xs[left] + xs[right]
        if total == target:
            return (xs[left], xs[right])
        if total < target:
            left += 1
        else:
            right -= 1
    return None

print(pair_sum([1, 3, 4, 6, 9, 11], 13))
Step by step
  1. L2Start at both ends: 1 and 11.
  2. L71 + 11 = 12 is too small: move left.
  3. L103 + 11 = 14 is too big: move right.
  4. L133 + 9 = 13.(3, 9)

Best 3-day total

Try it yourself

Sales per day; find the best run of 3 days. The window slides one day at a time.

sales = [4, 2, 7, 1, 8, 3, 5]
k = 3
window = sum(sales[:k])
best = window
for i in range(k, len(sales)):
    window += sales[i] - sales[i - k]
    best = max(best, window)
print(best)
Step by step
  1. L3First window: 4 + 2 + 7 = 13.
  2. L6Add the day that enters, subtract the day that leaves.
  3. L8Windows: 13, 10, 16, 12, 16. Best is 16.16

Common mistakes

Two pointers on an unsorted list

The squeeze only works because the list is sorted. Unsorted? Sort first (O(n log n)) or use a set (next lesson).

Off-by-one

range(k, len(xs)) and xs[i - k] must line up. Trace the first two steps by hand.

Quick quiz

1. What does this print?

xs = [1, 2, 3, 4, 5]
left, right = 0, len(xs) - 1
while left < right:
    xs[left], xs[right] = xs[right], xs[left]
    left += 1
    right -= 1
print(xs)
  1. A
    [5, 4, 3, 2, 1]
  2. B
    [1, 2, 3, 4, 5]
  3. C
    [5, 2, 3, 4, 1]
Show the answer

Answer: A

Swap the ends and move inward: this reverses the list in place.

2. Sliding a window of k over n numbers, how many additions does the running-total method need?

  1. AAbout n
  2. BAbout n × k
  3. CAbout k
Show the answer

Answer: A

k for the first window, then one add and one subtract per step: O(n).

Practice

3 exercises in three steps: predict what a program prints, change a program to meet a new requirement, then write one from scratch. Your code runs in the browser and is checked the moment you submit.

  1. PredictTrace the pointers

    Type exactly what this program prints.

  2. ModifyRemove duplicates in one pass

    dedupe(xs) gets a sorted list and returns it without repeats. The inner loop scans all of out for every item (O(n²)). Since the list is sorted, a repeat can only equal the last item kept. Use that to make it O(n).

  3. WriteBest window

    Write best_window(xs, k) that returns the largest sum of any k consecutive numbers in xs (assume len(xs) ≥ k ≥ 1). Use a sliding window: O(n).

Practise this lesson

Open the interactive lesson to edit and run these examples and solve the exercises with instant feedback. Free to start, no sign-up.

Interactive lessons open in order. If you have not done the earlier ones yet, you start at the course map.

Terms in this lesson

TermChineseDefinition
Array数组Items stored in order and reached by index; Python's list.
Two pointers双指针Two indexes moving through a list so each item is visited once.
Sliding window滑动窗口A moving range with a running total.