给你两个字符串 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
符合题意的有四种情况:
0. a本身是回文串; 1. b本身是回文串;2. a的开头加b的结尾是回文串;3. b的开头加a的结尾是回文串。
一开始按照这个思路写,力大砖飞,题是做出来了,但代码写的跟狗屎一样。
优化思路:
之所以写成屎一样的代码,是因为想要在一次遍历中结束,结果越搞越糟。
可以先判断一下a,b是否自身是回文串。第二次从判断失败的基础上再次判断a开头加b结尾,b开头加a结尾是否是回文串。
优化前代码:
class Solution { public boolean checkPalindromeFormation(String a, String b) { int p1 = 0; int p2 = a.length() - 1; // a自己就是回文串 boolean a1 = true; // b自己就是回文串 boolean b1 = true; // a的开头加b的结尾是回文串 boolean a2 = true; // b结尾部分比a的开头部分长 boolean a22 = true; // b的开头加a的结尾是回文串 boolean b2 = true; // a的结尾部分比b的开头部分长 boolean b22 = true; while (p1 < p2) { // a不是回文串 if (a1 && a.charAt(p1) != a.charAt(p2)) { a1 = false; } // b不是回文串 if (b1 && b.charAt(p1) != b.charAt(p2)) { b1 = false; } if (a2 && a.charAt(p1) != b.charAt(p2)){ int tem1 = p1; int tem2 = p2; while (tem1 < tem2) { if (a2 && a.charAt(tem1) != a.charAt(tem2)) { a2 = false; } if (a22 && b.charAt(tem1) != b.charAt(tem2)) { a22 = false; if (!a2) { break; } } tem1 ++; tem2 --; } if (a2 || a22) { return true; } } if (b2 && b.charAt(p1) != a.charAt(p2)) { int tem1 = p1; int tem2 = p2; while (tem1 < tem2) { if (b2 && b.charAt(tem1) != b.charAt(tem2)) { b2 = false; } if (b22 && a.charAt(tem1) != a.charAt(tem2)) { b22 = false; if (!b2) { break; } } tem1 ++; tem2 --; } if (b2 || b22) { return true; }; } if (!(a1 || a2 || b1 || b2)) { return false; } p1 ++; p2 --; } return true; } }
优化后代码(官解是真的强,直接放官解了):
class Solution { public boolean checkPalindromeFormation(String a, String b) { return checkConcatenation(a, b) || checkConcatenation(b, a); } public boolean checkConcatenation(String a, String b) { int n = a.length(); int left = 0, right = n - 1; while (left < right && a.charAt(left) == b.charAt(right)) { left++; right--; } if (left >= right) { return true; } return checkSelfPalindrome(a, left, right) || checkSelfPalindrome(b, left, right); } public boolean checkSelfPalindrome(String a, int left, int right) { while (left < right && a.charAt(left) == a.charAt(right)) { left++; right--; } return left >= right; } }
标签:力扣,right,charAt,1616,---,boolean,left,true,回文 From: https://www.cnblogs.com/allWu/p/17231799.html