String Manipulation Problems/Solutions: Android Engineer Interview

Expected to not only build elegant UIs and robust app architectures, but also handle string manipulation challenges efficiently—whether in data parsing, search indexing, localization, or backend communication. These challenges are frequent in interviews and common in production code.


In this post, we'll cover the most commonly asked string manipulation problems, provide clean Kotlin solutions, and share insights into why they're relevant in real Android development.


1. Reverse Words in a String

Why It Matters:

This is essential in chat interfaces, search functionality, or cleaning user inputs.

📥 Problem:

Input: "  the sky  is blue  "
Output: "blue is sky the"

✅ Kotlin Solution:

fun reverseWords(s: String): String {
    return s.trim().split("\\s+".toRegex()).reversed().joinToString(" ")
}

2. Valid Anagram

Why It Matters:

Used in search ranking, recommendation systems, or cache key generation.

📥 Problem:

Input: s = "anagram", t = "nagaram"
Output: true

✅ Kotlin Solution:

fun isAnagram(s: String, t: String): Boolean {
    return s.toCharArray().sorted() == t.toCharArray().sorted()
}

3. Longest Common Prefix

Why It Matters:

Used in auto-complete systems and directory-based file filtering.

📥 Problem:

Input: ["flower", "flow", "flight"]
Output: "fl"

✅ Kotlin Solution:

fun longestCommonPrefix(strs: Array<String>): String {
    if (strs.isEmpty()) return ""
    var prefix = strs[0]
    for (i in 1 until strs.size) {
        while (!strs[i].startsWith(prefix)) {
            prefix = prefix.dropLast(1)
            if (prefix.isEmpty()) return ""
        }
    }
    return prefix
}

4. Minimum Window Substring

Why It Matters:

Used in Android when querying over large text (OCR, search indexes, etc.).

📥 Problem:

Input: s = "ADOBECODEBANC", t = "ABC"
Output: "BANC"

✅ Kotlin Solution:

fun minWindow(s: String, t: String): String {
    if (s.length < t.length) return ""
    val tFreq = mutableMapOf<Char, Int>()
    for (c in t) tFreq[c] = tFreq.getOrDefault(c, 0) + 1

    val windowFreq = mutableMapOf<Char, Int>()
    var left = 0
    var formed = 0
    var result = ""
    var minLen = Int.MAX_VALUE

    for (right in s.indices) {
        val c = s[right]
        windowFreq[c] = windowFreq.getOrDefault(c, 0) + 1

        if (tFreq.containsKey(c) && windowFreq[c] == tFreq[c]) {
            formed++
        }

        while (formed == tFreq.size) {
            if (right - left + 1 < minLen) {
                minLen = right - left + 1
                result = s.substring(left, right + 1)
            }

            val lc = s[left]
            windowFreq[lc] = windowFreq.getOrDefault(lc, 0) - 1
            if (tFreq.containsKey(lc) && windowFreq[lc]!! < tFreq[lc]!!) {
                formed--
            }
            left++
        }
    }

    return result
}

5. Remove Invalid Parentheses

Why It Matters:

Used in form validation, input cleaning, and code formatting tools.

📥 Problem:

Input: "()())()"
Output: ["()()()", "(())()"]

✅ Kotlin Solution:

fun removeInvalidParentheses(s: String): List<String> {
    val result = mutableListOf<String>()
    val visited = mutableSetOf<String>()
    val queue = ArrayDeque<String>()

    queue.add(s)
    visited.add(s)
    var found = false

    while (queue.isNotEmpty()) {
        val str = queue.removeFirst()
        if (isValid(str)) {
            result.add(str)
            found = true
        }
        if (found) continue
        for (i in str.indices) {
            if (str[i] != '(' && str[i] != ')') continue
            val next = str.removeRange(i, i + 1)
            if (!visited.contains(next)) {
                visited.add(next)
                queue.add(next)
            }
        }
    }
    return result
}

fun isValid(s: String): Boolean {
    var count = 0
    for (c in s) {
        if (c == '(') count++
        else if (c == ')') {
            if (count == 0) return false
            count--
        }
    }
    return count == 0
}

6. Decode String (Nested Brackets)

Why It Matters:

Parsing encoded data from network or decoding compressed UI strings.

📥 Problem:

Input: "3[a2[c]]"
Output: "accaccacc"

✅ Kotlin Solution:

fun decodeString(s: String): String {
    val countStack = ArrayDeque<Int>()
    val stringStack = ArrayDeque<String>()
    var current = ""
    var i = 0

    while (i < s.length) {
        when {
            s[i].isDigit() -> {
                var num = 0
                while (s[i].isDigit()) {
                    num = num * 10 + (s[i] - '0')
                    i++
                }
                countStack.addLast(num)
            }
            s[i] == '[' -> {
                stringStack.addLast(current)
                current = ""
                i++
            }
            s[i] == ']' -> {
                val prev = stringStack.removeLast()
                val count = countStack.removeLast()
                current = prev + current.repeat(count)
                i++
            }
            else -> {
                current += s[i]
                i++
            }
        }
    }

    return current
}

Real-World Use Cases in Android

Problem Real-World Android Usage
Reverse Words Chat apps, voice command parsing
Anagram Check Spell check, search suggestion engine
Common Prefix Auto-complete, filtering product SKUs
Min Window Substring Highlighting search terms
Parentheses Validation Form validation, input sanitization
Decode String Parsing compressed server payloads

Conclusion

As a Senior Android Engineer, having deep fluency in string manipulation strengthens your:

  • Algorithmic thinking (needed for system design)

  • Debugging efficiency (e.g., malformed JSON, XML)

  • Cross-platform readiness (e.g., Kotlin Multiplatform, i18n)

  • Interview performance at top-tier companies

So keep practicing these patterns—they’ll boost your code clarity, performance, and technical leadership.


As an Android Engineer…

I’ve seen these exact problems show up in:

  • Live coding rounds

  • Design challenges

  • Production bug-fixes (especially with search, input validation, or backend data mismatches)

I recommend solving them on paper, IDE, and whiteboard. It builds confidence and a habit of thinking in Kotlin idioms.


📢 Feedback: Did you find this article helpful? Let me know your thoughts or suggestions for improvements! Please leave a comment below. I’d love to hear from you! 👇

Happy coding! 💻

0 comments:

Post a Comment