Agoda Staff iOS Engineer Interview Experience — Strong Technical Rounds, Great Discussions, and Key…
Round 1 — The HackerRank Technical Assessment
Agoda Staff iOS Engineer Interview Experience — Strong Technical Rounds, Great Discussions, and Key Learnings

Round 1 — The HackerRank Technical Assessment
The first round of Agoda’s interview process was a timed HackerRank assessment focused on problem solving, algorithmic thinking, and production-quality Swift implementation.
The format was straightforward but intentionally designed to evaluate more than just whether the solution passes test cases. The assessment emphasized engineering maturity — how candidates think about scalability, readability, and trade-offs under time pressure.
Assessment Format
- Duration: 60 minutes
- Language: Swift
- Total Problems: 2 algorithmic problems
- Evaluation Focus:
- Correctness
- Time and space complexity
- Code quality
- Edge-case handling
- Clean implementation style
Unlike many online assessments that purely optimize for speed, this round felt closer to a real engineering exercise.
Problem 1 — Array + HashMap + Tie-Breaking
1. Problem Statement
Given a list of product names representing purchased products, return the product with the highest frequency.
If multiple products have the same frequency:
- Sort alphabetically
- Return the last product alphabetically
2. Example
Input
[
"redShirt",
"greenPants",
"redShirt",
"orangeShoes",
"blackPants",
"blackPants"
]
Output
redShirt
The challenge was really about recognizing the underlying pattern and optimizing repeated computations.
Engineering Approach
Initial Thought Process (Brute Force)
My first thought was:
For every product:
- scan the whole array
- count occurrences
- track maximum frequency
Brute Force Logic
count occurrences using another loop
Problem With This Approach
Repeated scanning happens.
Example:
redShirt count recalculated multiple times
This creates:
O(N²)
time complexity.
Not efficient for:
N = 100000
Optimization Observation
I noticed:
Frequency calculation is repeated work.
Instead of recalculating:
- store frequencies once
- reuse them later
Best structure:
Dictionary / HashMap
because it provides:
O(1)
average lookup/update.
Optimal Approach
Step 1
Create frequency dictionary.
Step 2
Traverse products array.
Update count.
Step 3
Track:
- maximum frequency
- best product during tie
Step 4
If frequency is same: choose alphabetically larger product.
Swift-Specific Decisions
- Used
guardstatements for cleaner control flow - Kept the implementation modular and readable
- Avoided unnecessary temporary arrays
- Focused on predictable memory usage
import Foundation
func mostFrequentProduct(_ products: [String]) -> String {
// Step 1: Frequency Dictionary
var frequency: [String: Int] = [:]
// Step 2: Count frequencies
for product in products {
frequency[product, default: 0] += 1
}
// Step 3: Track answer
var result = ""
var maxCount = 0
// Step 4: Find best candidate
for (product, count) in frequency {
// Higher frequency found
if count > maxCount {
maxCount = count
result = product
}
// Same frequency
else if count == maxCount {
// Pick alphabetically larger
if product > result {
result = product
}
}
}
return result
}
Complexity Analysis
Frequency Counting
O(N)
Dictionary Traversal
O(K)
Where:
N= total productsK= unique products
Overall:
O(N)
Problem 2 — Next Smaller Element Processing Using Monotonic Stack
The second problem focused on array traversal and stack-based optimization.
Problem Statement
For every element in the array, find the first smaller element on the right side.
If a smaller element exists, return the distance between indexes.
Otherwise, return 0.
Example:
nums = [73, 74, 75, 71, 69, 72, 76, 73]
Output = [3, 2, 1, 1, 0, 0, 1, 0]
Initial Thought Process (Brute Force)
The first idea was straightforward:
For every element:
- scan all elements on the right
- stop when a smaller element is found
- calculate distance
import Foundation
func nextSmallerDistanceBruteForce(_ nums: [Int]) -> [Int] {
var result = Array(repeating: 0, count: nums.count)
for i in 0..<nums.count {
for j in (i + 1)..<nums.count {
// Smaller element found
if nums[j] < nums[i] {
result[i] = j - i
break
}
}
}
return result
}
// Example
let nums = [73, 74, 75, 71, 69, 72, 76, 73]
print(nextSmallerDistanceBruteForce(nums))
Problem With Brute Force
Problem With Brute Force
scan remaining array again
scan remaining array again
Complexity
Time Complexity
O(N²)
Space Complexity
O(1)
excluding output array.
Optimization Observation
The repeated scanning was the bottleneck.
Observation:
Some elements are waiting for their next smaller element.
Instead of rescanning:
Core Techniques
- Used a monotonic decreasing stack
- Stored indexes instead of values
- Resolved pending elements when a smaller value appeared
- Processed the array in linear time
import Foundation
func nextSmallerDistance(_ nums: [Int]) -> [Int] {
let n = nums.count
// Result array
var result = Array(repeating: 0, count: n)
// Stack stores indexes
var stack: [Int] = []
for currentIndex in 0..<n {
// Resolve pending larger elements
while let lastIndex = stack.last,
nums[currentIndex] < nums[lastIndex] {
stack.removeLast()
// Store distance
result[lastIndex] = currentIndex - lastIndex
}
// Push current index
stack.append(currentIndex)
}
return result
}
// Example
let nums = [73, 74, 75, 71, 69, 72, 76, 73]
print(nextSmallerDistance(nums))
Swift Practices
- Kept the stack implementation minimal
- Used expressive variable naming for readability
- Focused on simple and maintainable logic
- Avoided over-engineering the solution
This problem felt closer to real-world engineering thinking because it required identifying a reusable algorithmic pattern instead of relying purely on brute force.
Agoda’s assessment did not feel like a “write anything that passes” coding round. It strongly rewarded clean engineering habits — readable Swift code, complexity awareness, modular thinking, and production-style implementation choices.
My Biggest Takeaway
One important realization from this round was that passing all test cases is only part of the evaluation.
The code itself matters.
From my experience, Agoda appears to review submissions with an engineering lens:
- Is the implementation scalable?
- Is complexity justified?
- Is the code maintainable?
- Would this pass a real peer review?
For developers preparing for Agoda interviews, I would strongly recommend:
- Practice explaining trade-offs aloud
- Focus on clean Swift implementation patterns
- Always discuss time and space complexity
- Optimize incrementally instead of jumping directly to the final solution
- Treat HackerRank like production engineering, not competitive programming
That mindset made a significant difference during the assessment.
메타데이터
- post_id
- d9d90cc5b98a
- slug
- agoda-staff-ios-engineer-interview-experience-strong-technical-rounds-great-discussions-and-key-d9d90cc5b98a
- url
- https://medium.com/@shantaram-kokate-swift/agoda-staff-ios-engineer-interview-experience-strong-technical-rounds-great-discussions-and-key-d9d90cc5b98a
- canonical_url
- https://medium.com/@shantaram-kokate-swift/agoda-staff-ios-engineer-interview-experience-strong-technical-rounds-great-discussions-and-key-d9d90cc5b98a
- author_url
- https://medium.com/@shantaram-kokate-swift
- status
- ok
- fetched_at
- 2026-06-13 12:55:53