题目描述
给你两个字符串 a 和 b ,它们长度相同。请你选择一个下标,将两个字符串都在 相同的下标 分割开。由 a 可以得到两个字符串: aprefix 和 asuffix ,满足 a = aprefix + asuffix ,同理,由 b 可以得到两个字符串 bprefix 和 bsuffix ,满足 b = bprefix + bsuffix 。请你判断 aprefix + bsuffix 或者 bprefix + asuffix 能否构成回文串。
当你将一个字符串 s 分割成 sprefix 和 ssuffix 时, ssuffix 或者 sprefix 可以为空。比方说, s = “abc” 那么 “” + “abc” , “a” + “bc” , “ab” + “c” 和 “abc” + “” 都是合法分割。
如果 能构成回文字符串 ,那么请返回 true,否则返回 false 。
注意, x + y 表示连接字符串 x 和 y 。
示例 1:
输入:a = “x”, b = “y”
输出:true
解释:如果 a 或者 b 是回文串,那么答案一定为 true ,因为你可以如下分割:
aprefix = “”, asuffix = “x”
bprefix = “”, bsuffix = “y”
那么 aprefix + bsuffix = “” + “y” = “y” 是回文串。
示例 2:
输入:a = “abdef”, b = “fecab”
输出:true
示例 3:
输入:a = “ulacfd”, b = “jizalu”
输出:true
解释:在下标为 3 处分割:
aprefix = “ula”, asuffix = “cfd”
bprefix = “jiz”, bsuffix = “alu”
那么 aprefix + bsuffix = “ula” + “alu” = “ulaalu” 是回文串。
提示:
1 <= a.length, b.length <= 105
a.length == b.length
a 和 b 都只包含小写英文字母
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/split-two-strings-to-make-palindrome
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
分析
暴力解决,只需要取得所有的分割拼接后的字符串,然后判断此字符串和它的反转是否相等即可
代码
class Solution {
public boolean checkPalindromeFormation(String a, String b) {
int l = a.length();
if(l==1)
return true;
for(int i=0;i<l;i++){
if(judge(a.substring(0,i),b.substring(i)) || judge(b.substring(0,i),a.substring(i)) ){
return true;
}
}
return false;
}
public boolean judge(String x,String y){
StringBuffer sb = new StringBuffer(x+y);
StringBuffer ysb = new StringBuffer(sb);
return ysb.toString().equals(sb.reverse().toString());
}
}
发现超时了
重新分析
符合题意的回文字符串一定由三部分组成,分别是a的前部分,b的后部分或者b的前部分,a的后部分,以及中间部分。a的前部分和b的后部分一定是倒序相等的(比如xyz和zyx),中间部分有可能从a取,也有可能从b取,但是它们一定都是一个回文子串。
代码
class Solution {
public boolean checkPalindromeFormation(String a, String b) {
return checkConcatenation(a, b) || checkConcatenation(b, a);
}
//使用i,j两个指针,找到符合条件的a的前部分和b的后部分
//然后移动i,j使i~j是中间部分
public boolean checkConcatenation(String a, String b) {
int l=a.length();
int i=0,j=l-1;
while(i<j && a.charAt(i)==b.charAt(j)){//a的前部分=b的后部分的倒序
i++;
j--;
}
//假设中间部分来自a,判断该部分是否是回文字符串
int ai=i,aj=j;
while(ai<aj && a.charAt(ai)==a.charAt(aj)){
ai++;
aj--;
}
if(ai>=aj){
return true;
}
//假设中间部分来自b
int bi=i,bj=j;
while (bi<bj && b.charAt(bi)==b.charAt(bj)){
bi++;
bj--;
}
if(bi>=bj){
return true;
}
return false;
}
}