5. 最长回文子串
首先用start和end记录开始和结尾位置,遍历每一个字符,对于每一个字符有两种情况,第一种情况,从一个字符中心扩展,得到len1,第二种情况,从两个字符中心扩展,得到len2,取最大值,用最大值更新之前得到的start和end,最后substring。
class Solution {
public String longestPalindrome(String s) {
if (s == null || s.length() < 1) return "";
int start = 0, end = 0;
for (int i = 0; i < s.length(); i++) {
int len1 = charExpand(s, i, i);
int len2 = charExpand(s, i, i + 1);
int len = Math.max(len1, len2);
if (len > end - start) {
start = i - (len - 1) / 2;
end = i + len / 2;
}
}
return s.substring(start, end + 1);
}
public int charExpand(String s, int l, int r) {
while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) {
l--;
r++;
}
return r - l - 1;
}
}
6. N 字形变换
方法一
class Solution {
public String convert(String s, int numRows) {
// 方法一:用矩阵进行模拟
int n=s.length(),r=numRows;
if(r==1||r>=n) return s;
// 模拟矩阵的列和周期
int t=2*r-2; // 周期
int c=(n+t-1)/t*(r-1); //列数
char [][]mat=new char[r][c];
for(int i=0,x=0,y=0;i<n;i++){
mat[x][y]=s.charAt(i);
if(i%t<r-1){
++x; // 向下移动
}else{
--x; // 向右上移动
++y;
}
}
// 打印用一个StringBuffer存
StringBuffer ans = new StringBuffer();
for (char[] row:mat) {
for (char ch:row) {
if (ch!=0) {
ans.append(ch);
}
}
}
return ans.toString();
}
}
方法二
class Solution {
public String convert(String s, int numRows) {
// 方法二:矩阵模拟的改进,直接一行一行的保存
int n=s.length(),r=numRows;
if(r==1||r>=n) return s;
StringBuffer[] mat = new StringBuffer[r];
for (int i = 0; i < r; ++i) {
mat[i] = new StringBuffer();
}
for(int i=0,x=0,t=2*r-2;i<n;i++){
mat[x].append(s.charAt(i));
if(i%t<r-1){
++x; // 向下移动
}else{
--x; // 向右上移动
}
}
// 打印用一个StringBuffer存
StringBuffer ans = new StringBuffer();
for (StringBuffer row:mat) {
ans.append(row);
}
return ans.toString();
}
}
方法三 最优 时间复杂度O(n) 空间复杂度O(n)
class Solution {
public String convert(String s, int numRows) {
//方法三:直接构造
if(numRows < 2) return s;
List<StringBuilder> rows = new ArrayList<StringBuilder>();
for(int i = 0; i < numRows; i++) rows.add(new StringBuilder());
int i = 0; // 行数标志
int flag = -1; // 往上走还是往下走的标志
for(char c : s.toCharArray()) {
rows.get(i).append(c);
if(i == 0 || i == numRows -1) flag = - flag; // 行首和行尾变向
i += flag;
}
StringBuilder res = new StringBuilder();
for(StringBuilder row : rows) res.append(row); // 连接每行
return res.toString();
}
}
7. 整数反转
可能反转后会大于max和min有两种情况,这两种情况,一,当前的res不能大于/小于 最大值除以10/最小值除以10,二,res等于当前的最大值除以10/最小值除以10而且最后的个位数字也有要要求。
class Solution {
public int reverse(int x) {
int res = 0;
while(x!=0) {
//每次取末尾数字
int tmp = x%10;
//判断是否 大于 最大32位整数 2的31次方=2147483648
if (res>Integer.MAX_VALUE/10 || (res==Integer.MAX_VALUE/10 && tmp>7)) {
return 0;
}
//判断是否 小于 最小32位整数
if (res<Integer.MIN_VALUE / 10 || (res==Integer.MIN_VALUE / 10 && tmp<-8)) {
return 0;
}
res = res*10 + tmp;
x /= 10;
}
return res;
}
}
8. 字符串转换整数 (atoi)
首先去除空格,再根据后续出现的正负号确定符号,再记录ans
class Solution {
public int myAtoi(String s) {
int sign = 1, ans = 0, index = 0;
char[] array = s.toCharArray();
while (index < array.length && array[index] == ' ') {
index ++;
}
if (index < array.length && (array[index] == '-' || array[index] == '+')) {
sign = array[index++] == '-' ? -1 : 1;
}
while (index < array.length && array[index] <= '9' && array[index] >= '0') {
int digit = array[index++] - '0';
if (ans > (Integer.MAX_VALUE - digit) / 10) {
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
ans = ans * 10 + digit;
}
return ans * sign;
}
}