Skip to content

Instantly share code, notes, and snippets.

@atonamy
Last active August 5, 2022 14:22
Show Gist options
  • Save atonamy/c238f59d2a0e8dc6b9198a6e86cd7a6b to your computer and use it in GitHub Desktop.
Save atonamy/c238f59d2a0e8dc6b9198a6e86cd7a6b to your computer and use it in GitHub Desktop.
Find the the longest common substrings
/*
Solution to this problem https://www.geeksforgeeks.org/print-longest-common-substring/ extended version
time complexity O(m*n)
*/
data class Str(val string: StringBuilder,
var startPosition: Int,
var nextPosition: Int = startPosition+1,
val id: String = UUID.randomUUID().toString()
)
fun returnLCSubStr(stringOne: String, stringTwo: String): List<String> {
val stringMap = mutableMapOf<Char, MutableSet<Int>>()
val stringToMap = if(stringOne.length < stringTwo.length) stringTwo else stringOne
val stringTraverse = if(stringToMap === stringTwo) stringOne else stringTwo
var candidates = LinkedList<Str>()
var nextIndices = mutableMapOf<String, Int>()
stringToMap.forEachIndexed { index, char ->
stringMap[char]?.add(index) ?: run {
stringMap[char] = mutableSetOf(index)
}
}
var result = mutableListOf<String>()
var maximum = 0 to -1
for(currentPosition in stringTraverse.indices) {
val char = stringTraverse[currentPosition]
val indices = stringMap[char] ?: emptySet()
candidates.forEach {
if(it.nextPosition < currentPosition)
return@forEach
val nextIndex = nextIndices[it.id]
if(nextIndex != null && indices.contains(nextIndex)) {
it.string.append(char)
if(nextIndex+1 < stringToMap.length)
nextIndices[it.id] = nextIndex+1
it.nextPosition = currentPosition+1
}
}
indices.forEach { i ->
val nextIndex = i+1
if(nextIndex < stringToMap.length || currentPosition == stringTraverse.lastIndex) {
val candidate = Str(StringBuilder().append(char), currentPosition)
candidates.add(candidate)
nextIndices[candidate.id] = i+1
}
}
}
candidates.forEach {
if(it.string.length > maximum.first ||
(it.string.length == maximum.first && it.startPosition >= maximum.second)) {
if(it.string.length > maximum.first)
result = mutableListOf()
maximum = it.string.length to it.nextPosition
result.add(it.string.toString())
}
}
return result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment