通过替换给定对中的字符来检查字符串是否可以成为回文
给定一个字符串str和K对字符,任务是检查字符串str 是否可以成为回文,方法是将每对字符中的一个字符替换为另一个字符。
例子:
Input: str = “geeks”, K = 2, pairs = [[“g”, “s”], [“k”, “e”]]
Output: True
Explanation:
Swap ‘s’ of “geeks” with ‘g’ using pair [‘g’, ‘s’] = “geekg”
Swap ‘k’ of “geekg” with ‘e’ using pair [‘k’, ‘e’] = “geeeg”
Now the resultant string is a palindrome. Hence the output will be True.
Input: str = “geeks”, K = 1, pairs = [[“g”, “s”]]
Output: False
Explanation: Here only the first character can be swapped (g, s)
Final string formed will be : geekg, which is not a palindrome.
朴素方法:给定的问题可以通过创建一个无向图来解决,其中连接 (x, y) 的边表示字符x 和 y 之间的关系。
- 通过验证前半个字符和后半个字符来检查回文的条件。
- 如果不相等:
- 从第一个字符运行dfs并检查是否可以到达最后一个字符。
- 然后,检查第二个字符和倒数第二个字符,依此类推。
时间复杂度: O(N * M),其中N是目标字符串的大小, M是对数组的大小
辅助空间: O(1)
高效方法:借助以下想法可以有效地解决问题:
Use a disjoint set data structure where each pair [i][0] and pair [i][1] can be united under the same set and search operation can be done efficiently.
Instead of searching for the characters each time, try to group all the characters which are connected directly or indirectly, in the same set.
下面是上述方法的实现:
Python3
# Python code for the above approach:
class disjoint_set():
def __init__(self):
# string consist of only smallcase letters
self.parent = [i for i in range(26)]
self.rank = [1 for i in range(26)]
def find_parent(self, x):
if (self.parent[x] == x):
return x
self.parent[x] = self.find_parent(self.parent[x])
return (self.parent[x])
def union(self, u, v):
p1 = self.find_parent(u)
p2 = self.find_parent(v)
if (p1 != p2):
# rank of p1 smaller than p2
if(self.rank[p1] < self.rank[p2]):
self.parent[p1] = p2
elif(self.rank[p2] < self.rank[p1]):
self.parent[p2] = p1
# rank of p2 equal to p1
else:
self.parent[p2] = p1
self.rank[p1] += 1
def connected(self, w1, w2):
p1 = self.find_parent(w1)
p2 = self.find_parent(w2)
if (p1 == p2):
return True
return False
class Solution:
def solve(self, target, pairs):
size = len(target)
# Create a object of disjoint set
dis_obj = disjoint_set()
for (u, v) in pairs:
ascii_1 = ord(u) - ord('a')
ascii_2 = ord(v) - ord('a')
# Take union of both the characters
dis_obj.union(ascii_1, ascii_2)
left = 0
right = size-1
# Check for palindrome condition
# For every character
while(left < right):
s1 = target[left]
s2 = target[right]
# If characters not same
if (s1 != s2):
# Convert to ascii value between 0-25
ascii_1 = ord(s1) - ord('a')
ascii_2 = ord(s2) - ord('a')
# Check if both the words
# Belong to same set
if (not dis_obj.connected(ascii_1, ascii_2)):
return False
left += 1
right -= 1
# Finally return True
return (True)
if __name__ == '__main__':
target = "geeks"
pairs = [["g", "s"], ["e", "k"]]
obj = Solution()
ans = obj.solve(target, pairs)
if (ans):
print('true')
else:
print('false')
Javascript
true
时间复杂度: O(N)
辅助空间: O(1)