Skip to content

Commit 99608a0

Browse files
committed
feat: update 005
1 parent ca3a493 commit 99608a0

File tree

2 files changed

+75
-17
lines changed

2 files changed

+75
-17
lines changed

note/005/README.md

+36-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Output: "bb"
2828

2929
## 思路0
3030

31-
题意是寻找出字符串中最长的回文串,所谓回文串就是正序和逆序相同的字符串,也就是关于中间对称。我们先用最常规的做法,依次去求得每个字符的最长回文,要注意每个字符有奇数长度的回文串和偶数长度的回文串两种情况,相信你可以很轻易地从如下代码中找到相关代码,记录最长回文的始末位置即可,时间复杂度的话,首先要遍历一遍字符串,然后对每个字符都去求得最长回文,所以时间复杂度为O(n^2)。
31+
题意是寻找出字符串中最长的回文串,所谓回文串就是正序和逆序相同的字符串,也就是关于中间对称。我们先用最常规的做法,依次去求得每个字符的最长回文,要注意每个字符有奇数长度的回文串和偶数长度的回文串两种情况,相信你可以很轻易地从如下代码中找到相关代码,记录最长回文的始末位置即可,时间复杂度的话,首先要遍历一遍字符串,然后对每个字符都去求得最长回文,所以时间复杂度为 `O(n^2)`
3232

3333
```java
3434
class Solution {
@@ -58,15 +58,48 @@ class Solution {
5858
}
5959
```
6060

61-
## 思路1
6261

62+
## 思路1
6363

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

6570
```java
66-
71+
class Solution {
72+
public String longestPalindrome(String s) {
73+
int len = s.length();
74+
if (len <= 1) return s;
75+
int st = 0, end = 0;
76+
char[] chars = s.toCharArray();
77+
boolean[][] dp = new boolean[len][len];
78+
for (int i = 0; i < len; i++) {
79+
dp[i][i] = true;
80+
for (int j = 0; j < i; j++) {
81+
if (j + 1 == i) {
82+
dp[j][i] = chars[j] == chars[i];
83+
} else {
84+
dp[j][i] = dp[j + 1][i - 1] && chars[j] == chars[i];
85+
}
86+
if (dp[j][i] && i - j > end - st) {
87+
st = j;
88+
end = i;
89+
}
90+
}
91+
}
92+
return s.substring(st, end + 1);
93+
}
94+
}
6795
```
6896

6997

98+
## 思路2
99+
100+
最后一种思路那就是 `Manacher's Algorithm`,中文名叫马拉车算法,该算法就是专为解决此问题而发明的。
101+
102+
70103
## 结语
71104

72105
如果你同我一样热爱数据结构、算法、LeetCode,可以关注我GitHub上的LeetCode题解:[awesome-java-leetcode][ajl]

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

+39-14
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,55 @@
99
* </pre>
1010
*/
1111
public class Solution {
12-
int st, end;
12+
// int st, end;
13+
//
14+
// public String longestPalindrome(String s) {
15+
//// st = 0;
16+
//// end = 0;
17+
// int len = s.length();
18+
// if (len <= 1) return s;
19+
// char[] chars = s.toCharArray();
20+
// for (int i = 0; i < len; i++) {
21+
// helper(chars, i, i);
22+
// helper(chars, i, i + 1);
23+
// }
24+
// return s.substring(st, end + 1);
25+
// }
26+
//
27+
// private void helper(char[] chars, int l, int r) {
28+
// while (l >= 0 && r < chars.length && chars[l] == chars[r]) {
29+
// --l;
30+
// ++r;
31+
// }
32+
// if (end - st < r - l - 2) {
33+
// st = l + 1;
34+
// end = r - 1;
35+
// }
36+
// }
1337

1438
public String longestPalindrome(String s) {
1539
int len = s.length();
1640
if (len <= 1) return s;
41+
int st = 0, end = 0;
1742
char[] chars = s.toCharArray();
43+
boolean[][] dp = new boolean[len][len];
1844
for (int i = 0; i < len; i++) {
19-
helper(chars, i, i);
20-
helper(chars, i, i + 1);
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+
}
2157
}
2258
return s.substring(st, end + 1);
2359
}
2460

25-
private void helper(char[] chars, int l, int r) {
26-
while (l >= 0 && r < chars.length && chars[l] == chars[r]) {
27-
--l;
28-
++r;
29-
}
30-
if (end - st < r - l - 2) {
31-
st = l + 1;
32-
end = r - 1;
33-
}
34-
}
35-
3661
public static void main(String[] args) {
3762
Solution solution = new Solution();
3863
System.out.println(solution.longestPalindrome("babad"));

0 commit comments

Comments
 (0)