Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. 提供一个字符串s,找出其最长的回文子串
所谓的回文子串就是正序反序均一直的字符串,当然也可以这样理解:
选定字符串s,以其中轴为中心线,然后左右比较,在有限范围内,中心像两边同时遍历,元素均相等
- 1.首先提供两种编程算法:
public String getPailStr(String s){
int n = s.length();
String str = "";
int maxNums = 0;
List<Character> list = new ArrayList();
List<Character> keyList = new ArrayList();
int j = 0;
if(n == 1){
return s;
}
while(j < n){ //n
if(!list.contains(s.charAt(j))){
list.add(s.charAt(j++));//c--j:0;
}else{
int length = 0;
list.add(s.charAt(j));//continue next cc -- j=1;
for(int i = 0;i < list.size();i++){ //m
if(list.get(i) == s.charAt(j)){//i:0
keyList.clear();
length = list.size() - i;
if(length> maxNums){
keyList.clear();
for(int m = i;m < list.size();m++){// 0 2 ++
keyList.add(list.get(m)); //cc
}
if(revers(keyList))b{//2 //p
maxNums = keyList.size();
str = "";
for(char c:keyList){
str = str + c;
}
break;
}
}
}
}
j++;
}
}
return str;
}
public boolean revers(List list){
int middle = list.size()/2;
int i = 0;
int j = 0;
if(list.size() % 2 == 0){
i = middle -1;
j = middle;
}else if(list.size() % 2 == 1){
i = middle - 1;
j = middle + 1;
}
while(i >= 0 && j <= list.size() -1){
if(list.get(i--) == list.get(j++)){
continue;
}else{
return false;
}
}
return true;
}
这个时间复杂度最坏情况可以达到n*n*n,所以好汚疑问是一个比较差的实现 ok,那么优化下一种:
public String getPailStr(String s){
int n = s.length();
String str = "";
int maxNums = 0;
List<Character> list = new ArrayList();
List<Character> keyList = new ArrayList();
int j = 0;
if(n == 1){
return s;
}
while(j < n){
if(!list.contains(s.charAt(j))){
list.add(s.charAt(j++));//c--j:0;
}else{
int length = 0;
list.add(s.charAt(j));//continue next cc -- j=1;
for(int i = 0;i < list.size();i++){
if(list.get(i) == s.charAt(j)){//i:0
keyList.clear();
length = list.size() - i;
if(length> maxNums){
keyList.clear();
for(int m = i;m < list.size();m++){// 0 2 ++
keyList.add(list.get(m)); //cc
}
if(revers(keyList))b{//2
maxNums = keyList.size();
str = "";
for(char c:keyList){
str = str + c;
}
break;
}
}
}
}
j++;
}
}
// for(char c:tarList){
// str = str + c;
// }
return str;
}
public boolean revers(List list){
int middle = list.size()/2;
int i = 0;
int j = 0;
if(list.size() % 2 == 0){
i = middle -1;
j = middle;
}else if(list.size() % 2 == 1){
i = middle - 1;
j = middle + 1;
}
while(i >= 0 && j <= list.size() -1){
if(list.get(i--) == list.get(j++)){
continue;
}else{
return false;
}
}
return true;
}
这里是采用二分的一种思想实现,时间复杂度大概nlogn,所以比之前种好很多.