2021-08-16:回文对。给定一组 互不相同 的单词, 找出所有 不同 的索引对 (i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串。
Posted 福大大架构师每日一题
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021-08-16:回文对。给定一组 互不相同 的单词, 找出所有 不同 的索引对 (i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串。相关的知识,希望对你有一定的参考价值。
2021-08-16:回文对。给定一组 互不相同 的单词, 找出所有 不同 的索引对 (i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串。
福大大 答案2021-08-16:
k是字符串长度。
1.依次遍历,嵌套循环。
时间复杂度:O((N^2)k)
2.b逆序+a+b,a+b+a逆序。注意去重。
时间复杂度:O(N(k^2))。
代码用golang编写。代码如下:
package main
import "fmt"
func main() {
words := []string{"bat", "tab", "cat"}
ret := palindromePairs(words)
fmt.Println(ret)
}
func palindromePairs(words []string) [][]int {
wordset := make(map[string]int)
for i := 0; i < len(words); i++ {
wordset[words[i]] = i
}
res := make([][]int, 0)
//{ [6,23] 、 [7,13] }
for i := 0; i < len(words); i++ {
// i words[i]
// findAll(字符串,在i位置,wordset) 返回所有生成的结果返回
findRet := findAll(words[i], i, wordset)
res = append(res, findRet...)
}
return res
}
func findAll(word string, index int, words map[string]int) [][]int {
res := make([][]int, 0)
reverse := reverse(word)
rest, ok := words[""]
if ok && rest != index && word == reverse {
addRecord(&res, rest, index)
addRecord(&res, index, rest)
}
rs := manacherss(word)
mid := len(rs) >> 1
for i := 1; i < mid; i++ {
if i-rs[i] == -1 {
ok2 := false
rest, ok2 = words[reverse[0:mid-i]]
if ok2 && rest != index {
addRecord(&res, rest, index)
}
}
}
for i := mid + 1; i < len(rs); i++ {
if i+rs[i] == len(rs) {
ok3 := false
aaa := reverse[(mid<<1)-i:]
rest, ok3 = words[aaa]
if ok3 && rest != index {
addRecord(&res, index, rest)
}
}
}
return res
}
func addRecord(res *[][]int, left int, right int) {
newr := make([]int, 0)
newr = append(newr, left)
newr = append(newr, right)
*res = append(*res, newr)
}
func manacherss(word string) []int {
mchs := manachercs(word)
rs := make([]int, len(mchs))
center := -1
pr := -1
for i := 0; i != len(mchs); i++ {
if pr > i {
rs[i] = getMin(rs[center<<1-i], pr-i)
} else {
rs[i] = 1
}
for i+rs[i] < len(mchs) && i-rs[i] > -1 {
if mchs[i+rs[i]] != mchs[i-rs[i]] {
break
}
rs[i]++
}
if i+rs[i] > pr {
pr = i + rs[i]
center = i
}
}
return rs
}
func getMin(a int, b int) int {
if a < b {
return a
} else {
return b
}
}
func twoSelectOne(c bool, a int, b int) int {
if c {
return a
} else {
return b
}
}
func manachercs(word string) string {
chs := []byte(word)
mchs := make([]byte, len(chs)*2+1)
index := 0
for i := 0; i != len(mchs); i++ {
if (i & 1) == 0 {
mchs[i] = '#'
} else {
mchs[i] = chs[index]
index++
}
}
return string(mchs)
}
func reverse(str string) string {
chs := []byte(str)
l := 0
r := len(chs) - 1
for l < r {
tmp := chs[l]
chs[l] = chs[r]
l++
chs[r] = tmp
r--
}
return string(chs)
}
执行结果如下:
以上是关于2021-08-16:回文对。给定一组 互不相同 的单词, 找出所有 不同 的索引对 (i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串。的主要内容,如果未能解决你的问题,请参考以下文章