您的位置:首页 > 其它

leetcode 回文问题小结

2017-01-05 16:48 176 查看

leetcode 回文问题小结

1.Palindrome Number

问题描述

判断数字是否是回文,空间复杂度O(1)。

解题思路

法一: 将数字转换成字符串,判断一个字符串是否是回文。

public boolean isPalindrome(int x) {
if(x < 0)
return false;
if(x == 0)
return true;
if(x/10==0)
return true;
String str = x + "";
int i = 0;
while(i < str.length()/2){
if(str.charAt(i)!=str.charAt(str.length()-1-i))
return false;
i++;
}
return true;
}


法二:获得reverse之后的数字,如果两个数字相同,则是回文。

public boolean isPalindrome(int x) {
if(x < 0)
return false;
if(x == 0)
return true;
if(x/10==0)
return true;

int pre = x;
int ret = 0;
while(x != 0){
ret = ret * 10 + x%10;
x /= 10;
}
return ret==pre ? true : false;
}


2.Palindrome Linked List

问题描述

判断单链表是不是回文,时间复杂度O(n),空间复杂度O(1)。

解题思路

将链表前一半反转,中间值为头指针,头变成尾,如果与后半部分相同,就是回文链表,会破坏链表结构。改进:用快慢指针求链表中点。

public boolean isPalindrome(ListNode head) {
if(head == null || head.next ==null)
return true;
int length = getLength(head);
int leftEnd = length/2;
ListNode pre = null;
for(int k = 0; k < leftEnd; k++){
ListNode var = head.next;
head.next = pre;
pre = head;
head = var;
}
if(length%2!=0)
head = head.next;
while(pre != null && head != null){
System.out.println(pre.val+":"+head.val);
if(pre.val != head.val){
return false;
}
pre = pre.next;
head = head.next;
}
return (pre == null && head == null) ? true : false;
}
public int getLength(ListNode head){
int count = 0;
while(head!=null){
count++;
head = head.next;
}
return count;
}


3.Shortest Palindrome

问题描述

给定一个字符串S,你可以通过在它前面添加字符将它转换为回文。 查找并返回通过执行此转换可以找到的最短回文。

解题思路

找到S中以字符串首位为开头的最长回文,将剩余部分反序后添加到S的头部。查找最长回文时,从中间向两边查找。

public String shortestPalindrome(String s) {
if(s.length()==0 ||s.length()==1)
return s;
String ret = "";
int center = (s.length()-1)/2;
for(int j = center; j>=0;j--){
if(s.charAt(j) == s.charAt(j+1))
if((ret = isPalindrome(s,j,j+1))!=null)
break;
if((ret = isPalindrome(s,j,j))!=null)
break;
}
return ret+s;
}

public String isPalindrome(String s,int left,int right) {
int i = 0;
for(; left-i>=0 && right+i<s.length();i++){
if(s.charAt(left-i) != s.charAt(right+i))
break;
}
if((left-i)>=0)
return null;
StringBuffer sb = new StringBuffer(s.substring(right+i));
return sb.reverse().toString();
}


4.Palindrome Partitioning

问题描述

给定一个字符串s,分割s使得分割的每个子字符串是一个回文。返回s的所有可能的回文分割。

解题思路

递归方法

List<List<String>> listAll = new ArrayList<>();
public List<List<String>> partition(String s) {

if(s == null || s.length() == 0)
return listAll;
List<String> var = new ArrayList<>();
if(s.length() == 1){
var.add(s);
listAll.add(var);
return listAll;
}else{
getPartition(s,var);
}
return listAll;
}

public void getPartition(String s, List<String> list){
if(s.length() == 0)
listAll.add(list);
if(s.length() == 1){
list.add(s);
listAll.add(list);
return;
}
int n = s.length();
for(int i = 1; i <= n; i++){
String str = s.substring(0,i);
if(isPalindrome(str)){
List<String> varList = new ArrayList<>();
if(list.size() != 0){
for(String varStr : list){
varList.add(varStr);
}
}
varList.add(str);
getPartition( s.substring(i,n),varList);
}
}
}

public boolean isPalindrome(String s){
if(s.length() == 1){
return true;
}
int i = 0, j = s.length() - 1;
while(i <= j){
if(s.charAt(i) != s.charAt(j))
return false;
i++;
j--;
}
return true;
}


优化后:

