← Back to books

Chapter 1: How to Use This Book


"I failed my first coding interview spectacularly. I knew Swift inside out, had shipped multiple apps to the App Store, but when they asked me to reverse a linked list, my mind went blank. The problem wasn't my coding ability—it was that I'd never learned the patterns."

— A senior iOS developer at a FAANG company


Who This Book Is For

This book is written for mobile developers—iOS engineers fluent in Swift and Android engineers proficient in Kotlin—who want to ace their next coding interview without wading through solutions written in Python or Java.

You might be:

  • A senior mobile developer with years of production experience who hasn't touched algorithm problems since college
  • A mid-level engineer looking to break into top-tier companies like Google, Apple, Meta, or Netflix
  • A self-taught developer who learned mobile development through building apps but never formally studied data structures and algorithms
  • An experienced programmer switching between iOS and Android who wants to see idiomatic solutions in both languages

This book assumes you already know how to code. You understand variables, functions, classes, and basic object-oriented programming. What you might lack is the specific vocabulary and mental frameworks that interviewers expect. That's exactly what we'll build together.

This book is not for absolute beginners. If you've never written a for loop or don't understand what an array is, start with a fundamentals course first. Come back when you can comfortably build a simple app.


How Coding Interviews Actually Work

Before we dive into patterns and problems, let's demystify what actually happens in a coding interview. Understanding the game helps you play it better.

The Typical Format

Most technical interviews at major companies follow a predictable structure:

Duration: 45-60 minutes

Breakdown:

  • 5 minutes — Introductions and small talk
  • 5 minutes — Problem presentation and clarification
  • 25-35 minutes — Coding and discussion
  • 5-10 minutes — Your questions for the interviewer

You'll typically face 1-2 problems per session, with 3-5 technical rounds total across your interview loop.

What Interviewers Actually Evaluate

Here's something most candidates misunderstand: getting the correct answer is not enough. Interviewers evaluate you across multiple dimensions:

Problem-Solving Process — Can you break down an ambiguous problem into concrete steps? Do you ask clarifying questions? Do you consider edge cases before diving into code?

Communication — Can you articulate your thinking clearly? Do you explain why you're making certain choices, not just what you're doing?

Coding Ability — Is your code clean, readable, and reasonably efficient? Do you use appropriate data structures?

Testing Mindset — Do you trace through your solution with examples? Do you catch your own bugs before the interviewer points them out?

Collaboration — Are you pleasant to work with? Do you respond well to hints? Would the interviewer want you on their team?

A candidate who gets 80% of the way to a solution while demonstrating excellent problem-solving and communication often outperforms someone who silently produces a correct but messy solution.

The Language Question

"Can I use Swift/Kotlin in my interview?"

Yes. Almost every major company allows you to use your strongest language. Google, Apple, Meta, Amazon, and Netflix all accept Swift and Kotlin. Some companies even prefer that you use your primary language because it demonstrates genuine fluency rather than interview-prep proficiency in Python.

That said, be prepared for follow-up questions about language-specific details. If you use Swift, know the difference between struct and class. If you use Kotlin, understand data class and when to use lazy initialization.

This book gives you solutions in both languages precisely so you can practice in whichever you'll use on interview day.


The Pattern-First Approach Explained

Here's the secret that separates candidates who struggle with every new problem from those who confidently tackle unfamiliar challenges: patterns.

Why Memorizing Solutions Doesn't Work

There are thousands of coding problems on LeetCode. If you try to memorize solutions, you'll face three problems:

  1. Combinatorial explosion — You can't memorize enough solutions to cover every possible variation
  2. Recognition failure — Interviewers often modify classic problems slightly, breaking your pattern matching
  3. Fragile knowledge — Memorized solutions crumble under pressure or when asked follow-up questions

Why Patterns Do Work

Patterns are reusable problem-solving templates. When you learn the "Sliding Window" pattern, you're not memorizing one solution—you're learning a technique that applies to dozens of problems involving contiguous subarrays or substrings.

Consider these three problems:

  1. Find the maximum sum of any contiguous subarray of size k
  2. Find the longest substring with at most k distinct characters
  3. Find the smallest subarray with a sum greater than or equal to target

On the surface, they look different. But they all use the same underlying pattern: Sliding Window. Once you recognize the pattern, the solution structure becomes obvious.

How This Book Teaches Patterns

Each pattern chapter follows a consistent structure:

