LeetCode in Kotlin

3093. Longest Common Suffix Queries

Hard

You are given two arrays of strings wordsContainer and wordsQuery.

For each wordsQuery[i], you need to find a string from wordsContainer that has the longest common suffix with wordsQuery[i]. If there are two or more strings in wordsContainer that share the longest common suffix, find the string that is the smallest in length. If there are two or more such strings that have the same smallest length, find the one that occurred earlier in wordsContainer.

Return an array of integers ans, where ans[i] is the index of the string in wordsContainer that has the longest common suffix with wordsQuery[i].

Example 1:

Input: wordsContainer = [“abcd”,”bcd”,”xbcd”], wordsQuery = [“cd”,”bcd”,”xyz”]

Output: [1,1,1]

Explanation:

Let’s look at each wordsQuery[i] separately:

Example 2:

Input: wordsContainer = [“abcdefgh”,”poiuygh”,”ghghgh”], wordsQuery = [“gh”,”acbfgh”,”acbfegh”]

Output: [2,0,2]

Explanation:

Let’s look at each wordsQuery[i] separately:

Constraints:

Solution

class Solution {
    fun stringIndices(wc: Array<String>, wq: Array<String>): IntArray {
        var minLength = wc[0].length
        var minIndex = 0
        val n = wc.size
        val m = wq.size
        for (i in 0 until n) {
            if (minLength > wc[i].length) {
                minLength = wc[i].length
                minIndex = i
            }
        }
        val root = Trie(minIndex)
        for (i in 0 until n) {
            var curr: Trie? = root
            for (j in wc[i].length - 1 downTo 0) {
                val ch = wc[i][j]
                if (curr!!.has(ch)) {
                    val next = curr.get(ch)
                    if (wc[next!!.index].length > wc[i].length) {
                        next.index = i
                    }
                    curr = next
                } else {
                    curr.put(ch, i)
                    curr = curr.get(ch)
                }
            }
        }
        val ans = IntArray(m)
        for (i in 0 until m) {
            var curr: Trie? = root
            for (j in wq[i].length - 1 downTo 0) {
                val ch = wq[i][j]
                if (curr!!.has(ch)) {
                    curr = curr.get(ch)
                } else {
                    break
                }
            }
            ans[i] = curr!!.index
        }
        return ans
    }

    private class Trie(var index: Int) {
        var ch: Array<Trie?> = arrayOfNulls(26)

        fun get(ch: Char): Trie? {
            return this.ch[ch.code - 'a'.code]
        }

        fun has(ch: Char): Boolean {
            return this.ch[ch.code - 'a'.code] != null
        }

        fun put(ch: Char, index: Int) {
            this.ch[ch.code - 'a'.code] = Trie(index)
        }
    }
}