diff --git a/contest/src/main/java/com/github/contest/Execute.kt b/contest/src/main/java/com/github/contest/Execute.kt index cc73082b..8c72ba83 100644 --- a/contest/src/main/java/com/github/contest/Execute.kt +++ b/contest/src/main/java/com/github/contest/Execute.kt @@ -4,6 +4,7 @@ package com.github.contest import com.github.contest.math.numberOfPowerfulInt import com.github.contest.slidingWindow.customStructure.rabinKarpMultiPattern import com.github.contest.slidingWindow.customStructure.slidingWindowClassic +import com.github.contest.strings.camelMatch import com.github.contest.strings.fullJustify import com.github.contest.strings.subStrHash import java.util.TreeMap @@ -22,6 +23,7 @@ fun main() { fun launchPerformance() { val text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit".repeat(10) + val new = "banana".repeat(5000) val patterns = listOf( "Lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit", "xyz", "abc" diff --git a/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowLeetcode.kt b/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowLeetcode.kt index aba05c3c..921d51c3 100644 --- a/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowLeetcode.kt +++ b/contest/src/main/java/com/github/contest/slidingWindow/SlidingWindowLeetcode.kt @@ -318,5 +318,78 @@ fun findRepeatedDnaSequences(s: String): List { return res } +/** + * 1044. Longest Duplicate Substring + */ + +fun longestDupSubstring(s: String): String { + if (s.length == 2 && s[0] == s[1]) return "${s[0]}" + + var left = 1 + var right = s.length + var maxLen = 0 + var res = "" + + while (left < right) { + + val window = (left + right) / 2 + + if (window == maxLen) return res + + val check = findDuplicate(s, window) + + if (check != null) { + left = window + maxLen = window + res = check + } else right = window + } + + return res +} + + +private fun findDuplicate(s: String, length: Int): String? { + val base = 26 + val mod = 1_000_000_007 + var hash = 0L + var power = 1L + val seen = HashMap>() + + + for (i in 0 until length - 1) { + power = (power * base) % mod + } + + + for (i in 0 until length) { + hash = (hash * base + (s[i] - 'a')) % mod + } + seen.getOrPut(hash) { mutableListOf() }.add(0) + + + for (i in 1..s.length - length) { + + hash = (hash - (s[i - 1] - 'a') * power % mod + mod) % mod + + hash = (hash * base + (s[i + length - 1] - 'a')) % mod + + + if (seen.containsKey(hash)) { + val currentSub = s.substring(i, i + length) + for (start in seen[hash]!!) { + if (s.substring(start, start + length) == currentSub) { + return currentSub + } + } + seen[hash]!!.add(i) + } else { + seen[hash] = mutableListOf(i) + } + } + + return null +} + diff --git a/contest/src/main/java/com/github/contest/slidingWindow/customStructure/RabinKarpImpl.kt b/contest/src/main/java/com/github/contest/slidingWindow/customStructure/RabinKarpImpl.kt index b36a3013..c690d1ee 100644 --- a/contest/src/main/java/com/github/contest/slidingWindow/customStructure/RabinKarpImpl.kt +++ b/contest/src/main/java/com/github/contest/slidingWindow/customStructure/RabinKarpImpl.kt @@ -59,11 +59,11 @@ fun rabinKarpMultiPattern(text: String, patterns: List): Map text.length) continue + val patternLen = pattern.length + if (patternLen == 0 || patternLen > text.length) continue var hash = 0 - for (i in 0 until m) { + for (i in 0 until patternLen) { hash = (d * hash + pattern[i].code) % q }