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) }
执行结果如下: