面试经典算法:马拉松算法,最长回文子串Golang实现

aside section._1OhGeD · · 780 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

求一个字符串中最长的回文子串。

a11.png
package main

import "fmt"

/*
    马拉松算法,求最长回文子串,时间复杂度:线性
*/
func main() {
    // 回文数
    str := "abcddcbadcbadcabdadacd"

    // 填充#变成奇数个元素
    strArray := make([]byte, 0, 2*len(str)+1) // 每个字符是一个byte

    for i := 0; i < len(str); i++ {
        strArray = append(strArray, str[i])
        strArray = append(strArray, '#')
    }

    fmt.Print("原始字符串:")
    for i := 0; i < len(strArray); i++ {
        fmt.Print(string(strArray[i]))
    }
    fmt.Println()

    // 每个字符的最大回文半径
    radiusLen := make([]int, len(strArray))

    // 最大回文半径的中心位置
    id := 0

    // 最大回文串的右边界
    maxIndex := 0

    // 遍历新的串
    for i := 0; i < len(strArray); i++ {
        // 如果i在最大回文串中,那么可以进行判断,加快算法效率
        if i < maxIndex {
            j := 2*id - i // j和i是id的对称点

            if radiusLen[j] < maxIndex-i {
                // j的半径被最长串包住,那么i的半径必然等于j
                radiusLen[i] = radiusLen[j]
                continue
            } else if radiusLen[j] > maxIndex-i {
                // j的半径超出了最长串,那么i的半径必然是 j-(id-radiusLen(id)) = maxIndex - i 可画图观察
                radiusLen[i] = maxIndex - i
                continue
            } else if radiusLen[j] == maxIndex-i {
                // j的半径刚刚好到达最长串边界,这时i的半径可能比j还大,循环不会退出
                radiusLen[i] = radiusLen[j]
            }
        }

        for {
            // i半径必须合理,不能超过数组界,以圆心向两边拓展,逐一比较字符是否相等
            if i-radiusLen[i] >= 0 && i+radiusLen[i] < len(strArray) && strArray[i-radiusLen[i]] == strArray[i+radiusLen[i]] {
                radiusLen[i] = radiusLen[i] + 1
            } else {
                break
            }
        }

        // 如果半径比最大串还大,换人!
        if radiusLen[i] > radiusLen[id] {
            maxIndex = i + radiusLen[i] - 1
            id = i
        }
    }

    fmt.Print("处理完最长回文子串:")
    for i := id - (radiusLen[id] - 1); i <= id+(radiusLen[id]-1); i++ {
        fmt.Print(string(strArray[i]))
    }
}

转载请注明:http://www.lenggirl.com/algorithm/mala.html


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:aside section._1OhGeD

查看原文:面试经典算法:马拉松算法,最长回文子串Golang实现

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

780 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传