skip to content

Arrays & Strings

Learn contiguous-memory structures from the ground up: how arrays are laid out and indexed, how dynamic arrays grow, how matrices are stored and traversed, and how strings are represented and manipulated across languages. Interviewers probe this layer constantly because almost every coding problem starts from an array or a string, and your reasoning about costs here reveals whether you understand memory, not just APIs.

part ofData structures & algorithmsoverview, primer and where to startread it →
on this pageshow

explore

questions

page 2 of 2

What is the worst-case cost of a single append to a growable character buffer?

level: middleimportance: should knowfreq 58%

basics

~20 s

One append is usually constant time, but the append that finds the buffer full is O(n): it allocates a larger block and copies every buffered character across. Amortized over many appends the total is still O(n).

open as a page

Why does an in-place code-unit swap loop mangle text with emoji or accents?

level: middleimportance: should knowfreq 52%

basics

~20 s

Swapping code units also flips the internal order of multi-unit characters: a surrogate pair comes out low half first and becomes invalid, and a combining accent lands before the letter it belonged to. Correct order-reversal walks grapheme clusters.

open as a page

Why does reading every 16th value of a contiguous capture buffer take nearly as long as reading all of them?

level: middleimportance: should knowfreq 42%

basics

~20 s

Memory is fetched in whole cache lines, not single values. A 16-element stride over 4-byte values lands on a new line every step, exactly as many lines as the full scan touches, so traffic is unchanged and only the arithmetic gets cheaper.

open as a page

Removing one element from an array: when may you swap with the last instead of shifting?

level: middleimportance: should knowfreq 50%

basics

~20 s

Only when the array's order carries no meaning. Swapping the last element into the vacated slot is constant time but permutes the array; shifting the tail left costs Θ(n − i) and is the only order-preserving option.

open as a page

Why must Rabin-Karp compare symbols after two window hashes turn out to be equal?

level: middleimportance: should knowfreq 58%

basics

~20 s

Equal hashes do not mean equal text. The hash compresses m symbols into one bounded value, so different windows can collide. Rabin-Karp treats a hash match as a candidate only and confirms it with an O(m) comparison.

open as a page

In expand-around-center symmetry checks, why are there 2n-1 centers rather than n?

level: middleimportance: should knowfreq 48%

basics

~20 s

Odd-length symmetric spans center on a character; even-length spans center between two characters. That is n on-character centers plus n-1 gaps, so 2n-1 in total, and scanning only the n characters misses every even-length span.

open as a page

Before a bulk load, what does pre-allocating a growable array's capacity actually buy you?

level: seniorimportance: should knowfreq 44%

basics

~20 s

Pre-allocating removes the repeated allocate-copy-release cycles during the load: fewer allocator round-trips, no moment holding two blocks at once, no growth-driven invalidation, and a flatter latency profile. It does not change the asymptotic cost of appending n elements.

open as a page

Why does a log-ingest service see p99 append spikes even though appends are amortized O(1)?

level: seniorimportance: should knowfreq 47%

basics

~20 s

Amortized O(1) bounds the total cost of a run of appends, not any single one. The appends that trigger growth copy the whole buffer, and those copies get slower as it grows — exactly the rare stalls a p99 measures.

open as a page

When is swap-with-last array removal wrong despite costing only O(1) per element?

level: seniorimportance: should knowfreq 44%

basics

~20 s

Swap-with-last removal teleports the final live element into the hole, destroying the relative order of what remains. It is wrong whenever a consumer depends on that order — an arrival-ordered log, or any downstream search assuming sortedness.

open as a page

For a spreadsheet-like grid, when does one flat buffer beat an array of separate row arrays?

level: seniorimportance: should knowfreq 45%

basics

~20 s

One flat buffer wins when whole-grid passes dominate: a single allocation, contiguous scans, no per-access indirection. Separate row arrays win when the structure changes at row granularity — reordering, inserting or sharing rows costs a handle move instead of copying every cell.

open as a page

When joining thousands of text fragments into one document, why compute the total length first?

level: seniorimportance: should knowfreq 44%

basics

~20 s

Summing the fragment lengths first lets you allocate the result exactly once and fill it in one pass: no reallocation copies, no slack, no growth pause. A growable buffer ties asymptotically but loses on peak memory and tail latency.

open as a page

Why is a byte offset into UTF-8 O(1) but a character offset not?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Bytes are fixed size, so byte N is one address computation away. Characters are not: UTF-8 spends one to four bytes each, so reaching the Nth character means scanning from a known boundary — O(n) unless you keep an index.

open as a page

In a log pipeline, when does interning repeated strings pay off — and when does the table become the leak?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Interning keeps one canonical instance per distinct value, so it pays when cardinality is small and bounded while occurrences are enormous. It backfires on high-cardinality fields: the table retains every distinct value forever, turning short-lived garbage into a permanent leak.

open as a page

A teammate calls your fixed-capacity array of 16-bit sensor samples primitive and says hardware bounds-checks it for free — how do you defend the design and correct the claim?

level: seniorimportance: should knowfreq 35%

basics

~20 s

A fixed-capacity contiguous buffer gives a provable memory budget, no allocation in the hot path, and O(1) indexing — exactly what a constrained device needs. The hardware claim is false: memory protection is page-granular, so most out-of-bounds accesses land in mapped memory and trap nothing.