Pattern Recognition Signals — What keywords or problem characteristics suggest this pattern? When you see "contiguous subarray" or "substring," your brain should immediately think "Sliding Window."

Core Concept — The fundamental idea behind the pattern, explained simply without code first.

Template Code — A reusable code skeleton in both Swift and Kotlin that you can adapt to specific problems.

Variations — Different flavors of the pattern (e.g., fixed-size window vs. dynamic window).

Practice Problems — Carefully selected problems that reinforce the pattern, ordered from easier to harder.

After working through this book, when you encounter a new problem, your thought process will be: "What pattern does this match?" rather than "Have I seen this exact problem before?"


Swift vs Kotlin: A Quick Syntax Comparison

If you're primarily an iOS or Android developer looking to understand solutions in the other language, this section will help you translate concepts quickly.

Variable Declaration

// Swift
let constant = 10        // Immutable
var variable = 20        // Mutable
var name: String = "Ada" // Explicit type
// Kotlin
val constant = 10        // Immutable
var variable = 20        // Mutable
var name: String = "Ada" // Explicit type

Nearly identical. Swift uses let, Kotlin uses val.

Optionals and Nullability

// Swift
var name: String? = nil
let length = name?.count ?? 0
if let unwrapped = name {
    print(unwrapped)
}
// Kotlin
var name: String? = null
val length = name?.length ?: 0
name?.let {
    println(it)
}

Same concepts, slightly different syntax. Swift's if let becomes Kotlin's ?.let.

Collections

// Swift
var array = [1, 2, 3]
var dict = ["a": 1, "b": 2]
var set: Set = [1, 2, 3]

array.append(4)
dict["c"] = 3
// Kotlin
var array = mutableListOf(1, 2, 3)
var dict = mutableMapOf("a" to 1, "b" to 2)
var set = mutableSetOf(1, 2, 3)

array.add(4)
dict["c"] = 3

Swift uses built-in literals. Kotlin uses explicit mutable/immutable collection functions.

Functions

// Swift
func greet(name: String) -> String {
    return "Hello, \(name)"
}

func add(_ a: Int, _ b: Int) -> Int {
    return a + b
}
// Kotlin
fun greet(name: String): String {
    return "Hello, $name"
}

fun add(a: Int, b: Int): Int {
    return a + b
}

Swift uses func and -> for return types. Kotlin uses fun and : for return types.

Closures / Lambdas

// Swift
let doubled = [1, 2, 3].map { $0 * 2 }
let filtered = [1, 2, 3].filter { $0 > 1 }

let sum = [1, 2, 3].reduce(0) { acc, num in
    acc + num
}
// Kotlin
val doubled = listOf(1, 2, 3).map { it * 2 }
val filtered = listOf(1, 2, 3).filter { it > 1 }

val sum = listOf(1, 2, 3).fold(0) { acc, num ->
    acc + num
}

Swift uses $0, $1 for unnamed parameters. Kotlin uses it for single parameters.

Classes and Structs

// Swift
class TreeNode {
    var val: Int
    var left: TreeNode?
    var right: TreeNode?
    
    init(_ val: Int) {
        self.val = val
    }
}

struct Point {
    var x: Int
    var y: Int
}
// Kotlin
class TreeNode(var `val`: Int) {
    var left: TreeNode? = null
    var right: TreeNode? = null
}

data class Point(var x: Int, var y: Int)

Kotlin's primary constructors are more concise. Note that val is a keyword in Kotlin, so we use backticks when it's a property name.

Control Flow

// Swift
for i in 0..<n { }           // 0 to n-1
for i in 0...n { }           // 0 to n
for num in array { }         // for-each
while condition { }
for i in stride(from: 10, to: 0, by: -1) { }  // countdown
// Kotlin
for (i in 0 until n) { }     // 0 to n-1
for (i in 0..n) { }          // 0 to n
for (num in array) { }       // for-each
while (condition) { }
for (i in 10 downTo 1) { }   // countdown

Swift uses ..< and ... for ranges. Kotlin uses until and ...


How to Practice Effectively

Reading this book cover to cover won't make you better at interviews. You need deliberate practice. Here's a strategy that works.

The 3-Phase Approach

Phase 1: Learn the Pattern (Days 1-2 per pattern)

Read the pattern explanation thoroughly. Understand why it works, not just how. Implement the template code yourself without looking. Type it out, don't copy-paste.

Phase 2: Guided Practice (Days 3-5 per pattern)

