const solve = (nums) => { let left = 0, right = nums.length - 1; while (left < right) { const sum = nums[left] + nums[right]; if (sum === target) return [left, right]; }}
Language Guide

LeetCode in Swift: The Complete Guide for iOS Interviews

Master algorithm patterns in Swift with protocol-oriented problem solving, value types, and idiomatic data structures for Apple platform interviews.

10 min read|

LeetCode in Swift

Protocol-oriented problem solving for iOS interviews

Why Swift for LeetCode

Swift has become a first-class language for coding interviews, especially if you are targeting roles at Apple, Uber, Lyft, Airbnb, or any company with a significant iOS codebase. Interviewers at these companies expect candidates to write idiomatic Swift, not just translated Java or Python.

Beyond employer relevance, Swift offers genuine advantages for algorithmic problem solving. Its strong type system catches errors at compile time, optionals force you to handle edge cases explicitly, and value types like structs and enums make your data flow predictable.

Protocol-oriented programming — Swift's signature paradigm — also maps well to algorithmic thinking. You can define protocols for graph nodes, tree traversals, or custom comparators and compose solutions cleanly. If you already write Swift for work or side projects, solving LeetCode in Swift reinforces the same mental models you use daily.

ℹ️

Did You Know

Swift is the primary language for iOS, macOS, and Apple platform development. Apple, Uber, Lyft, and Airbnb conduct Swift-based technical interviews for mobile engineering roles.

Setting Up Swift for LeetCode

The fastest way to start solving LeetCode in Swift is directly on the LeetCode website. Select "Swift" from the language dropdown on any problem page and you are ready to go — no local setup required. LeetCode compiles Swift 5.x, so you have access to modern language features.

For local development, Xcode Playgrounds offer a great interactive environment. Create a new playground (File → New → Playground), and you get instant feedback as you type. This is especially useful for experimenting with data structures or tracing through an algorithm step by step.

If you prefer a lightweight option, the Swift REPL in Terminal works well for quick tests. Run `swift` in your terminal on macOS to launch an interactive session. For larger solutions, create a `.swift` file and run it with `swift myfile.swift` — no project or Xcode required.

  • LeetCode.com — select Swift from language dropdown, supports Swift 5.x
  • Xcode Playgrounds — interactive, visual feedback, great for prototyping
  • Swift REPL — lightweight terminal-based option for quick experiments
  • Swift Package Manager — for organizing larger solution sets with dependencies

Swift Data Structures You Need to Know

Swift's standard library gives you strong built-in collections, but there are notable gaps compared to Java or Python that you need to plan around. Knowing what is available — and what you will need to build yourself — saves precious interview minutes.

Array is your workhorse. It supports O(1) append, O(1) random access, and works as a stack with `append()` and `popLast()`. For queue behavior, removing from the front with `removeFirst()` is O(n), so for BFS-heavy problems you may want a simple index-based queue or a custom Deque.

Dictionary and Set are hash-based and give you O(1) average lookups. Use Dictionary for frequency counting, grouping, and memoization. Set handles deduplication and membership checks. Both are generic, so you get full type safety.

The biggest gap is the lack of a built-in PriorityQueue or Heap. For problems like "Top K Frequent Elements" or Dijkstra's algorithm, you will need to implement a basic binary heap or use a sorted approach. Practice writing a MinHeap struct before your interview — it takes about 30 lines and is worth memorizing.

  • Array — stack operations, random access, sorting with custom comparators
  • Dictionary — frequency maps, memoization tables, adjacency lists
  • Set — deduplication, membership checks, set operations (union, intersection)
  • No built-in PriorityQueue — implement a binary heap or use sorted insertion
  • ArrayDeque (Swift 5.9+) — double-ended queue, but check LeetCode support
⚠️

Watch Out

Swift has no built-in PriorityQueue. For heap-based problems, implement a simple binary MinHeap or MaxHeap struct. Practice this before your interview — it is a common stumbling block for Swift candidates.

Swift-Specific Patterns for Problem Solving

Swift's language features enable patterns that do not exist in other languages. Learning to use these idioms makes your solutions shorter, safer, and more impressive to interviewers who know Swift.

Optionals are your best friend for null-safety patterns. Instead of checking `if node != nil` everywhere, use optional binding (`if let`, `guard let`) to unwrap safely. For tree problems, this eliminates entire classes of null-pointer bugs and makes recursive base cases clean.

Enums with associated values are powerful for representing problem states. You can model a graph node as `enum Node { case leaf(Int); case branch(Node, Node) }` or use enums to represent directions, states, or moves in BFS/DFS problems.

Protocol extensions let you add default implementations to types. Define a `protocol Comparable` extension for custom sorting, or use protocol-oriented design to make your solution reusable across similar problems. Interviewers notice when candidates use Swift idiomatically rather than writing Java-in-Swift.

  1. 1Use guard let for early returns — cleaner than nested if-let chains
  2. 2Leverage tuple returns for problems that need multiple values (e.g., min and max)
  3. 3Use closures with sorted(by:), filter, map, and reduce for concise transformations
  4. 4Define typealiases for complex types: typealias Graph = [Int: [Int]]
  5. 5Use defer for cleanup in problems with resource management