open as a page

A diff inserts each match result into a sorted score array per event — what do you flag in review?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Each insert opens a hole mid-array, so it costs linear time in the scores already stored. Across m events that compounds to quadratic total work — invisible at fifty players, a stall at fifty thousand.

open as a page

When is KMP not worth using over a naive substring scan in production?

level: seniorimportance: should knowfreq 45%

basics

~20 s

On varied text with short patterns a naive scan already runs close to linear with a tighter inner loop, so KMP's table build and extra memory rarely pay off. Pay for it when inputs are repetitive or attacker-chosen.

open as a page

Rabin-Karp is quoted as expected O(n+m) — what input forces O(n*m), and how do you defend against it?

level: seniorimportance: should knowfreq 46%

basics

~20 s

Any input that makes a fingerprint hit fire at nearly every offset forces an O(m) confirmation each time, giving O(n*m). Either an attacker crafts collisions against your fixed hash parameters, or the pattern genuinely occurs almost everywhere.

open as a page

What normalization rules must an anagram check agree on before any code is written?

level: seniorimportance: should knowfreq 38%

basics

~20 s

State the canonicalization first: case folding, whether whitespace and punctuation are dropped, whether digits count, and which characters are in scope at all. Two phrases are anagrams only relative to that rule, so leaving it unstated leaves the behaviour undefined.

open as a page

Growth factor 2x or 1.5x for a buffer in a service with a hard memory cap — how do you decide?

level: principalimportance: should knowfreq 39%

basics

~20 s

Decide on the transient peak, not the copy count. Both blocks are live during a growth, so 2x peaks near three times the data and 1.5x near two and a half; factors under about 1.618 also permit reuse of freed blocks.

open as a page

Rotating a 10^9-entry memory-mapped log by k: is an O(1)-space in-place rotation the right call?

level: principalimportance: should knowfreq 35%

basics

~20 s

Often not. The cheapest rotation of a huge log is logical: keep a base offset and index modulo n, moving nothing. A physical in-place rotation saves memory but rewrites every page and is not crash-safe.

open as a page

For a quarter-turn board rotation on memory-tight devices, how do you choose in-place cycling over a fresh copy?

level: principalimportance: should knowfreq 38%

basics

~20 s

Ask first whether the original must survive and whether the board is square: those two answers usually decide it outright. Only when peak memory is genuinely the binding constraint is the harder in-place ring cycle worth its review cost, and transpose-plus-reverse is already in-place anyway.

open as a page

In a jagged schedule table with a different slot count per day, which grid operations silently break?

level: middleimportance: nice to knowfreq 28%

basics

~20 s

Anything that treats one row's length as the table's width: column reads, per-column aggregates, transposition, and neighbour lookups. A jagged table has no single column count, so those operations either read past a short row or quietly ignore the tail of a long one.

open as a page

How do you mask the leading digits of a fixed-length record when strings are immutable?

level: middleimportance: nice to knowfreq 34%

basics

~20 s

Copy the record once into a mutable character array, overwrite the digits in place at O(1) each, then convert back once. That is two copies per record instead of one full copy per masked character.

open as a page

The juggling rotation writes each element once — why does three-reversal often still win?

level: seniorimportance: nice to knowfreq 30%

basics

~20 s

Both are O(n) time and O(1) extra space, so asymptotics cannot separate them. Juggling halves the writes but strides through memory in gcd-sized cycles, and those scattered touches cost more than the extra sequential pass reversal pays for.

open as a page

Why can a 10-character substring keep a 2 GB document alive in memory?

level: seniorimportance: nice to knowfreq 28%

basics

~20 s

A substring can be a view — an offset and length over the parent's buffer — rather than a copy. Extraction is then O(1), but the view references the whole parent buffer, so all 2 GB stays reachable while the slice lives.

open as a page

Structure-of-arrays vs array-of-records: why does splitting telemetry records into parallel field arrays speed up a one-field hot loop?

level: seniorimportance: nice to knowfreq 28%

basics

~20 s

One array per field means a loop reading a single field gets only that field's values in each fetched cache line, instead of dragging along every unused field of every record. Fewer lines touched, far less wasted bandwidth, same O(n).

open as a page

Why does KMP suit scanning a non-rewindable byte stream for a fixed signature?

level: seniorimportance: nice to knowfreq 30%

basics

~20 s

KMP's whole state is the prefix table plus the current matched length, and its text pointer never moves backward, so it consumes each byte once, in order, with memory proportional to the signature and a work bound hostile traffic cannot inflate.

open as a page

Should a growable array's capacity ever shrink automatically in a service whose catalog peaks each December?

level: principalimportance: nice to knowfreq 24%

basics

~20 s

It depends on whether holding the December peak actually costs you anything measurable. Shrinking copies survivors into a smaller block and invalidates positions, so any automatic policy needs hysteresis: shrink only far below capacity, and to a size that leaves headroom.

open as a page

Rabin-Karp or a linear-guarantee matcher per pattern: how do you screen submissions against 50,000 known snippets?

level: principalimportance: nice to knowfreq 30%

basics

~20 s

One rolling-hash pass fingerprints every window once and tests it against a set holding all 50,000 snippet fingerprints, so needle count barely touches scan time. A single-pattern matcher per snippet costs 50,000 passes per submission — no latency budget survives that.

open as a page

showing 31–59 of 59