有关回文的编程题总结
题目一:给定一个字符串 s
,找到 s
中最长的回文子串。你可以假设 s
的最大长度为 1000。
解法一:中心扩展法
使用中心扩展法:由于回文字符串有可能是偶数个字符,也有可能是奇数个字符,所以回文子串的中心有可能是一个字符也有可能是字符中间位置。所以需要遍历字符串s的左右中心点,判断是否为回文子串。
import java.util.Scanner;
public class Solution{
public static int expandAroundCenter(String s, int left, int right){
int l = left;
int r = right;
//由中心向两边延伸,两端字符相同继续延伸,不相同则返回回文子串的长度。
while(l >= 0 && r < s.length() && s.charAt(l)==s.charAt(r)){
l--;
r++;
}
return r-l-1;
}
public static String longestPalindrome(String s){
if(s.length() < 1 || s == null){
return "";
}
int start = 0;
int end = 0;
for(int i = 0; i < s.length(); i++){
int len1 = expandAroundCenter(s, i, i) ;//回文子串中心为i位置的字符
int len2 = expandAroundCenter(s, i, i+1);//回文中心在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 static void main(String[] args) {
Scanner input = new Scanner (System.in);
String s = input.nextLine();
System.out.println(longestPalindrome(s));
}
}
解法二:暴力算法
暴力算法
暴力法将选出所有子字符串可能的开始和结束位置,并检验它是不是回文
public class Solution {
public String longestPalindrome(String s){
String result = "";
for (int i = 0; i < s.length(); i++) {
for (int j = i+1; j < s.length(); j++) {
String temp1 = s.substring(i,j);
String temp2 = reverse(temp1);
if(temp1.equals(temp2) && result.length()<temp1.length()){
result = temp1;
}
}
}
return result;
}
/**
* 使用StringBuilder或者StringBuffer的reverse方法实现String的反转
* @param s
* @return s反转后的字符串
*/
public String reverse(String s){
return new StringBuilder(s).reverse().toString();
}
}
解法三:动态规划
public class Solution2 {
public String longestPalindrome(String s) {
boolean [][] p = new boolean[s.length()][s.length()];
String maxPalindrome = "";
for (int i = 0; i < s.length(); i++) {
for (int start = 0; start < s.length(); start++) {
int end = start + i;
if (end >= s.length()){
break;
}
//i==0和i==1是初始化单个回文字符串和两个字符的回文字符串
p[start][end] = (i == 0 || i == 1 || p[start + 1][end - 1]) && s.charAt(start) == s.charAt(end);
if (p[start][end] && i > maxPalindrome.length()) {
maxPalindrome = s.substring(start, end + 1);
}
}
}
return maxPalindrome;
}
}
题目二:判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
要考虑负数,个位数是0的数字直接就不是回文数字
我们获取数字的一半,反转后半部分的一半,如果和前半部分相似就确定为回文数字
关于奇数位的数字,通过最后partlyNumber/10==x;
除以10将中间的位数去掉,因为中间的数字一定等于其本身,不影响其是不是回文数。
public class Solution {
public boolean isPalindrome(int x) {
if(x < 0||(x!=0&& x%10==0)){
return false;
}else{
int partlyNumber = 0;
while (x > partlyNumber){
partlyNumber = partlyNumber*10+x%10;
x/= 10;
}
return partlyNumber==x||partlyNumber/10==x;
}
}
}