Resources
| Resources | |||||
|---|---|---|---|---|---|
| CPH | solutions to the problems above | ||||
| IUSACO | above + mention of max subarray sum | ||||
| CF EDU | video explanation of two pointers | ||||
Two Pointers
The Two Pointers method iterates two pointers across an array to track indices satisfying some condition. There are two common variations:
- Two pointers starting at different ends of the array and moving towards each other.
- Two pointers moving in the same direction at different speeds. This variation is known as the Sliding Window algorithm.
Sum of Two Values
Focus Problem – try your best to solve this problem before continuing!
View Internal SolutionSolution - Sum of Two Values
The "Opposite Ends" method allows us to find the target pair in linear time if the array is sorted. Instead of checking every possible pair (which would take time), we use the sorted property to narrow down the search space in a single pass.
We want to find two indices and such that .
We can start by sorting the array. Then, we can initialize a left pointer at the beginning of the array () and a right pointer at the end ().
While :
- If , we have found the target sum.
- If , the sum is too small. To increase the sum, we increment .
- If , the sum is too large. To decrease the sum, we decrement .
Since the array is sorted, moving the left pointer to the right will never decrease the sum, and moving the right pointer to the left will never increase the sum.
Implementation
Time Complexity:
C++
#include <algorithm>#include <iostream>#include <utility>#include <vector>using namespace std;int main() {int n, x;cin >> n >> x;
Java
import java.io.*;import java.util.*;public class Main {public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));StringTokenizer st = new StringTokenizer(br.readLine());int n = Integer.parseInt(st.nextToken());int x = Integer.parseInt(st.nextToken());
Python
n, x = map(int, input().split())nums = [(int(val), i) for i, val in enumerate(input().split())]nums.sort()l = 0r = n - 1while l < r:sum = nums[l][0] + nums[r][0]if sum == x:
Sliding Window
The Sliding Window method is a variation of the two pointers technique where two pointers move in the same direction to maintain a specific range or "window" of elements. While standard two pointers often move towards each other, the sliding window technique is used to find a contiguous subarray that satisfies a condition.
Focus Problem – try your best to solve this problem before continuing!
Solution - Books
We want to find the longest contiguous segment of books that can be read within minutes.
To accomplish this, we can define and to represent the beginning and end of the segment. Both will start at the beginning of the array. These numbers can be thought of as pointers, hence the name "two pointers."
For every value of in increasing order, let's increase until the total time for the segment is maximized while being less than or equal to .
will store the maximum value of (segment size) that we have encountered so far.
After incrementing by one, the time used decreases, hence the right pointer never has to move leftwards. Thus:
Since both pointers will move at most times, the overall time complexity is .
As an example, consider the first case in the sample inputs:
| Left Pointer | ||||
| 3 | 1 | 2 | 1 | |
| Right Pointer |
We can move the right pointer to index :
| Left Pointer | ||||
| 3 | 1 | 2 | 1 | |
| Right Pointer |
The sum of the values in this range is , and there are values. So, the current maximum segment length is . By incrementing the left pointer by , we can subtract from the sum of values to get . The array then looks like:
| Left Pointer | ||||
| 3 | 1 | 2 | 1 | |
| Right Pointer |
Now, we can move the right pointer to the end. This makes the sum of values and the length of the segment equal to . So, is now .
| Left Pointer | ||||
| 3 | 1 | 2 | 1 | |
| Right Pointer |
Since the right pointer has reached the end of the array, we are done at this point. This leaves us with .
Here's an animation of the above example:
Implementation
Time Complexity:
C++
#include <bits/stdc++.h>using namespace std;int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int N, T;cin >> N >> T;vector<int> A(N);
Java
import java.io.*;import java.util.*;public class Books {public static void main(String[] args) {Kattio io = new Kattio();int N = io.nextInt();int T = io.nextInt();int[] A = new int[N];
Python
N, T = map(int, input().split())A = list(map(int, input().split()))r = -1window_sum = 0 # sum of A[l ... r inclusive]ans = 0for l in range(N):while r + 1 < N and window_sum + A[r + 1] <= T:r += 1window_sum += A[r]ans = max(ans, r - l + 1)window_sum -= A[l]print(ans)
Problems
| Status | Source | Problem Name | Difficulty | Tags | ||
|---|---|---|---|---|---|---|
| CSES | Easy | Show TagsSliding Window | ||||
| CSES | Easy | Show Tags2P, Sorting | ||||
| Silver | Easy | Show Tags2P, Sorting | ||||
| CF | Easy | Show Tags2P, Binary Search | ||||
| CF | Easy | Show Tags2P | ||||
| CF | Normal | Show Tags2P, Sliding Window, Sorting | ||||
| Silver | Normal | Show Tags2P, Sorting | ||||
| Silver | Normal | Show Tags2P, Sorting | ||||
| CF | Normal | Show Tags2P | ||||
| Silver | Normal | Show TagsBinary Search, Prefix Sum, Two Pointers | ||||
Quiz
What is the two pointers algorithm?
Module Progress:
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!