Skip to content

Commit

Permalink
1
Browse files Browse the repository at this point in the history
  • Loading branch information
isaiahliu committed Dec 16, 2024
1 parent 5d96b81 commit 62180f3
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 25 deletions.
53 changes: 28 additions & 25 deletions src/main/kotlin/p32xx/Problem3291.kt
Original file line number Diff line number Diff line change
@@ -1,44 +1,47 @@
package p32xx

import util.expect
import kotlin.math.sign

fun main() {
class Solution {
fun minValidStrings(words: Array<String>, target: String): Int {
class Trie(val depth: Int) {
val children = arrayOfNulls<Trie>(26)
val back = IntArray(target.length)
for (word in words) {
val pi = prefixFunction(word, target)
val m = word.length
for (i in target.indices) {
back[i] = maxOf(back[i], pi[m + 1 + i])
}
}
val dp = IntArray(target.length + 1) {
it.sign * target.length
}
for (i in target.indices) {
dp[i + 1] = dp[i + 1 - back[i]] + 1

val root = Trie(0)
words.forEach {
var current = root
it.forEach { ch ->
current = current.children[ch - 'a'] ?: Trie(current.depth + 1).also {
current.children[ch - 'a'] = it
}
if (dp[i + 1] > target.length) {
return -1
}
}
return dp.last()
}

var dp = hashMapOf(root to 1)

target.forEach { ch ->
val newDp = hashMapOf<Trie, Int>()
var min = Int.MAX_VALUE
dp.forEach { (node, count) ->
node.children[ch - 'a']?.also {
newDp[it] = count
min = minOf(min, count)
}
fun prefixFunction(word: String, target: String): IntArray {
val s = "$word#$target"
val pi = IntArray(s.length)
for (i in 1 until s.length) {
var j = pi[i - 1]
while (j > 0 && s[i] != s[j]) {
j = pi[j - 1]
}

if (min < Int.MAX_VALUE) {
newDp[root] = min + 1
if (s[i] == s[j]) {
j++
}

dp = newDp
pi[i] = j
}

return dp.values.minOrNull() ?: -1
return pi
}
}

Expand Down
55 changes: 55 additions & 0 deletions src/main/kotlin/p32xx/Problem3292.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package p32xx

import util.expect
import kotlin.math.sign

fun main() {
class Solution {
fun minValidStrings(words: Array<String>, target: String): Int {
val back = IntArray(target.length)
for (word in words) {
val pi = prefixFunction(word, target)
val m = word.length
for (i in target.indices) {
back[i] = maxOf(back[i], pi[m + 1 + i])
}
}
val dp = IntArray(target.length + 1) {
it.sign * target.length
}
for (i in target.indices) {
dp[i + 1] = dp[i + 1 - back[i]] + 1

if (dp[i + 1] > target.length) {
return -1
}
}
return dp.last()
}

fun prefixFunction(word: String, target: String): IntArray {
val s = "$word#$target"
val pi = IntArray(s.length)
for (i in 1 until s.length) {
var j = pi[i - 1]
while (j > 0 && s[i] != s[j]) {
j = pi[j - 1]
}

if (s[i] == s[j]) {
j++
}
pi[i] = j
}
return pi
}
}

expect {
Solution().minValidStrings(
arrayOf(
"abc", "aaaaa", "bcdef"
), "aabcdabc"
)
}
}

0 comments on commit 62180f3

Please sign in to comment.