
When aiming for an Android developer role, you’ll face not only Android-specific questions but also Data Structures & Algorithms (DSA) challenges 🧩. These are often designed to assess problem-solving skills critical for senior roles.
💡 Here’s a simplified, emoji-packed guide to ace these questions!
1. Optimize App Startup Using Data Structures
🛠 Problem: Speed up app startup by quickly fetching configuration data stored as key-value pairs.
🎯 Goal: Ensure retrieval in O(1)
time.
🧑💻 Solution: Use a HashMap!
fun loadConfig(pairs: List<Pair<String, String>>): Map<String, String> {
val configMap = mutableMapOf<String, String>()
pairs.forEach { configMap[it.first] = it.second }
return configMap
}
fun main() {
val config = listOf("theme" to "dark", "font" to "large")
println(loadConfig(config)["theme"]) // 🌟 Output: dark
}
2. Efficient Caching for News App 🗞️
🛠 Problem: Cache articles and quickly retrieve the most recent one.
🎯 Goal: Use LRU Cache (Least Recently Used).
🧑💻 Solution: Use LinkedHashMap.
class LRU<K, V>(private val size: Int) : LinkedHashMap<K, V>(size, 0.75f, true) {
override fun removeEldestEntry(eldest: MutableMap.MutableEntry<K, V>?) = size > this.size
}
fun main() {
val cache = LRU<String, String>(3)
cache["1"] = "Article 1"
cache["2"] = "Article 2"
cache["3"] = "Article 3"
println(cache) // 🎯 Output: {1=Article 1, 2=Article 2, 3=Article 3}
}
3. Find Duplicate Images in Gallery 📷
🛠 Problem: Detect duplicate images based on their unique hashes.
🎯 Goal: Return a list of duplicate hashes.
🧑💻 Solution: Use a Set to track duplicates.
fun findDuplicates(hashes: List<String>): List<String> {
val seen = mutableSetOf<String>()
return hashes.filter { !seen.add(it) }
}
fun main() {
val hashes = listOf("hash1", "hash2", "hash1", "hash3")
println(findDuplicates(hashes)) // 🔍 Output: [hash1]
}
4. Schedule Notifications Without Overlaps 🕒
🛠 Problem: Ensure no overlapping reminders in notifications.
🎯 Goal: Use interval scheduling.
🧑💻 Solution: Sort and compare intervals.
data class Reminder(val start: Int, val end: Int)
fun canSchedule(reminders: List<Reminder>): Boolean {
val sorted = reminders.sortedBy { it.start }
for (i in 1 until sorted.size) {
if (sorted[i].start < sorted[i - 1].end) return false
}
return true
}
fun main() {
val reminders = listOf(Reminder(1, 3), Reminder(2, 5))
println(canSchedule(reminders)) // 🚫 Output: false
}
5. Find Missing User ID 🔢
🛠 Problem: Detect a missing number in a sequence of user IDs.
🎯 Goal: Use the sum formula!
🧑💻 Solution: Compare actual sum with expected.
fun findMissingID(ids: List<Int>): Int {
val n = ids.size + 1
return n * (n + 1) / 2 - ids.sum()
}
fun main() {
println(findMissingID(listOf(1, 2, 4))) // 🎯 Output: 3
}
6. Merge Two Sorted Lists 📋
🛠 Problem: Merge two sorted lists into one.
🎯 Goal: Use the two-pointer technique.
🧑💻 Solution: Compare and merge!
fun mergeLists(list1: List<Int>, list2: List<Int>): List<Int> {
val result = mutableListOf<Int>()
var i = 0
var j = 0
while (i < list1.size && j < list2.size) {
if (list1[i] <= list2[j]) result.add(list1[i++])
else result.add(list2[j++])
}
result.addAll(list1.drop(i))
result.addAll(list2.drop(j))
return result
}
fun main() {
println(mergeLists(listOf(1, 3), listOf(2, 4))) // ✅ Output: [1, 2, 3, 4]
}
7. Detect Cycles in User Sessions
💡 Problem:
In user session data represented as a linked list, detect if there’s a cycle.
🛠️ Solution:
Use Floyd’s Cycle Detection Algorithm (a.k.a the Fast and Slow Pointer method).
class Node(val value: Int) {
var next: Node? = null
}
fun hasCycle(head: Node?): Boolean {
var slow = head
var fast = head
while (fast?.next != null) {
slow = slow?.next
fast = fast.next?.next
if (slow == fast) return true
}
return false
}
fun main() {
val head = Node(1).apply {
next = Node(2).apply {
next = Node(3).apply { next = this@apply } // Creates a cycle
}
}
println(hasCycle(head)) // Output: true 🚨
}
🔑 Key Takeaway: Fast pointer catches the slow pointer if a cycle exists.
8. Optimize Network Calls with Debouncing
💡 Problem:
Handle rapid inputs (e.g., from a search bar) and process only the final input after a delay.
🛠️ Solution:
Use Kotlin Coroutines to debounce network calls.
import kotlinx.coroutines.*
var searchJob: Job? = null
fun performDebouncedSearch(query: String, delayMs: Long = 300L) {
searchJob?.cancel()
searchJob = CoroutineScope(Dispatchers.Main).launch {
delay(delayMs)
performSearch(query)
}
}
fun performSearch(query: String) {
println("🔍 Searching for: $query")
}
fun main() {
performDebouncedSearch("android")
performDebouncedSearch("android dev")
performDebouncedSearch("android developer") // This will run after 300ms
}
🔑 Key Takeaway: Cancel unnecessary jobs to avoid spamming API requests.
9. Find the Kth Largest Metric
💡 Problem:
In a list of app metrics, find the kth largest value.
🛠️ Solution:
Use a Min-Heap for efficient retrieval.
import java.util.PriorityQueue
fun findKthLargest(metrics: IntArray, k: Int): Int {
val minHeap = PriorityQueue<Int>()
for (metric in metrics) {
minHeap.add(metric)
if (minHeap.size > k) minHeap.poll()
}
return minHeap.peek()
}
fun main() {
val metrics = intArrayOf(3, 2, 1, 5, 6, 4)
println(findKthLargest(metrics, 2)) // Output: 5 🎉
}
🔑 Key Takeaway: The heap size equals k
, ensuring optimal time complexity.
10. Count Unique Users
💡 Problem:
In a list of user IDs, count the unique users.
🛠️ Solution:
Use a Set to filter duplicates.
fun countUniqueUsers(userIds: List<String>): Int {
return userIds.toSet().size
}
fun main() {
val userIds = listOf("u1", "u2", "u1", "u3", "u2")
println(countUniqueUsers(userIds)) // Output: 3 ✨
}
🔑 Key Takeaway: Sets automatically discard duplicates.
11. Top K Most Used Features
💡 Problem:
Identify the top K features used in your app.
🛠️ Solution:
Combine HashMap (to count) with PriorityQueue (to sort).
fun topKFeatures(features: List<String>, k: Int): List<String> {
val freqMap = features.groupingBy { it }.eachCount()
val pq = PriorityQueue<Map.Entry<String, Int>>(compareBy { it.value })
for (entry in freqMap.entries) {
pq.add(entry)
if (pq.size > k) pq.poll()
}
return pq.map { it.key }
}
fun main() {
val features = listOf("home", "profile", "home", "settings", "home", "profile")
println(topKFeatures(features, 2)) // Output: ["profile", "home"] 🌟
}
🔑 Key Takeaway: PriorityQueues keep top K elements efficiently.
12. Rearrange Screens to Avoid Repetition
💡 Problem:
Rearrange screen IDs so no two adjacent screens are the same.
🛠️ Solution:
Use a Max-Heap to organize by frequency.
import java.util.PriorityQueue
fun rearrangeScreens(screens: List<String>): List<String> {
val freqMap = screens.groupingBy { it }.eachCount()
val pq = PriorityQueue<Map.Entry<String, Int>>(compareByDescending { it.value })
pq.addAll(freqMap.entries)
val result = mutableListOf<String>()
var prev: Map.Entry<String, Int>? = null
while (pq.isNotEmpty()) {
val current = pq.poll()
result.add(current.key)
if (prev != null && prev.value > 0) pq.offer(prev)
prev = current.copy(value = current.value - 1)
}
return if (result.size == screens.size) result else emptyList()
}
fun main() {
val screens = listOf("A", "A", "B", "B", "C")
println(rearrangeScreens(screens)) // Output: [A, B, A, C, B] or similar 🎨
}
🔑 Key Takeaway: Use heaps to alternate frequencies intelligently.
🎉 Final Words
📝 Preparing for Android developer interviews can feel overwhelming. But with these simplified DSA examples, you’re ready to tackle challenging problems efficiently!
✨ Pro Tip: Practice these snippets, tweak the examples, and try variations to boost your understanding.
📚 Good luck with your interviews, and don’t forget to stay awesome! 😎🌟
Thank you for reading! 🙌 Let’s code together! 💻🤝