add new solutions
This commit is contained in:
parent
67cad91898
commit
51975f3386
24 changed files with 933 additions and 14 deletions
96
solutions/29/q2977/solution.go
Normal file
96
solutions/29/q2977/solution.go
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
package q2977
|
||||
|
||||
import "math"
|
||||
|
||||
const INF int = math.MaxInt
|
||||
|
||||
func minimumCost(source string, target string, original []string, changed []string, cost []int) int64 {
|
||||
// Index words
|
||||
words := make([]string, 0, len(original)+len(changed))
|
||||
wIdx := make(map[string]int, len(original)+len(changed))
|
||||
|
||||
addWords := func(arr []string) {
|
||||
for _, word := range arr {
|
||||
if _, ok := wIdx[word]; !ok {
|
||||
words = append(words, word)
|
||||
wIdx[word] = len(words) - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
addWords(original)
|
||||
addWords(changed)
|
||||
|
||||
// Calculate min cost from `original` to `changed`
|
||||
mat := make([][]int, len(words))
|
||||
for i := range mat {
|
||||
mat[i] = make([]int, len(words))
|
||||
mat[0][i] = INF
|
||||
}
|
||||
for i := 1; i < len(words); i++ {
|
||||
copy(mat[i], mat[0])
|
||||
}
|
||||
|
||||
q := make([][3]int, 0, 2*len(original)) // src, dst, cost
|
||||
for i := range original {
|
||||
src, dst, cst := wIdx[original[i]], wIdx[changed[i]], cost[i]
|
||||
q = append(q, [3]int{src, dst, cst})
|
||||
mat[src][dst] = min(mat[src][dst], cst)
|
||||
}
|
||||
|
||||
for ; len(q) > 0; q = q[1:] {
|
||||
src, dst, cst := q[0][0], q[0][1], q[0][2]
|
||||
for next := range mat {
|
||||
if next == src || mat[dst][next] == INF {
|
||||
continue
|
||||
}
|
||||
nextCost := mat[dst][next] + cst
|
||||
if nextCost < mat[src][next] {
|
||||
mat[src][next] = nextCost
|
||||
q = append(q, [3]int{src, next, nextCost})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate min cost for converting entire string
|
||||
lengthsT := make(map[int]struct{}, len(original))
|
||||
for i := range original {
|
||||
lengthsT[len(original[i])] = struct{}{}
|
||||
}
|
||||
lengths := make([]int, 0, len(lengthsT))
|
||||
for l := range lengthsT {
|
||||
lengths = append(lengths, l)
|
||||
}
|
||||
|
||||
minCost := make([]int, len(source)+1)
|
||||
for i := range minCost {
|
||||
minCost[i] = INF
|
||||
}
|
||||
minCost[0] = 0
|
||||
|
||||
for i := 1; i < len(minCost); i++ {
|
||||
if source[i-1] == target[i-1] {
|
||||
minCost[i] = minCost[i-1]
|
||||
}
|
||||
for _, l := range lengths {
|
||||
if l > i || minCost[i-l] == INF {
|
||||
continue
|
||||
}
|
||||
srcStr, dstStr := source[i-l:i], target[i-l:i]
|
||||
src, ok1 := wIdx[srcStr]
|
||||
dst, ok2 := wIdx[dstStr]
|
||||
if !ok1 || !ok2 || mat[src][dst] == INF {
|
||||
continue
|
||||
}
|
||||
|
||||
minCost[i] = min(minCost[i], minCost[i-l]+mat[src][dst])
|
||||
}
|
||||
}
|
||||
|
||||
ret := minCost[len(minCost)-1]
|
||||
if ret == INF {
|
||||
return -1
|
||||
}
|
||||
return int64(ret)
|
||||
}
|
||||
|
||||
var _ = minimumCost
|
||||
Loading…
Add table
Add a link
Reference in a new issue