LeetCode in Kotlin

1044. Longest Duplicate Substring

Hard

Given a string s, consider all duplicated substrings: (contiguous) substrings of s that occur 2 or more times. The occurrences may overlap.

Return any duplicated substring that has the longest possible length. If s does not have a duplicated substring, the answer is "".

Example 1:

Input: s = “banana”

Output: “ana”

Example 2:

Input: s = “abcd”

Output: “”

Constraints:

Solution

class Solution {
    private lateinit var hsh: LongArray
    private lateinit var pw: LongArray
    private val cnt: Array<MutableList<Int>> = Array(26) { ArrayList() }

    fun longestDupSubstring(s: String): String {
        val n = s.length
        val base = 131
        for (i in 0..25) {
            cnt[i] = ArrayList()
        }
        hsh = LongArray(n + 1)
        pw = LongArray(n + 1)
        pw[0] = 1
        for (j in 1..n) {
            hsh[j] = (hsh[j - 1] * base + s[j - 1].code.toLong()) % MOD
            pw[j] = pw[j - 1] * base % MOD
            cnt[s[j - 1].code - 'a'.code].add(j - 1)
        }
        var ans = ""
        for (i in 0..25) {
            if (cnt[i].isEmpty()) {
                continue
            }
            val idx: MutableList<Int> = cnt[i]
            var set: MutableSet<Long>
            var lo = 1
            var hi = n - idx[0]
            while (lo <= hi) {
                val len = (lo + hi) / 2
                set = HashSet()
                var found = false
                for (nxt in idx) {
                    if (nxt + len <= n) {
                        val substrHash = getSubstrHash(nxt, nxt + len)
                        if (set.contains(substrHash)) {
                            found = true
                            if (len + 1 > ans.length) {
                                ans = s.substring(nxt, nxt + len)
                            }
                            break
                        }
                        set.add(substrHash)
                    }
                }
                if (found) {
                    lo = len + 1
                } else {
                    hi = len - 1
                }
            }
        }
        return ans
    }

    private fun getSubstrHash(l: Int, r: Int): Long {
        return (hsh[r] - hsh[l] * pw[r - l] % MOD + MOD) % MOD
    }

    companion object {
        private const val MOD = 1e9.toInt() + 7
    }
}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy