Go寻找最长回文字符串——中心扩展法
时间:2022-07-22
本文章向大家介绍Go寻找最长回文字符串——中心扩展法,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目要求
给定一个字符串,求出它的最长回文子串的长度
题目分析
常规思路
分析题目可知,该题可以抓换成两个问题如下
- 求出字符串的所有的子串
- 判断所有的字串中是回文字符串,且长W度最长 对于上面的解法属于常规思路,求子串可以利用切片的性质比较简单
判断是否是回文
对于一个回文字符串,我们可以很轻易的找到其中的规律就是首尾逐个字符进行遍历是相同的字符因此我们可以定义两个指针指向首和尾,进行遍历比较,如果遇见不相同的则返回false
代码
func IsPalindrome_one(str string) bool {
// 非法输入
if len(str) == 0 {
return false
}
// 定义两个指针
right := len(str) - 1
left := 0
for i := left; i < len(str)/2; i++ {
if str[i] != str[right] {
return false
}
right--
}
return true
}
寻找子串
对于一个字符串,举例abcd,可以从a进行遍历,分别追加后面的字符形成子串,然后以b进行遍历。代码如下
// 获取所有的字串
func getAllSubstring(str string) (re []string) {
for i := 0; i < len(str); i++ {
j := len(str)
for j = len(str); j > i; j-- {
re = append(re, str[i:j])
}
}
return re
}
完整代码
// 常规解法
func LookPanlind_one(str string) string {
// 找到该字符串的所有字串存放到字符串数组
re := getAllSubstring(str)
max := 0
sign := 0
// 遍历 数组
for i := 0; i < len(re); i++ {
if IsPalindrome_one(re[i]) {
if max < len(re[i]) {
max = len(re[i])
sign = i
}
}
}
return re[sign]
}
// 获取所有的字串
func getAllSubstring(str string) (re []string) {
for i := 0; i < len(str); i++ {
j := len(str)
for j = len(str); j > i; j-- {
re = append(re, str[i:j])
}
}
return re
}
// 判断是否是回文字符串
func IsPalindrome_one(str string) bool {
// 非法输入
if len(str) == 0 {
return false
}
// 定义两个指针
right := len(str) - 1
left := 0
for i := left; i < len(str)/2; i++ {
if str[i] != str[right] {
return false
}
right--
}
return true
}
虽然可以求出最终结果,但是这样的方法过于复杂,我们是将所有的字串进行查找出后进行循环判断,增加了代码的时间复杂度,下面介绍中心扩展法
中心扩展法
对于一个回文字符串,找到一个中心位置,不断向外扩展,所对应的字符都是相同的,举例“aba”,以b为中心,判断出a和a相同,因此对于一个字符串,只需要找到一个中心轴,判断其两边的字符的相等情况即可。
// 中心扩展法
func LookPanlind_two(str string) (s string) {
i, j, max, c := 0, 0, 0, 0
for i = 0; i < len(str); i++ {
// 回文长度为奇数
for j = 0; (i+j) < len(str) && (i-j) >= 0; j++ {
if str[i-j] != str[i+j] {
break
}
c = 2*j + 1
}
if max < c {
s = str[(i - j + 1):(i + j)]
println("奇数", s)
max = c
}
// 回文长度为偶数
for j = 0; (i+j+1) < len(str) && (i-j) >= 0; j++ {
if str[i-j] != str[i+j+1] {
break
}
c = 2*j + 2
}
if max < c {
s = str[(i - j + 1):(i + j + 1)]
println("偶数", s)
max = c
}
}
return s
}
代码分析
对于寻找奇数的回文,扩展根据i为中心轴进行左右指针的移动,因此我们可以定义一个j初始化为0,i+j则为当前或者下一个字符,i-j则为当前或者前一个字符,然后对字符进行比较。c用于表示临时的回文长度,求出后将之与max进行比对.对于找到最长的字符串,仍可利用切片的性质,这里需要注意的是对于切片为前者包含,后者不包含,但是由于进入if循环后j多+1了一次,因此i-j便是多减去了一个1,所以要+1,后者的由于j多加1刚好满足切片的条件。
for j = 0; (i+j) < len(str) && (i-j) >= 0; j++ {
if str[i-j] != str[i+j] {
break
}
c = 2*j + 1
}
if max < c {
s = str[(i - j + 1):(i + j)]
println("奇数", s)
max = c
}
作者 | 陌无崖
转载请联系授权
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- LeetCode题目31:下一个排列
- LeetCode题目33:搜索旋转排序数组
- LeetCode题目34:在排序数组中查找元素的第一个和最后一个位置
- LeetCode题目35:搜索插入位置
- LeetCode题目36:有效的数独
- 你必须掌握动态规划——LeetCode题目5:最长回文子串
- 有意思的难题——LeetCode题目37:解数独
- 源码分析-分布式链路追踪:Skywalking存储插件能力-elasticsearch
- mongodb 4.0副本集搭建
- 浅析Kubernetes Pod重启策略和健康检查
- SpringBoot2 整合Ehcache组件,轻量级缓存管理
- 数据源管理 | 分布式NoSQL系统,Cassandra集群管理
- 【NPM库】- 0x03 - Express
- 数值微分|多项式的导数计算
- 让windows 10 内置ubuntu(WSL)成为扩增子分析生产力