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
}
作者 | 陌无崖
转载请联系授权
- 微信小程序新功能上线 一键连Wi-Fi手机变门禁卡
- 使用xUnit为.net core程序进行单元测试(中)
- Asp.Net 用Jquery和一般处理程序实现无刷新上传大文件
- WCF技术剖析之十五:数据契约代理(DataContractSurrogate)在序列化中的作用
- WCF技术剖析之十四:泛型数据契约和集合数据契约(上篇)
- WCF技术剖析之十四:泛型数据契约和集合数据契约(下篇)
- WCF技术剖析(卷1)之前言
- WCF技术剖析(卷1)之目录
- WCF技术剖析(卷1)之推荐序
- 谈谈基于SQL Server 的Exception Handling[上篇]
- 谈谈WCF中的Data Contract(4):WCF Data Contract Versioning
- 如何在silverlihgt中使用右键
- WCF技术剖析之十二:数据契约(Data Contract)和数据契约序列化器(DataContractSerializer)
- silverlight向服务器post数据类
- 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两题选手】MySQL类题目(一)
- 【LeetCode每日一题】(8.11)被围绕的区域
- 二叉树的前中后序遍历(迭代法)(带动画)
- 【LeetCode两题选手】算法类题目(8.8)
- 【LeetCode每日一题】(8.9)复原IP地址(回溯)
- 【回溯算法】N叉树相关技巧
- 【回溯算法】回溯,从入门到入土,七道试题精选、精讲、精练
- 数据结构练手小项目(AVL树、哈希表、循环链表、MySQL数据库)
- 【LeetCode】每日一题(8.2)二叉树展开为链表
- 【小技巧】argc和argv的用法
- 全面分析redis持久化机制
- 【奇技淫巧】-- 接雨水
- 【奇技淫巧】-- 最长连续序列
- 【redis】跟我一起动手玩玩redis主从复制和哨兵模式
- 【C++】八大排序算法 :GIF + 亲测代码 +专项练习平台