Ask what a string is and the quick answer is: “an array of characters.” That answer is true. It explains why the string exercises on this site yield to techniques you already know: two pointers, sliding windows, stacks. It also leaves out the part that causes string problems to bite. A string is an array of bytes, and a stack of agreements - the encoding, the language’s string type, the terminal, the font - decides what those bytes mean. This article covers both sides: the array framing that makes the Strings category tractable, and the “stack of agreements” that separates a string from an array.
A string is an array, so array techniques transfer
For algorithm problems, the quick answer works. A string is a sequence. Every technique that walks a sequence can walk a string:
- Two pointers. Reverse String is one pointer at each end, swapping inward. Palindrome checking is the same move with an equality test instead of a swap.
- Sliding window. A window of start and end pointers slides over the string, and the substring it frames is the unit of the answer. The site’s Longest Substring Without Repeating Characters is the canonical shape: grow the window while the substring stays duplicate-free, shrink it the moment a repeat enters, track the widest.
- The stack. Nesting problems are string problems wearing brackets. Valid Parentheses pushes opens and pops on closes; the stack is the memory of what is still open.
If you can walk an array, you can walk a string. The two seeded string exercises use exactly that idea. Length of Last Word looks trivial until trailing spaces appear: scan from the end, skip the spaces, then count the word. The trap is the boundary. The spaces belong to the string, and a naive “split on space and take the last element” hits the empty element produced by trailing spaces. Longest Substring Without Repeating Characters is the sliding window with a seen-set that tells you when a repeat enters the frame. Both are array problems wearing quotes.
The difference: a string is bytes plus a stack of agreements
This is where a string stops being just an array. A number is a number. The byte
0x41 means the letter A only because everyone agreed that it does - and that agreement is not universal. ASCII and UTF-8 say 0x41 is A; EBCDIC, the encoding IBM shipped on the System/360, says 0x41 is an unassigned gap between two non-contiguous runs of letters. One byte. Two possible meanings, depending on the agreement in force.
That pattern runs through strings. A string is data plus a stack of agreements, with each layer interpreting it. The encoding decides which numbers map to which characters. The language’s string type decides whether you index bytes, code units, or code points. The terminal decides which bytes are text and which are control commands. The font decides which characters become which glyphs - and one character can be two glyphs (a ligature), or several characters can be one glyph (an emoji). A string bug appears when two layers disagree: mojibake is bytes drawn under the wrong encoding’s agreement, and an emoji counted wrong is a code-unit index reading a code-point-length string.
The gotcha that actually bites: “length” is three numbers
The practical consequence is simple: the length of a string is not one number. The three candidates disagree as soon as the string leaves plain ASCII:
-
Code units are the storage cells the language hands you. JavaScript
counts these, which is why
'😂'.lengthis2- the emoji is one character stored as two UTF-16 code units. - Code points are the abstract characters, one number each. The emoji is one code point.
-
Graphemes are what a human sees as “one character”. An emoji family
'👨👩👧👦'is seven code points and11code units in JavaScript, but one grapheme - one visible symbol.
For the problems on this site, the distinction is mostly harmless. The seeded strings stay in the ASCII-adjacent range where all three numbers agree. Know the distinction anyway. The reason is the same one the Real numbers article gives for teaching that floats are not reals: the machine’s model of a thing and your mental model of it can differ. Once the input includes an emoji, an accented letter, or a non-Latin script, that difference is no longer academic.
The other gotcha: strings are often immutable
There is one more practical difference from arrays, and it changes the complexity of obvious code. In JavaScript and Elixir, a string cannot be mutated in place. “Append a character” is not “write one byte”; it is “copy the whole string and add the character”. Build a string one character at a time in a loop and the cost is : each append copies everything built so far. Collect the pieces in an array (which can grow cheaply) and join once at the end. The array is the working buffer; the string is the frozen result. Elixir makes the same point with binaries: append via a list of chunks and IO.iodata_to_binary/1, not by repeated concatenation.
This is the string form of a lesson the whole site is built on: the representation of a value determines which operations are cheap. An array is mutable and its append is ; a string is immutable and its append is . Use the array as scratch space and the string as the answer. That representation choice separates a solution that finishes from one that times out.
Why this matters here
The Strings category is small on purpose - two seeded problems - because strings are not a separate technique. They are arrays with a stack of agreements on top. The technique is borrowed: two pointers, sliding window, stack. String immutability and indexing are the new wrinkles. The Encoding article explains how a sequence of simple cells comes to mean something complicated. A string works the same way: bytes, plus a decision about what they stand for.
Where to go next
- Length of Last Word - the trailing-space boundary, in the grader.
- Longest Substring Without Repeating Characters - the sliding window over a string.
- Valid Parentheses - the string-plus-stack nesting shape.
- Two pointers - the walk that string reversal and palindromes use.
- The encoding - how a sequence of simple cells means something complicated - the idea a string is built on.
- Real numbers - the same “the machine’s model is not your model” honesty, applied to floats.
A string is an array of characters as long as everyone agrees on what a character is. The algorithm skill comes from arrays; the string-specific skill is spotting which agreement is in force and where the next one - the encoding, the index, the terminal - could disagree.