Reading

Arrays and Immutable Strings

Understand the JavaScript operations beneath array and string interview solutions.

50 min 4 objectives
Learning objectives
  • Explain the cost of common array operations
  • Avoid numeric sorting and mutation traps in JavaScript
  • Work safely with immutable strings
  • Select an iteration style that matches the needed information

Arrays are indexed sequences with tradeoffs

An array gives each element a numbered position. Reading values[i] is constant time because the position directly identifies the slot. Work at the end is usually cheap; work at the front or middle often moves everything after it.

OperationTypical costReason
arr[i] read/writeO(1)direct position
push / popamortized O(1)changes the end
shift / unshiftO(n)remaining elements move
includes / indexOfO(n)may scan all elements
slice / spreadO(n)creates and fills a copy
sortO(n log n)comparison sorting

Dynamic arrays occasionally need a larger backing store. That is why push is described as amortized rather than worst-case O(1): one append may trigger a copy, but a long series of appends still averages constant work per operation.

Mutation versus copying

JavaScript methods do not all behave alike:

  • sort, reverse, splice, push, and pop mutate the array.
  • slice, map, filter, and spread create new arrays.

Mutation is useful when a problem requires O(1) auxiliary space, but it can surprise a caller that expected the original input to remain intact. State your choice explicitly.

Strings are values, not editable character arrays

You can read text[i], but you cannot assign a character back into the string. Operations such as slice, toLowerCase, and concatenation produce new strings.

Repeated result += character can create and copy a growing string many times. Modern engines optimize some cases, but an interview analysis should not depend on an invisible optimization. For predictable linear construction, collect pieces and join once:

Code
function alternatingCase(input: string): string {
  const parts: string[] = []
  for (let i = 0; i < input.length; i += 1) {
    parts.push(i % 2 === 0 ? input[i].toUpperCase() : input[i].toLowerCase())
  }
  return parts.join("")
}

Choose the loop by the information you need

Use for...of when values are enough. Use an index loop when you need neighbors, positions, two moving boundaries, or an index in the answer.

Longest Common Prefix (LeetCode #14) gives an array of strings and asks for the longest starting substring shared by all of them. A column-by-column scan needs both the character position and each word:

Code
function longestCommonPrefix(words: string[]): string {
  if (words.length === 0) return ""

  for (let column = 0; column < words[0].length; column += 1) {
    const expected = words[0][column]
    for (let row = 1; row < words.length; row += 1) {
      if (column >= words[row].length || words[row][column] !== expected) {
        return words[0].slice(0, column)
      }
    }
  }
  return words[0]
}

If there are w words and the shortest relevant prefix has length k, the scan is O(w · k). Describing it as O(n) hides the two dimensions.

Character codes and alphabets

character.charCodeAt(0) - 97 maps lowercase English a..z to 0..25. A fixed array of 26 counts can be faster and simpler than a Map only when the input contract really guarantees that alphabet. Unicode text, uppercase letters, punctuation, or emojis make that assumption incorrect. General solutions should prefer a Map unless constraints justify the fixed alphabet.

Common mistakes

  • Calling shift() repeatedly to simulate a queue and accidentally creating O(n²) work.
  • Mutating a caller’s array through sort() or reverse() without acknowledging it.
  • Forgetting the comparator for numeric sorting.
  • Treating strings as mutable arrays.
  • Using for...of and then searching again for an index you could have retained.
Checkpoint

Price the operations

Explain the cost and mutation behavior of push, shift, slice, sort, and string concatenation. Then explain why the prefix scan stops at the first mismatch.