回文串是面试常常遇到的问题(虽然问题本身没啥意义),本文就告诉你回文串问题的核心思想是什么。
首先,明确一下什:回文串就是正着读和反着读都一样的字符串。
比如说字符串 aba
和 abba
都是回文串,因为它们对称,反过来还是和本身一样。反之,字符串 abac
就不是回文串。
可以看到回文串的的长度可能是奇数,也可能是偶数,这就添加了回文串问题的难度,解决该类问题的核心是双指针。下面就通过一道最长回文子串的问题来具体理解一下回文串问题:
一、思考
对于这个问题,我们首先应该思考的是,给一个字符串 s
,如何在 s
中找到一个回文子串?
有一个很有趣的思路:既然回文串是一个正着反着读都一样的字符串,那么如果我们把 s
反转,称为 s'
,然后在 s
和 s'
中寻找最长公共子串,这样应该就能找到最长回文子串。
比如说字符串 abacd
,反过来是 dcaba
,它的最长公共子串是 aba
,也就是最长回文子串。
但是这个思路是错误的,比如说字符串 aacxycaa
,反转之后是 aacyxcaa
,最长公共子串是 aac
,但是最长回文子串应该是 aa
。
虽然这个思路不正确,但是这种把问题转化为其他形式的思考方式是非常值得提倡的。
下面,就来说一下正确的思路,如何使用双指针。
寻找回文串的问题核心思想是:从中间开始向两边扩散来判断回文串。对于最长回文子串,就是这个意思:
我们使用两个指针来区别奇数和偶数场景
public static void main(String[] args) {
longestPalindrome lp =new longestPalindrome();
String lp2 = lp.lp("abcdcbedebcabcdefgfedcbaaaaaaa");
System.out.println(lp2);
}
private String lp(String txt) {
String res ="";
for (int i = 0; i < txt.length(); i++) {
// oushu
String s1 = rStr(txt, i, i);
// jishu
String s2 = rStr(txt, i, i+1);
res = res.length()>s1.length() ?res:s1;
res = res.length()>s2.length() ?res:s2;
}
return res;
}
private String rStr(String str ,int l,int r) {
while(l>=0 && r<str.length() && str.charAt(l) == str.charAt(r)) {
l--;
r++;
}
return str.substring(l+1,r);
}