You are given two strings a and b of the same length. Choose an index and split both strings at the same index, splitting a into two strings: aprefix and asuffix where a = aprefix + asuffix, and splitting b into two strings: bprefix and bsuffix where b = bprefix + bsuffix. Check if aprefix + bsuffix or bprefix + asuffix forms a palindrome.
When you split a string s into sprefix and ssuffix, either ssuffix or sprefix is allowed to be empty. For example, if s = “abc”, then “” + “abc”, “a” + “bc”, “ab” + “c” , and “abc” + “” are valid splits.
Return true if it is possible to form a palindrome string, otherwise return false.
Notice that x + y denotes the concatenation of strings x and y.
Example 1:
Input: a = “x”, b = “y”
Output: true
Explaination: If either a or b are palindromes the answer is true since you can split in the following way:
aprefix = “”, asuffix = “x”
bprefix = “”, bsuffix = “y”
Then, aprefix + bsuffix = “” + “y” = “y”, which is a palindrome.
Example 2:
Input: a = “abdef”, b = “fecab”
Output: true
Example 3:
Input: a = “ulacfd”, b = “jizalu”
Output: true
Explaination: Split them at index 3:
aprefix = “ula”, asuffix = “cfd”
bprefix = “jiz”, bsuffix = “alu”
Then, aprefix + bsuffix = “ula” + “alu” = “ulaalu”, which is a palindrome.
Example 4:
Input: a = “xbdef”, b = “xecab”
Output: false
Constraints:
1 <= a.length, b.length <= 105
a.length == b.length
a and b consist of lowercase English letters
最近抽到的都是这种思考10分钟编码两小时的题。一方面很讨厌做这种题,做出来也没什么成就感,一旦写完都不想回头多看哪怕一眼。但另一方面也深知之所以会这么讨厌这种题是因为很多基础的东西不扎实。所以哪怕烦得想砸电脑,一般也会坚持把题做完。
说回到这题, 假设:
a = “aaabbccc”
b = “cccbbaaa”
我们随便截取一下
a_prefix = “aa” a_suffix = “abbccc”
b_prefix = “cc” b_suffix = “cbbaaa”
我们再进一步把suffix切一下
a_prefix = “aa” a_middle = “abbc” a_suffix = “cc”
b_prefix = “cc” b_middle = “cbba” b_suffix = “aa”
看出点什么来了吗?
简单点说就是题目里要求的那种回文可以拆解为下面几种情况:
- a_middle本身是回文,且a_prefix == reverse(b_suffix),这样a_prefix + a_middle + b_suffix就是回文
- a_middle本身是回文,且b_prefix == reverse(a_suffix),这样b_prefix + a_middle + a_suffix就是回文
- b_middle本身是回文,且a_prefix == reverse(b_suffix),这样a_prefix + b_middle + b_suffix就是回文
- b_middle本身是回文,且b_prefix == reverse(a_suffix),这样b_prefix + b_middle + a_suffix就是回文
之所以要这样拆解是因为a_prefix == reverse(b_suffix)这类判断和a_middle为回文的判断的时间复杂度是O(Logn),并且后一步判断依依赖前一步的判断,只要其中一步不成立,那可以直接判断后面所剩的都不成立。
代码写的有点糙,脑子不够用,只能按照繁琐的来,简化一步脑子就转不过来了,大家凑活着看
impl Solution {
pub fn check_palindrome_formation(a: String, b: String) -> bool {
let a_chars: Vec<char> = a.chars().collect();
let b_chars: Vec<char> = b.chars().collect();
if a.len() % 2 == 0 {
let mut a_border = vec![false; a.len() / 2];
for i in 0..a.len() / 2 {
if a_chars[i] == b_chars[a.len() - i - 1] {
a_border[i] = true;
} else {
break;
}
}
if *a_border.last().unwrap() {
return true;
}
let mut b_border = vec![false; a.len() / 2];
for i in 0..a.len() / 2 {
if b_chars[i] == a_chars[a.len() - i - 1] {
b_border[i] = true;
} else {
break;
}
}
if *b_border.last().unwrap() {
return true;
}
let mut left = a.len() / 2 - 1;
let mut right = a.len() / 2;
loop {
if a_chars[left] == a_chars[right] {
if left == 0 {
return true;
}
if a_border[left - 1] || b_border[left - 1] {
return true;
}
left -= 1;
right += 1;
} else {
break;
}
}
let mut left = a.len() / 2 - 1;
let mut right = a.len() / 2;
loop {
if b_chars[left] == b_chars[right] {
if left == 0 {
return true;
}
if a_border[left - 1] || b_border[left - 1] {
return true;
}
left -= 1;
right += 1;
} else {
break;
}
}
} else {
let mut a_border = vec![false; a.len() / 2 + 1];
for i in 0..=a.len() / 2 {
if a_chars[i] == b_chars[a.len() - i - 1] {
a_border[i] = true;
} else {
break;
}
}
if *a_border.last().unwrap() {
return true;
}
let mut b_border = vec![false; a.len() / 2 + 1];
for i in 0..=a.len() / 2 {
if b_chars[i] == a_chars[a.len() - i - 1] {
b_border[i] = true;
} else {
break;
}
}
if *b_border.last().unwrap() {
return true;
}
let mut left = a.len() / 2;
let mut right = a.len() / 2;
loop {
if a_chars[left] == a_chars[right] {
if left == 0 {
return true;
}
if a_border[left - 1] || b_border[left - 1] {
return true;
}
left -= 1;
right += 1;
} else {
break;
}
}
let mut left = a.len() / 2;
let mut right = a.len() / 2;
loop {
if b_chars[left] == b_chars[right] {
if left == 0 {
return true;
}
if a_border[left - 1] || b_border[left - 1] {
return true;
}
left -= 1;
right += 1;
} else {
break;
}
}
}
false
}
}