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: a_prefix
and a_suffix
where a = a_prefix + a_suffix
, and splitting b
into two strings: b_prefix
and b_suffix
where b = b_prefix + b_suffix
. Check if a_prefix + b_suffix
or b_prefix + a_suffix
forms a palindrome.
When you split a string s
into s_prefix
and s_suffix
, either s_suffix
or s_prefix
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
Example 2:
Input: a = "xbdef", b = "xecab"
Output: false
Example 3:
Input: a = "ulacfd", b = "jizalu"
Output: true
A brute force solution would be to iterate through all possible split points of the strings a
and b
, and for each split, check if a_prefix + b_suffix
or b_prefix + a_suffix
is a palindrome. This would involve creating substrings and reversing strings multiple times.
def is_palindrome(s):
return s == s[::-1]
def check_palindrome_formation_brute_force(a, b):
n = len(a)
for i in range(n + 1):
a_prefix = a[:i]
a_suffix = a[i:]
b_prefix = b[:i]
b_suffix = b[i:]
if is_palindrome(a_prefix + b_suffix) or is_palindrome(b_prefix + a_suffix):
return True
return False
O(n^2), where n is the length of the strings. The outer loop iterates n+1 times. Inside the loop, string concatenation takes O(n) time, and is_palindrome
takes O(n) time.
O(n), due to the creation of substrings.
The optimal approach involves a more efficient way to check for palindrome formation. The main idea is to check if there exists a split point such that the unmatched parts of the prefix and suffix are palindromes.
check(a, b)
that checks if a split exists that forms a palindrome.left = 0
and right = n - 1
. Compare a[left]
and b[right]
. If they are equal, increment left
and decrement right
. Continue until left >= right
or a mismatch is found.left >= right
, the whole string is a palindrome. If a mismatch is found, check if either a[left:right+1]
or b[left:right+1]
is a palindrome. If either one is, then return True
.a
and b
, and another time with b
and a
.def is_palindrome_range(s, left, right):
while left < right:
if s[left] != s[right]:
return False
left += 1
right -= 1
return True
def check(a, b):
left = 0
right = len(a) - 1
while left < right and a[left] == b[right]:
left += 1
right -= 1
if left >= right:
return True
return is_palindrome_range(a, left, right) or is_palindrome_range(b, left, right)
def check_palindrome_formation(a, b):
return check(a, b) or check(b, a)
O(n), where n is the length of the strings. The check
function iterates through the strings at most once. The is_palindrome_range
function also takes at most O(n) time.
O(1). The algorithm uses a constant amount of extra space.
a
matches the reversed second half of b
, or vice versa.