Work through the problems in order. For each problem:

  1. Read the problem statement
  2. Spend 5 minutes thinking before looking at hints
  3. Try to identify which pattern applies
  4. Attempt a solution for 20-30 minutes
  5. If stuck, read the approach explanation (but not the code)
  6. Try again for 15 minutes
  7. Finally, study the solution and understand every line

Phase 3: Independent Practice (Ongoing)

After completing a pattern chapter, solve 2-3 similar problems on LeetCode without looking at this book. If you can solve new problems using the pattern, you've internalized it.

The Spaced Repetition Secret

Your brain forgets patterns if you don't revisit them. After completing each pattern, schedule review sessions:

  • 1 day later: Solve one problem from the pattern without hints
  • 1 week later: Solve another problem
  • 1 month later: Revisit the hardest problem

This spaced repetition transforms short-term understanding into permanent knowledge.

Time Yourself

Real interviews have time pressure. Once you're comfortable with a pattern, practice under timed conditions:

  • Easy problems: 15 minutes
  • Medium problems: 25 minutes
  • Hard problems: 40 minutes

If you can't solve a medium problem in 25 minutes during practice, you won't solve it in an interview.

Verbalize Your Thinking

Coding silently is comfortable but counterproductive. Practice explaining your thought process out loud as you solve problems. Record yourself if possible. You'll discover gaps in your understanding when you can't articulate a concept clearly.


Common Data Structures: Quick Reference

Before diving into patterns, make sure you're comfortable with these fundamental data structures. Each pattern builds on them.

Data Structure Swift Kotlin Common Operations
Dynamic Array [Int] MutableList<Int> append, access by index, iterate
Hash Map [Key: Value] MutableMap<K, V> insert, lookup, delete in O(1)
Hash Set Set<Int> MutableSet<Int> insert, contains, delete in O(1)
Stack [Int] (use append/popLast) ArrayDeque<Int> push, pop, peek in O(1)
Queue [Int] (inefficient) or custom ArrayDeque<Int> enqueue, dequeue in O(1)
Heap No built-in (use CFBinaryHeap or custom) PriorityQueue<Int> insert, extract-min/max in O(log n)
Linked List Custom implementation Custom implementation insert, delete in O(1) with reference
Binary Tree Custom implementation Custom implementation traversal, search
Graph Adjacency list: [[Int]] Map<Int, List<Int>> BFS, DFS

We'll implement custom structures when needed throughout the book.


Setting Up Your Practice Environment

You don't need anything fancy. Here's a minimal setup that works:

For Swift

Option 1: Xcode Playground Create a new Playground in Xcode. Fast iteration, good for experimenting.

Option 2: Online Use SwiftFiddle or LeetCode's Swift environment.

Option 3: Command Line Create a .swift file and run with swift filename.swift.

For Kotlin

Option 1: IntelliJ IDEA Create a scratch file (Cmd+Shift+N) for quick experiments.

Option 2: Online Use Kotlin Playground or LeetCode's Kotlin environment.

Option 3: Command Line Create a .kt file, compile with kotlinc filename.kt -include-runtime -d output.jar, and run with java -jar output.jar.

Recommended Workflow

  1. Read the problem on LeetCode (don't look at solutions)
  2. Solve it in your local environment with full IDE support
  3. Copy your solution to LeetCode to verify correctness
  4. Compare with this book's solution
  5. Note what you could improve

A Note on Problem Selection

This book covers 88 carefully selected problems—slightly more than the classic "Blind 75" list. Why the expansion?

Some patterns need more than one or two problems to truly sink in. The additional problems aren't filler; they're chosen to expose you to important variations that frequently appear in interviews.

The problems are organized by pattern, not by difficulty. This is intentional. You'll find an easy problem followed by a hard one if they both demonstrate the same pattern. Mastering the pattern matters more than grinding through problems in difficulty order.

If you're short on time, prioritize problems marked with ★ in each chapter. These are the highest-frequency interview questions that offer the best return on your time investment.


What's Next

You now understand how this book works and how to extract maximum value from it. In the next chapter, we'll cover complexity analysis—the language you need to discuss the efficiency of your solutions. Keep it short, keep it practical, and then we'll dive into patterns.

The journey from "I know how to code apps" to "I can solve any coding interview problem" isn't about talent. It's about learning the right patterns and practicing deliberately.

Let's begin.


Continue to Chapter 2: Complexity Analysis Essentials →