Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5765dbc

Browse files
committed
feat: update 005
1 parentdb178b6 commit5765dbc

File tree

2 files changed

+55
-22
lines changed

2 files changed

+55
-22
lines changed

‎note/005/README.md

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,12 @@ class Solution {
6262
##思路1
6363

6464
如果利用暴力法遍历所有字串是否回文的情况这道题肯定是`Time Limit Exceeded` 的,那么我们是否可以把之前遍历的结果利用上呢,那么动态规划的想法就呼之欲出了,我们定义`dp[i][j]` 的意思为字符串区间`[i, j]`是否为回文串,那么我们分三种情况:
65+
6566
1.`i == j` 时,那么毫无疑问`dp[i][j] = true`
6667
2.`i + 1 == j` 时,那么`dp[i][j]` 的值取决于`s[i] == s[j]`
6768
3.`i + 1 < j` 时,那么`dp[i][j]` 的值取决于`dp[i + 1][j - 1] && s[i] == s[j]`
68-
根据以上的动态转移方程,我们的问题即可迎刃而解,时间复杂度的话很显而易见,也是`O(n^2)`
69+
70+
根据以上的动态转移方程,我们的问题即可迎刃而解,时间复杂度的话显而易见,也是`O(n^2)`
6971

7072
```java
7173
classSolution {
@@ -97,7 +99,32 @@ class Solution {
9799

98100
##思路2
99101

100-
最后一种思路那就是`Manacher's Algorithm`,中文名叫马拉车算法,该算法就是专为解决此问题而发明的。
102+
马拉车算法(Manacher's Algorithm)
103+
104+
##背景
105+
106+
给定一个字符串,求出其最长回文子串。例如:
107+
108+
1. s = "babad",最长回文长度为`3`,可以是`bab` 或者`aba`
109+
2. s = "cbbda",最长回文长度为`2`,即`bb`
110+
3. s = "abcde",最长回文长度为`1`,即单个字符本身。
111+
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)
115+
116+
以上问题的传统思路大概是,遍历每一个字符,以该字符为中心向两边查找。其时间复杂度为`O(n2)`,效率很差。
117+
118+
1975 年,一个叫 Manacher 的人发明了一个算法,Manacher 算法(中文名:马拉车算法),该算法可以把时间复杂度提升到`O(n)`。下面来看看马拉车算法是如何工作的。
119+
120+
最后一种思路那就是`Manacher's Algorithm`,中文名叫马拉车算法,该算法就是专为解决此问题而发明的,其时间复杂度提升到了线性。下面我以我理解的思路来讲解其原理。
121+
由于回文串的奇偶行不确定,比如`lol` 是奇回文,而`lool` 是偶回文,马拉车算法的第一步就是对其进行预处理,做法就是在每个字符两侧都加上一个特殊字符,一般就是不会出现在原串中的即可,我们可以选取`#`,那么
122+
123+
`lol` ->`#l#o#l#`
124+
`lool` ->`#l#o#o#l#`
125+
126+
这样处理后不管原来字符串长度是奇还是偶,最终得到的长度都将是奇数,这样就能把两种情况合并起来考虑。
127+
101128

102129

103130
##结语

‎src/com/blankj/medium/_005/Solution.java

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,34 +33,40 @@ public class Solution {
3333
// st = l + 1;
3434
// end = r - 1;
3535
// }
36+
// }
37+
38+
// public String longestPalindrome(String s) {
39+
// int len = s.length();
40+
// if (len <= 1) return s;
41+
// int st = 0, end = 0;
42+
// char[] chars = s.toCharArray();
43+
// boolean[][] dp = new boolean[len][len];
44+
// for (int i = 0; i < len; i++) {
45+
// dp[i][i] = true;
46+
// for (int j = 0; j < i; j++) {
47+
// if (j + 1 == i) {
48+
// dp[j][i] = chars[j] == chars[i];
49+
// } else {
50+
// dp[j][i] = dp[j + 1][i - 1] && chars[j] == chars[i];
51+
// }
52+
// if (dp[j][i] && i - j > end - st) {
53+
// st = j;
54+
// end = i;
55+
// }
56+
// }
57+
// }
58+
// return s.substring(st, end + 1);
3659
// }
3760

3861
publicStringlongestPalindrome(Strings) {
39-
intlen =s.length();
40-
if (len <=1)returns;
41-
intst =0,end =0;
42-
char[]chars =s.toCharArray();
43-
boolean[][]dp =newboolean[len][len];
44-
for (inti =0;i <len;i++) {
45-
dp[i][i] =true;
46-
for (intj =0;j <i;j++) {
47-
if (j +1 ==i) {
48-
dp[j][i] =chars[j] ==chars[i];
49-
}else {
50-
dp[j][i] =dp[j +1][i -1] &&chars[j] ==chars[i];
51-
}
52-
if (dp[j][i] &&i -j >end -st) {
53-
st =j;
54-
end =i;
55-
}
56-
}
57-
}
58-
returns.substring(st,end +1);
62+
63+
returns;
5964
}
6065

6166
publicstaticvoidmain(String[]args) {
6267
Solutionsolution =newSolution();
6368
System.out.println(solution.longestPalindrome("babad"));
6469
System.out.println(solution.longestPalindrome("cbbd"));
70+
6571
}
6672
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp