LeetCode 5 - 回文串 - 解题思路记录 - GoLang

1,552 阅读3分钟

题目:

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1: 输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

示例 2: 输入: "cbbd"
输出: "bb"

接下来开始分析解题思路:
我在刚接触这道题目的时候,我自己的想法是说能不能用栈去匹配栈顶元素的值是否与下一个元素匹配
在我尝试过之后,我才发现不行。因为我很难判断目前栈内的元素跟谁能匹配
比方说:badac字符串

在最后一个字母a 压栈后,并不知道要弹出哪个。
说明这个方法我是解不出来的,后来看到了别人的解题思路后,学习再加消化,现在来总结一下解题思路
我们先来看核心的代码

func isCharacterMatch(left int, right int, str string, max *int, st *int) {
 for {
  if left >= 0 && right < len(str) && str[left] == str[right]{
   if right - left + 1 > *max{
    *max = right - left + 1
    *st = left
   }
   left = left - 1
   right = right + 1
  }else{
   break
  }
 }
}

这个方法的核心就在 if 中的3个判断条件

  1. left>=0
  2. right < len(str)
  3. str[left] == str[right]\

然后我们来举例子,解释一下这3个条件,怎么样才能满足
我们先来考虑2个例子,

  1. babad
  2. cabbae

这两个例子有什特别的地方吗? 有
就是字符串从中心起始的位置不一样,我们来画个图

字符串的两个中心点是不一样的
也就是说,我们存在两种条件需要去做
第一个是 i-1, i+1 (相当于第一个例子)
第二个是 i, i+1 (相当于第二个例子)

比方说我们的i=1

那么条件满足了,进入下一个if, 这一个if 为什么要+1?
我们再来看一张图

那么这里的max 是什么?
max 其实是当前找到最长回文字符串的长度
因此如果我们有发现比当前更长的时候,需要更新最长的回文字符串
也就是\

*max = right - left +1
*st = left

这一句里的st是字符串start的位置,我们再来看一张图\

所以这道题的答案就是bab (当然aba也可以)
第一个例子看完了,我们来看第二个例子cabbad的例子
同样的思路,在例题2就不能这样子做了

因为在这个例子中,i 和 i+1才是中心点再向两边扩散,
然后我们再看一下第二层的if内部

这下,我们就解释了这个最核心的地方了,来个总结

然后我们看一下主函数\

func longestPalindrome(s string) string {
 if len(s) < 2{
  return s
 }
  maxLength  := 0
  start  := 0
 for i := 0; i< len(s); i++{
  isCharacterMatch(i, i+1, s, &maxLength, &start)
  isCharacterMatch(i-1, i+1, s, &maxLength, &start)

 }
 fmt.Println(start, maxLength)
 if start ==0 && maxLength ==0 {
  return string(s[0])
 }
 str := s[start:start+maxLength]
 return str
}

主函数中的for 就是为了遍历整个字符串, 接下来,我们看一下 第一个if len(s)<2的情况
举个例子 a -> 他的回文就是他本身
再来是下面那个IF 字符串ab->a 指向的是str[0]个元素
最后我们返回 start -> start+maxLength 内的元素,就是最大的回文字符串了\

记录自己的理解过程、对于GoLan也不是很熟悉,共同努力吧!