Crash Course to Swift for LeetCode
Already know algorithmic problem solving for another language? Here is what you need to jump start your journey with swift interview coding.
1. Optionals
Why it matters: Linked Lists (ListNode?) and Trees (TreeNode?) rely heavily on optionals. You must know how to unwrap safely.
let num: Int? = 10
let userAge: Int? = nil
// 1. Safe Unwrapping (The Standard)
if let val = num {
print("Value is \(val)")
}
// 2. Guard Let (The Early Exit - Great for functions)
func check(_ n: Int?) {
guard let val = n else { return }
print(val)
}
// 3. Nil Coalescing (The Default Value)
// If userAge is nil, use 0.
let age = userAge ?? 0
2. Dictionaries (Hash Maps)
Why it matters: Essential for frequency maps (Two Sum, Valid Anagram). Swift has a specific trick to avoid "if/else" logic when incrementing counts.
var counts: [String: Int] = [:]
let key = "apple"
// The "Default Value" Subscript
// Instead of checking if key exists, just ask for it with a default of 0.
counts[key, default: 0] += 1
// Extracting Values
let value = counts[key] ?? 0 // Returns nil if key doesn't exist
let allValues = Array(counts.values) // Get all values as array
let allKeys = Array(counts.keys) // Get all keys as array
// Iterating
for (key, value) in counts {
print("\(key): \(value)")
}
3. Sets
Why it matters: Essential for duplicate detection and unique element tracking. O(1) lookups make them perfect for membership tests.
var seen = Set<Int>()
// Add and Check (O(1))
seen.insert(5)
if seen.contains(5) { /* found */ }
// Common Operations
seen.remove(5) // Remove element
seen.isEmpty // Check if empty
seen.count // Get size
// Initialize Set with Values
let set1: Set<Int> = [1, 2, 3]
4. Arrays & Stacks
Why it matters: Swift Arrays define stack behavior (popLast/append). Be careful with removeFirst() as it is O(n).
var stack: [Int] = []
// O(1) Operations
stack.append(5) // Push
let top = stack.popLast() // Pop
// O(n) Operations (Avoid inside loops!)
stack.insert(10, at: 0)
stack.removeFirst()
// Useful Array Operations
let arr = [1, 2, 3, 4, 5]
arr.first // Optional first element
arr.last // Optional last element
arr.isEmpty // Check if empty
arr.count // Get length
5. Strings
Why it matters: Swift Strings enforce Unicode correctness, so integer indexing (str[0]) is forbidden. You must convert to an Array for random access or use Substring methods.
let str = "Swift"
let mixed = "Hello World 123"
// 1. Efficient Slicing (Returns Substring)
let start = str.prefix(3) // "Swi"
let end = str.suffix(2) // "ft"
// 2. Array Conversion (The LeetCode Standard)
// Required for O(1) access patterns (like Two Pointers)
let chars = Array(str)
// now you can do: chars[0]
// 3. Case Conversion
let lower = "Hello".lowercased() // "hello"
let upper = "Hello".uppercased() // "HELLO"
// 4. Common String Operations
str.contains("ift") // Check substring
str.hasPrefix("Swi") // Check prefix
str.hasSuffix("ft") // Check suffix
str.replacingOccurrences(of: "i", with: "y") // Replace
// 5. Splitting
let words = "a b c".components(separatedBy: " ") // ["a", "b", "c"]
let chars2 = Array("abc") // ["a", "b", "c"]
// 6. Filtering Strings
let str = "Hello123!@#"
let alphanumeric = str.filter { $0.isLetter || $0.isNumber }
6. Functional Shorthand
Why it matters: Shows language mastery and keeps code clean during interviews.
let nums = [1, 2, 3, 4, 5]
// Map: Transform
let doubled = nums.map { $0 * 2 }
// Filter: Select
let evens = nums.filter { $0 % 2 == 0 }
// Reduce: Aggregate
let sum = nums.reduce(0, +)
let product = nums.reduce(1, *)
// Sort: Custom Logic (Descending)
let sorted = nums.sorted { $0 > $1 }
7. Ranges & Indexing
Why it matters: Useful for array slicing and creating index ranges for loops. Swift's range syntax is concise and readable.
let arr = [1, 2, 3, 4, 5]
// Array Slicing
let slice1 = arr[0..<3] // [1, 2, 3] (exclusive end)
let slice2 = arr[0...2] // [1, 2, 3] (inclusive end)
let slice3 = arr[2...] // [3, 4, 5] (from index to end)
// Ranges for Loops
for i in 0..<arr.count { }
for i in stride(from: 0, to: 10, by: 2) { } // 0, 2, 4, 6, 8
for i in stride(from: 10, through: 0, by: -1) { } // Reverse