Skip to content

Commit 1ae1534

Browse files
committed
feat: update 005
1 parent 631870e commit 1ae1534

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

note/005/README.md

+11-6
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,15 @@ class Solution {
109109
2. s = "cbbda",最长回文长度为 `2`,即 `bb`
110110
3. s = "abcde",最长回文长度为 `1`,即单个字符本身。
111111

112-
这个问题等同于LeetCode上的 [Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring)
113-
114-
其相关题解可以查看这里:[传送门](https://github.com/Blankj/awesome-java-leetcode/blob/master/note/005/README.md)
112+
这个问题等同于LeetCode上的 [Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring),其相关题解可以查看这里:[传送门](https://github.com/Blankj/awesome-java-leetcode/blob/master/note/005/README.md)
115113

116114
以上问题的传统思路大概是遍历每一个字符,以该字符为中心向两边查找,其时间复杂度为 `O(n2)`,效率很差。
117115

118116
1975年,一个叫 Manacher 的人发明了 Manacher 算法(中文名:马拉车算法),该算法可以把时间复杂度提升到 `O(n)`,下面我以我理解的思路来讲解其原理。
119117

118+
119+
## 分析
120+
120121
由于回文串的奇偶行不确定,比如 `lol` 是奇回文,而 `lool` 是偶回文,马拉车算法的第一步就是对其进行预处理,做法就是在每个字符两侧都加上一个特殊字符,一般就是不会出现在原串中的即可,我们可以选取 `#`,那么
121122

122123
```
@@ -132,16 +133,20 @@ lool -> #l#o#o#l#
132133

133134
我们以 `lollool` 为例,参看下表。
134135

135-
| str | # | l | # | o | # | l | # | l | # | o | # | o | # | l | # |
136-
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
137-
| len | 1 | 2 | 1 | 4 | l | 2 | 5 | 2 | 1 | 2 | 5 | 2 | 1 | 2 | 1 |
136+
| str | # | l | # | o | # | l | # | l | # | o | # | o | # | l | # |
137+
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
138+
| len[] | 1 | 2 | 1 | 4 | l | 2 | 5 | 2 | 1 | 2 | 5 | 2 | 1 | 2 | 1 |
138139

139140
可以发现 `len[i] - 1` 就等于该回文串在原串中的长度。
140141

141142
证明:在转换后的字符串 `str` 中,那么对于以 `str[i]` 为中心的最长回文串的长度为 `2 * len[i] - 1`,其中又有 `len[i]` 个分隔符,所以在原字符串中的回文串长度就是 `len[i] - 1`
142143

143144
那么我们剩下的工作就是求 `len` 数组。
144145

146+
为了防止数组越界,我们在首位再加上非 `#` 的不常用字符,比如 `~`,那么 `lollool` 就表示为 `~#l#o#l#l#o#o#l#~`,这样我们就省去写很多 `if else` 的边界处理。
147+
148+
我们先看一张
149+
145150

146151

147152
## 结语

0 commit comments

Comments
 (0)