分割两个字符串得到回文串

题目描述

给你两个字符串 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;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值