String Traversal

RoadmapsDSA

Overview

String traversal is the process of examining or transforming a string character-by-character in a single linear pass. Since strings are essentially arrays of characters, traversal involves moving a cursor across the sequence and updating a state based on the current character.

Naive string manipulation often relies on chained high-level methods (e.g., splitting, replacing, joining) which can cause severe memory bloat and degrade performance to O(N^2) due to repeated memory allocations. A single-pass O(N) traversal requires minimal, constant auxiliary memory.

Where used: UTF-8 decoders parsing byte streams into characters, Validating formatting or executing simple character transformations

Why learn this

Aha moment

# Bad: O(N^2) memory reallocation
result = ""
for char in string:
    if char.isalpha():
        result += char.lower()

# Good: O(N) array join
result_arr = []
for char in string:
    if char.isalpha():
        result_arr.append(char.lower())
result = "".join(result_arr)

Prediction: The first method is simpler and just as fast.

Common guess: String concatenation is a basic O(1) operation in modern languages.

Strings are immutable arrays. You cannot append to them. You have to allocate a entirely new array and copy the old data over. The array-join method allocates a dynamic array once and writes into it, maintaining true linear time.

Common mistakes

Glossary

memory bloat
When a program wastes large amounts of RAM by creating unnecessary copies of data.
immutable strings
Text data that cannot be changed once created; any edit requires building a completely new copy.
mutable structure
A data container designed to let you safely change its contents in place.

Recall questions

Understanding checks

If you need to parse a massive 10GB log file and count the number of error flags, why is a manual line-by-line traversal better than calling `file.read().split('\n')`?

Calling `read().split()` attempts to load the entire 10GB file into RAM simultaneously, crashing the program. A manual line-by-line traversal only keeps a single line in memory at any given time (O(1) auxiliary space).

This demonstrates the difference between high-level abstractions that prioritize developer convenience and low-level traversal that prioritize memory constraints.

You are traversing a string to check if it contains valid brackets. You maintain a `balance` integer, incrementing on `(` and decrementing on `)`. What must be true about this state variable for the string to be valid?

The `balance` must never drop below 0 at any point during the traversal, and it must exactly equal 0 at the very end.

This is a classic state-tracking pattern. It proves that you cannot just count the total number of brackets; the state at every individual step of the traversal matters.

Practice tasks

Count specific characters

Write a function that traverses a string in a single pass and returns the count of vowels.

Continue learning

Previous: Iteration & Traversal

Next: Frequency Arrays

Next: Two Pointers on Strings

Return to DSA Roadmap