Skip to content

Commit 40213a0

Browse files
committed
三刷5
1 parent 6ff429f commit 40213a0

File tree

3 files changed

+132
-18
lines changed

3 files changed

+132
-18
lines changed

docs/0005-longest-palindromic-substring.adoc

+36-18
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,34 @@
11
[#0005-longest-palindromic-substring]
2-
= 5. Longest Palindromic Substring
2+
= 5. 最长回文子串
33

4-
{leetcode}/problems/longest-palindromic-substring/[LeetCode - Longest Palindromic Substring^]
4+
https://leetcode.cn/problems/longest-palindromic-substring/[LeetCode - 5. 最长回文子串 ^]
55

6-
Given a string *s*, find the longest palindromic substring in *s*. You may assume that the maximum length of *s* is 1000.
6+
给你一个字符串 `+s+`,找到 `+s+` 中最长的 回文 子串。
77

8-
.Example 1:
9-
[subs="verbatim,quotes,macros"]
10-
----
11-
*Input:* "babad"
12-
*Output:* "bab"
13-
*Note:* "aba" is also a valid answer.
14-
----
8+
*示例 1:*
9+
10+
....
11+
输入:s = "babad"
12+
输出:"bab"
13+
解释:"aba" 同样是符合题意的答案。
14+
....
15+
16+
*示例 2:*
17+
18+
....
19+
输入:s = "cbbd"
20+
输出:"bb"
21+
....
22+
23+
24+
*提示:*
25+
26+
* `+1 <= s.length <= 1000+`
27+
* `+s+` 仅由数字和英文字母组成
1528
16-
.Example 2:
17-
[subs="verbatim,quotes,macros"]
18-
----
19-
*Input:* "cbbd"
20-
*Output:* "bb"
21-
----
2229
23-
== 解题分析
30+
31+
== 思路分析
2432

2533
最简单的方式:使用两个指针,把字符串逐个"拆成"子串,然后留下最大子串即可。可惜,这种算法的时间复杂度是 O(n^3^)。
2634

@@ -32,7 +40,6 @@ image::images/0005-01.png[]
3240

3341
另外,这道题还可以练手动态规划。
3442

35-
3643
[[src-0005]]
3744
[tabs]
3845
====
@@ -53,8 +60,18 @@ include::{sourcedir}/_0005_LongestPalindromicSubstring.java[tag=answer]
5360
include::{sourcedir}/_0005_LongestPalindromicSubstring_2.java[tag=answer]
5461
----
5562
--
63+
64+
三刷::
65+
+
66+
--
67+
[{java_src_attr}]
68+
----
69+
include::{sourcedir}/_0005_LongestPalindromicSubstring_3.java[tag=answer]
70+
----
71+
--
5672
====
5773

74+
5875
== 参考资料
5976

6077
* https://www.geeksforgeeks.org/manachers-algorithm-linear-time-longest-palindromic-substring-part-1/[Manacher's Algorithm - Linear Time Longest Palindromic Substring - Part 1^]
@@ -69,5 +86,6 @@ include::{sourcedir}/_0005_LongestPalindromicSubstring_2.java[tag=answer]
6986
* https://leetcode.cn/problems/longest-palindromic-substring/solutions/9001/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-bao-gu/[5. 最长回文子串 - 详细通俗的思路分析,多解法^]
7087
* https://leetcode.cn/problems/longest-palindromic-substring/solutions/4299/zui-chang-hui-wen-zi-chuan-c-by-gpe3dbjds1/[5. 最长回文子串^]
7188
* https://leetcode.cn/problems/longest-palindromic-substring/solutions/7792/zhong-xin-kuo-san-dong-tai-gui-hua-by-liweiwei1419/[5. 最长回文子串 - 动态规划、中心扩散、Manacher 算法^]
89+
* https://leetcode.cn/problems/maximum-length-of-repeated-subarray/solutions/28583/wu-li-jie-fa-by-stg-2/[718. 最长重复子数组 - 滑动窗口解法^]
7290

7391

logbook/202406.adoc

+4
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,10 @@
919919
|{doc_base_url}/0718-maximum-length-of-repeated-subarray.adoc[题解]
920920
|❌ 动态规划。滑动窗口的解法也很妙!
921921
922+
|{counter:codes}
923+
|{leetcode_base_url}/longest-palindromic-substring/[5. Longest Palindromic Substring^]
924+
|{doc_base_url}/0005-longest-palindromic-substring.adoc[题解]
925+
|✅ 滑动窗口解法
922926
923927
|===
924928
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package com.diguage.algo.leetcode;
2+
3+
import java.util.Objects;
4+
5+
public class _0005_LongestPalindromicSubstring_3 {
6+
// tag::answer[]
7+
8+
/**
9+
* 相仿 718 题的思路。
10+
*
11+
* TODO 解法还有少许缺陷:142个用例,通过了140个。
12+
* abcdbbfcba 找不到合适的回文字符串。
13+
*
14+
* @author D瓜哥 · https://www.diguage.com
15+
* @since 2024-10-08 14:22:42
16+
*/
17+
public String longestPalindrome(String s) {
18+
if (Objects.isNull(s) || s.length() == 1) {
19+
return s;
20+
}
21+
return findMax(s, new StringBuilder(s).reverse().toString());
22+
}
23+
24+
private String findMax(String a, String b) {
25+
int length = b.length();
26+
String result = "";
27+
28+
// 处理 a 的头部 与 b 的尾部 的字符串
29+
for (int len = 1; len <= length; len++) {
30+
String temp = maxLength(a, 0, b, length - len, len);
31+
if (temp.length() > result.length() && isPalindromic(temp)) {
32+
result = temp;
33+
}
34+
}
35+
// 由于两个字符串长度相同,则不需要处理中间对其部分的处理
36+
// 这里的代码假设,a 短 b 长
37+
// for (int i = b.length() - a.length(); i >= 0; i--) {
38+
// String temp = maxLength(a, 0, b, i, a.length());
39+
// }
40+
41+
// 处理 a 的尾部 与 b 的头部
42+
for (int i = 1; i < length; i++) {
43+
String temp = maxLength(a, i, b, 0, length - i);
44+
if (temp.length() > result.length() && isPalindromic(temp)) {
45+
result = temp;
46+
}
47+
}
48+
49+
return result.isEmpty() ? null : result;
50+
}
51+
52+
private String maxLength(String a, int as, String b, int bs, int len) {
53+
int count = 0;
54+
StringBuilder temp = new StringBuilder();
55+
String result = "";
56+
for (int i = 0; i < len; i++) {
57+
if (a.charAt(as + i) == b.charAt(bs + i)) {
58+
count++;
59+
temp.append(a.charAt(as + i));
60+
if (temp.length() > result.length()) {
61+
result = temp.toString();
62+
}
63+
} else if (count > 0) {
64+
count = 0;
65+
temp = new StringBuilder();
66+
}
67+
}
68+
int sn = a.length();
69+
System.out.println(String.format("%3d %3d %3d %" + (as + len != a.length() ? "-" : "")
70+
+ sn + "s %" + (as + len == a.length() ? "-" : "") + sn + "s" + " %" + sn + "s",
71+
as, bs, len, a.substring(as, as + len), b.substring(bs, bs + len), result));
72+
return result;
73+
}
74+
75+
private boolean isPalindromic(String s) {
76+
int l = 0, r = s.length() - 1;
77+
while (l < r) {
78+
if (s.charAt(l) != s.charAt(r)) {
79+
return false;
80+
}
81+
l++;
82+
r--;
83+
}
84+
return true;
85+
}
86+
87+
// end::answer[]
88+
public static void main(String[] args) {
89+
new _0005_LongestPalindromicSubstring_3()
90+
.longestPalindrome("abcdbbfcba");
91+
}
92+
}

0 commit comments

Comments
 (0)