List<List<String>> resultLst;
ArrayList<String> currLst;
public List<List<String>> partition(String s) {
resultLst = new ArrayList<List<String>>();
currLst = new ArrayList<String>();
backTrack(s,0);
return resultLst;
}
public void backTrack(String s, int l){
if(currLst.size()>0 //the initial str could be palindrome
&& l>=s.length()){
List<String> r = (ArrayList<String>) currLst.clone();
resultLst.add(r);
}
for(int i=l;i<s.length();i++){
if(isPalindrome(s,l,i)){
if(l==i)
currLst.add(Character.toString(s.charAt(i)));
else
currLst.add(s.substring(l,i+1));
backTrack(s,i+1);
currLst.remove(currLst.size()-1);
}
}
}
public boolean isPalindrome(String str, int l, int r){
if(l==r) return true;
while(l<r){
if(str.charAt(l)!=str.charAt(r)) return false;
l++;r--;
}
return true;
}


5.Valid Palindrome

问题描述

给定一个字符串,确定它是否是回文的,仅仅考虑其中的数字和字符并忽略其他。

例如,

“A man, a plan, a canal: Pannama” 是回文的。

“race a car” 不是回文。

解题思路

定义空字符串是回文,将首位空格去掉,使用两个指针,头指针和尾指针,指向空格时跳过。

public boolean isPalindrome(String s) {
if(s.length()<=1)
return true;
int i = 0, j = s.length() - 1;
while(i <= j){
while(i<=j && !isAlNum(s.charAt(i))) i++;
while(i<=j && !isAlNum(s.charAt(j))) j--;
if(i <= j){
String str1 = s.charAt(i)+"";
String str2 = s.charAt(j)+"";
if(str1.compareToIgnoreCase(str2)!=0)
return false;
}
i++;
j--;
}
return true;
}

public boolean isAlNum(char  ch){
int asc = (int)ch;
if((asc >= 48 && asc <= 57) || (asc >= 65 && asc <= 90) || (asc >= 97 && asc <= 122))
return true;
return false;
}


法二:先将字符串的空格去掉,都变成小写格式

public boolean isPalindrome(String s) {
if(s == null)
return false;
s = s.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
if(s.length()<=1)
return true;
int i = 0, j = s.length() - 1;
while(i <= j){
if(s.charAt(i) != s.charAt(j))
return false;

i++;
j--;
}
return true;
}


6.Longest Palindrome

问题描述

给定一个由小写或大写字母组成的字符串,找到可以用这些字母构建的最长回文的长度。区分大小写,Aa不是

解题思路

字母出现偶数次的都可以加到回文中。奇数次的要-1。

public int longestPalindrome(String s) {
if(s == null)
return 0;
if(s.length()<=1)
return s.length();
HashMap<Character,Integer> map = new HashMap<>();
int sum = 0;
boolean flag = false;
for(int i = 0; i < s.length(); i++){
if(map.containsKey(s.charAt(i))){
map.put(s.charAt(i),map.get(s.charAt(i))+1);
}else{
map.put(s.charAt(i),1);

}
}
for(Integer value : map.values()){
if(value%2 == 0)
sum += value;
else{
flag = true;
sum += value - 1;
}
}
return flag ? sum + 1 : sum;
}


7.Longest Palindromic Substring

问题描述

给定一个字符串s,在s中找到最长的回文子串。 您可以假设s的最大长度为1000。 如 “babad” 的输出是 “bab”或者“aba”

解题思路

暴力求解:穷举思路:取出所有的子串,判断它是否回文,并返回最长的子串。

动态规划:用boolean[i][j]=true 表示字符串从i到j的子串是回文串,当 pali[i+1][j-1] == true && s.charAt(i)==s.charAt(j)时,pali[i][j] = true;否则为false

空间、时间复杂度 O(n2)

public String longestPalindrome(String s) {
//时间o(n2) 空间o(n2) 动态规划
if(s.length()==0 || s.length()==1)
return s;
int max = 0;
String ret = "";
boolean pali[][] = new boolean[s.length()][s.length()];
for(int i = 0; i < s.length(); i++){
for(int j = 0; j < s.length(); j++){
pali[i][j] = false;
}
}
for(int i = 0; i < s.length(); i++){
pali[i][i] = true;
if(i < (s.length()-1)){
if(s.charAt(i)==s.charAt(i+1))
pali[i][i+1] = true;
else{
pali[i][i+1] = false;
}
}

}
for(int i = s.length()-1; i >= 0; i--){
for(int j = s.length()-1; j >= i; j--){
if(pali[i][j] == true){
if(max < (j - i + 1)){
max = j - i + 1;
ret = s.substring(i,j+1);
}
continue;
}
if((j - i) ==1)
continue;
if( pali[i+1][j-1] == true && s.charAt(i)==s.charAt(j)){
pali[i][j] = true;
if(max < (j - i + 1)){
max = j - i + 1;
ret = s.substring(i,j+1);
}
}
else
pali[i][j] = false;
}
}
return ret;
}


Manacher算法:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  回文