给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba”也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
这道题最直接的解法就是中心扩散法,即从每个字符或者每个两个字符间开始判断左右两边是否相等,不过时间复杂度太高,最适合的还是Manacher算法,此算法在中心扩散算法的基础上,通过简化一下重复判断操作使其时间复杂度为O(N)。具体的方法是利用之前判断的回文串的对称性省略一些不必要的判断。
class Solution {
public String longestPalindrome(String s) {
StringBuilder str = new StringBuilder("!#");
for(int i=0;i"#");
}
str.append("@");
String t = str.toString();
int p[] = new int[t.length()];
int right=0,center=0,resCenter=0,resLength=0;
for(int i=1;i1;i++){
p[i] = right>i?Math.min(p[2*center-i],right-i):1;
while(t.charAt(i+p[i])==t.charAt(i-p[i]))++p[i];
if(right < i+p[i]){
right = i+p[i];
center = i;
}
if(resLengthint start = (resCenter-resLength)/2;
return s.substring(start,start+resLength-1);
}
}
将字符串 “PAYPALISHIRING” 以Z字形排列成给定的行数:
P A H N
A P L S I I G
Y I R
之后从左往右,逐行读取字符:”PAHNAPLSIIGYIR”
实现一个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入: s = “PAYPALISHIRING”, numRows = 3
输出: “PAHNAPLSIIGYIR”
示例 2:
输入: s = “PAYPALISHIRING”, numRows = 4
输出: “PINALSIGYAHRPI”
解释:
P I N
A L S I G
Y A H R
P I
首先字符串是排列的是一个躺着的Z字形其实说成是N字形更为明显,多看看示例不难会发现一点特征。N字形是循环排列的,一个循环周期数为2*numRows-2;那么只需要抓住一个周期的特点即可解决问题。对于第一行和最后一行的数来说,直接从第一个数开始加上一个循环周期既可以得到对应的下一个数。而中间的几行每一行对应两个数,而且自上而下每一行的两个数下标只差为2*numRows-2*(行号+1),这里行号从0开始到numRows-1。那么利用这个周期特征就可以完成每一行字符的提取,然后自上而下提取所有行,即可得到结果
其中num为一个周期内包含的字符个数,temp为获取当前周期内此行对应了下一个字符(只有第一行和最后一行中间的行的才有下一个字符)。第一层循环是行号循环,第二层循环是层次循环获取每一行中所有的字符。
class Solution {
public String convert(String s, int numRows) {
if(numRows<=1)
return s;
int num = 2*numRows-2;
StringBuilder str = new StringBuilder();
for(int i=0;ifor(int j=i;jstr.append(s.charAt(j));
int temp = j+num-2*i;
if(i!=0&&i!=numRows-1&&tempstr.append(s.charAt(temp));
}
return str.toString();
}
}
给定一个 32 位有符号整数,将整数中的数字进行反转。
示例 1:
输入: 123
输出: 321
示例 2:
输入: -123
输出: -321
示例 3:
输入: 120
输出: 21
注意:
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。根据这个假设,如果反转后的整数溢出,则返回 0。
这道思路很简单通过对输入值每位数拆分再重组即可达到反转的效果。但是需要注意的点就是反转溢出,比如int的最大值是2147483647,反转之后为7463847412,明显已经超过int值的取值范围,那么需要返回0,我这里直接通过使用long类型来存储,在反转之后判断是否溢出,如果溢出则返回0,反之就返回反转后的数字。
class Solution {
public int reverse(int x) {
long num = Math.abs(x);
boolean flag = x<0;
long res=0;
while(num>0){
res = res*10+num%10;
num/=10;
}
if(!flag&&res>Integer.MAX_VALUE
||flag&&res*-1return 0;
}
return flag?(int)(-1*res):(int)res;
}
}