Imagine you have two lists and you want to walk through both of them at the same time. At each step you look at one item from each list, apply some simple test, and then decide how to move forward: sometimes you step forward in both lists, and sometimes you step forward in only one. This idea of "walk through more than one array together, and move based on what you find" is called the simultaneous traversal technique.
It works best on a small family of (usually easy) problems that share one shape:
> Template: Given two arrays, traverse both at once based on the result of some function applied to items from both arrays.
Most of these problems use exactly two arrays, but some can use more.
s a subsequence of t?We are given two arrays (here, arrays of characters):
s = a, b, ct = h, a, e, b, h, c, fWe must answer: is s a subsequence of t?
A *subsequence* means: can we find all the letters of s inside t, in the same order, without rearranging them? The letters do not need to be next to each other in t — other letters may sit between them. We just need a, then later a b, then later a c.
Looking at t, the a is at position 1, a b is at position 3, and a c is at position 5. They appear in the right order, so the answer is True. (The skipped letters h, e, h, f simply don't matter.)
The most natural first attempt is to handle one letter of s at a time:
s (here a).t from the start until you find that item.s (b), and keep walking through t from where you stopped — never restart from the beginning.s this way, return true. If you run off the end of t while letters of s still remain, return false.In code, this uses an outer loop over s and an inner loop that scans t:
bool isSubsequence(vector<char>& s, vector<char>& t) {
int j = 0;
// Traverse each element of array `s`
for(int i=0; i<s.size(); i++) {
if(j == t.size()) {
return false;
}
// Store current element of `s`
char item = s[i];
// Traverse `t` and look for `item` in `t`
while (j < t.size()) {
if(item == t[j]) {
j++;
break;
}
j++;
}
}
}
Notice that j (the position in t) is declared outside the loops, so each search for the next letter continues from where the last one ended. This actually already walks through both arrays together — but with a loop inside a loop, an item variable, and a break, it is fiddly and easy to get wrong.
The same problem fits our template neatly, and the result is much simpler. Keep one pointer in each array:
index1 → current position in sindex2 → current position in tNow apply one rule on every step:
> Compare s[index1] and t[index2].
> - If they match, move forward in both arrays (index1++ and index2++) — we found this letter, so look for the next one.
> - If they don't match, move forward in only t (index2++) — keep searching t for the current letter of s.
Walking through s = a,b,c and t = h,a,b,e,h,c,f:
a vs h → no match → move only in ta vs a → match → move in bothb vs b → match → move in bothc vs e → no match → move only in tc vs h → no match → move only in tc vs c → match → move in bothNow index1 has gone past the end of s. s is fully traversed, so s is a subsequence of t → True.
// pointer for s
int index1 = 0;
// pointer for t
int index2 = 0;
while (index1 < s.length() && index2 < t.length()) {
if (s[index1] == t[index2]) {
// If the current character matches, move the pointer for s
index1++;
}
// Move the pointer for t in every iteration
index2++;
}
The loop stops when either pointer reaches the end. If index1 reached the end of s, every letter was found and the answer is true; otherwise t ran out first and the answer is false.
This version does exactly the same work as the brute-force version, but it is cleaner, easier to read, and less error-prone — no inner loop, no break, no temporary item.
The lesson is not really about subsequences — it's about recognizing a *pattern*. Whenever a problem says "given two (or more) arrays, compare items and step through them based on the result," reach for simultaneous traversal. Other easy problems that fit the same shape include:
Once you can spot the pattern, all of these become small variations on "two pointers, one comparison, move one or both."