Common Algorithm Patterns Implemented in Swift

The core algorithm patterns — two pointers, sliding window, BFS, DFS, dynamic programming, and backtracking — translate well into Swift. The key is knowing the idiomatic way to express each pattern.

For two pointers on a sorted array, use `var left = 0; var right = nums.count - 1` and move them toward each other with a while loop. Swift arrays are value types, so passing them to helper functions creates copies — use `inout` if you need to modify in place.

BFS in Swift uses an Array as a queue. While `removeFirst()` is O(n), for most interview problems the input size makes this acceptable. If performance matters, track a `head` index instead of removing. Build adjacency lists with `var graph: [Int: [Int]] = [:]` and populate with `graph[node, default: []].append(neighbor)`.

Dynamic programming with memoization uses a Dictionary. Define `var memo: [String: Int] = [:]` (or use a tuple-based key) and check `if let cached = memo[key] { return cached }` before computing. Swift's strong typing means your memo table catches key-type mismatches at compile time.

Backtracking follows the standard explore-choose-unchoose pattern. Use `inout` arrays for the current path to avoid copying overhead, and append/removeLast for stack-based state management.

💡

Pro Tip

Use Swift's default dictionary values to simplify graph building and frequency counting: graph[node, default: []].append(neighbor) and freq[char, default: 0] += 1. This eliminates nil-checking boilerplate.

Swift Gotchas That Trip Up LeetCode Candidates

Swift has several quirks that catch developers off guard during timed interviews. Knowing these in advance prevents wasted minutes debugging language issues instead of solving the actual problem.

String indexing is the biggest gotcha. Swift strings are not random-access — you cannot do `str[3]`. Instead, use `str[str.index(str.startIndex, offsetBy: 3)]` or convert to an Array of Characters first with `Array(str)`. For most interview problems, converting to `[Character]` upfront is the practical choice.

Sorting is another common trap. Swift's default `sorted()` on an array of integers works as expected (numeric order). But if you need a custom comparator, use `sorted(by: { $0 > $1 })` for descending. Be careful with strings — Swift sorts them lexicographically by Unicode scalar value, which is usually what you want but occasionally surprises.

Value types versus reference types matter for trees and linked lists. TreeNode and ListNode in LeetCode are defined as classes (reference types), so mutations propagate as expected. But if you define your own data structures as structs, copies will be created on assignment. Use classes for node-based structures and structs for everything else.

  • String indexing — convert to [Character] array for O(1) random access
  • No built-in PriorityQueue — implement your own binary heap
  • Value vs reference types — use classes for TreeNode/ListNode, structs for data
  • Integer overflow — Swift crashes on overflow by default; use &+ for wrapping arithmetic
  • Array.removeFirst() is O(n) — use index tracking for performance-critical BFS

10 Must-Solve LeetCode Problems in Swift

These ten problems cover the core patterns you will encounter in iOS and general software engineering interviews. Solve each one in Swift, paying attention to the language-specific implementation notes.

Start with Two Sum (#1) to practice Dictionary-based lookups — the classic `complement = target - num` pattern. Then move to Valid Parentheses (#20) for stack fundamentals using Array's `append` and `popLast`. These build your Swift muscle memory for the collections API.

Merge Two Sorted Lists (#21) and Reverse Linked List (#206) test your comfort with reference-type ListNode manipulation in Swift. Binary Tree Level Order Traversal (#102) combines BFS with Swift arrays as queues — practice the `removeFirst` vs index-tracking tradeoff here.

For intermediate patterns, solve Number of Islands (#200) with DFS using `inout` grid mutation, Coin Change (#322) with Dictionary-based memoization, and Top K Frequent Elements (#347) where you will need either a custom heap or a bucket sort approach in Swift.

Round out your practice with Longest Substring Without Repeating Characters (#3) for sliding window with a Dictionary-based character index map, and Course Schedule (#207) for graph cycle detection using an adjacency list built with Dictionary's default subscript.

  1. 1Two Sum (#1) — Dictionary complement lookup, O(n) time
  2. 2Valid Parentheses (#20) — Array as stack with append/popLast
  3. 3Merge Two Sorted Lists (#21) — ListNode reference manipulation
  4. 4Reverse Linked List (#206) — iterative pointer swapping in Swift
  5. 5Binary Tree Level Order Traversal (#102) — BFS with Array queue
  6. 6Number of Islands (#200) — DFS with inout grid mutation
  7. 7Coin Change (#322) — bottom-up DP with Array, top-down with Dictionary memo
  8. 8Top K Frequent Elements (#347) — bucket sort or custom heap
  9. 9Longest Substring Without Repeating Characters (#3) — sliding window + Dictionary
  10. 10Course Schedule (#207) — adjacency list with Dictionary default subscript

Study Strategy

Solve each problem twice: once focusing on correctness, once optimizing for idiomatic Swift. Use YeetCode flashcards to review the pattern behind each problem through spaced repetition — recognition beats memorization in interviews.

Ready to master algorithm patterns?

YeetCode flashcards help you build pattern recognition through active recall and spaced repetition.

Start practicing now