Irbisa · Cheatsheet
Live Coding Round in Swift
Big O, hashing, stacks and queues, two pointers, sliding window, binary search, linked lists, trees, LRU cache, heaps and DP in Swift
What is Big-O notation, and how do you state the time and space complexity of your solution in a coding round?
How does a
Setor aDictionaryturn two-sum, duplicate detection or an anagram check from O(n²) into O(n) in Swift?func hasDuplicate(_ xs: [Int]) -> Bool { var seen = Set<Int>() for x in xs { if !seen.insert(x).inserted { return true } // inserted is false for a repeat } return false…How do you implement a stack and a queue in Swift, and why is
Array.removeFirst()a poor way to dequeue?struct Stack<Element> { private var items: [Element] = [] mutating func push(_ x: Element) { items.append(x) } // amortized O(1) mutating func pop() -> Element? { items.popLast() } // O(1), nil when empty var top: Element? { items.last } var isEmpty: Bool { items.isEmpty }…Live task: check that a string of brackets like
"([]{})"is balanced. Which structure do you use, and which inputs break a naive solution?func isBalanced(_ s: String) -> Bool { let openerFor: [Character: Character] = [")": "(", "]": "[", "}": "{"] var stack: [Character] = [] for c in s { if "([{".contains(c) { stack.append(c)…Live task: merge two sorted arrays into one sorted array in O(n + m) without calling
sorted(). What are the edge cases?func merge<T: Comparable>(_ a: [T], _ b: [T]) -> [T] { var result: [T] = [] result.reserveCapacity(a.count + b.count) // one allocation var i = 0, j = 0 while i < a.count && j < b.count { if a[i] <= b[j] { // <= takes a's element first on a tie: stable…Live task: write your own
mapandreduceas extensions onSequence. What do generics andrethrowsadd to the signature?extension Sequence { func myMap<T>(_ transform: (Element) throws -> T) rethrows -> [T] { var result: [T] = [] result.reserveCapacity(underestimatedCount) // a lower bound, often 0: only a hint for element in self { result.append(try transform(element))…How do
Dictionary(grouping:by:),reduce(into:)anduniquingKeysWith:solve "group anagrams" and "count words", and why is plainreducea trap here?let words = ["eat", "tea", "tan", "ate", "nat", "bat"] // Group anagrams: the sorted letters are the shared keylet groups = Dictionary(grouping: words) { String($0.sorted()) }// ["aet": ["eat", "tea", "ate"], "ant": ["tan", "nat"], "abt": ["bat"]]…Find the bug: this palindrome check returns the right answer, but takes seconds on a 100,000-character string.
func isPalindrome(_ s: String) -> Bool { var left = 0 var right = s.count - 1 while left < right { let l = s[s.index(s.startIndex, offsetBy: left)] let r = s[s.index(s.startIndex, offsetBy: right)] if l != r { return false } left += 1 right -= 1 } return true}Which algorithm does Swift's
sort()use, is it stable, and how do you sort users by score descending and then by name?import Foundation struct User { let name: String let score: Int}…Live task: merge overlapping time slots like
[1, 3], [2, 6], [8, 10]. Why sort first, and should touching slots such as[1, 3]and[3, 5]merge?func merge(_ slots: [ClosedRange<Int>]) -> [ClosedRange<Int>] { let sorted = slots.sorted { $0.lowerBound < $1.lowerBound } // O(n log n) var result: [ClosedRange<Int>] = [] for slot in sorted { if let last = result.last, slot.lowerBound <= last.upperBound { // overlaps or touches the last merged slot: extend it, keeping the later end…How do the two-pointer and sliding-window techniques turn an O(n²) scan into O(n)? Show it on the longest substring without repeating characters.
// Two pointers on a sorted array: indices of a pair with the given sum, O(n)func pair(in sorted: [Int], sum target: Int) -> (Int, Int)? { var l = 0, r = sorted.count - 1 while l < r { let sum = sorted[l] + sorted[r] if sum == target { return (l, r) }…This binary search crashes on some inputs and never returns on others. What is wrong with it, and which loop invariant makes it correct?
func indexOf(_ target: Int, in a: [Int]) -> Int? { var lo = 0 var hi = a.count while lo <= hi { let mid = (lo + hi) / 2 if a[mid] == target { return mid } if a[mid] < target { lo = mid } else { hi = mid - 1 } } return nil}Live task: reverse a singly linked list in place. Follow-up: can freeing a million-node list overflow the stack in Swift, and what about a deep tree?
final class Node<T> { var value: T var next: Node? init(_ value: T, next: Node? = nil) { self.value = value self.next = next…How do you traverse a binary tree depth-first and breadth-first in Swift, and which one fits "max depth" and which "level order"?
final class TreeNode { let val: Int var left: TreeNode? var right: TreeNode? init(_ val: Int, _ left: TreeNode? = nil, _ right: TreeNode? = nil) { self.val = val…Live task: implement an LRU cache with O(1)
getandput. Which two structures do you combine, and why is aDictionaryalone not enough?final class LRUCache<Key: Hashable, Value> { private final class Node { let key: Key? // nil only in the two sentinels var value: Value? var next: Node? weak var prev: Node? // weak: neighbours must not retain each other…How do you recognise a dynamic programming problem, and how do you go from plain recursion to memoization to a bottom-up table in Swift?
// House robber: the most money from houses 0...i without robbing two neighbours.// best(i) = max(best(i - 1), best(i - 2) + nums[i]): skip house i, or rob it // 1. Plain recursion: O(2^n), the same i is solved again and againfunc robNaive(_ nums: [Int], _ i: Int) -> Int { if i < 0 { return 0 }…Swift's standard library has no heap. How do you find the 100 most frequent words in a large text, and what does each approach cost?
typealias Entry = (word: Substring, count: Int) // A min-heap by count in a plain array: the children of i sit at 2i + 1 and 2i + 2func siftDown(_ heap: inout [Entry], from start: Int) { var i = start while true {…Feature modules declare which modules they depend on. How do you compute a build order with a topological sort, and how does the same pass detect a cycle?
struct CycleError: Error { let stuck: [String] } /// deps[module] lists the modules that must be built before it.func buildOrder(_ deps: [String: [String]]) -> Result<[String], CycleError> { var waitingOn: [String: Int] = [:] // module -> dependencies not built yet var dependents: [String: [String]] = [:] // dependency -> modules waiting for it…