777.在LR字符串中交换相邻字符
在一个由 ‘L’ , ‘R’ 和 ‘X’ 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时, 返回True。
L与R就表示L只能往左转,R只能往右转。即:XL→LX,RX→XR。
一开始卡了很久,试着把start完全按照规则转换后与end进行比较。无奈最后还是以失败告终。这种方法我尝试了从前往后、从后往前等等方法,都没能实现。
后来想到利用将字符串中的L与R都整合在一个check列表中进行比较,对比相同字符的相对位置。但是依然有个别测试用例无法通过,即:前后有两个L或R的情况。这种想法只能处理一些极端情况的测试用例。当然,这一部分也是非常有必要的,可以加入到整体算法中作为检查特例的一部分。
最后,还是参考了双指针法进行检查。这种方法是可行的,但是在遇到一些特别的测试用例时无法通过,因此就需要上面那个部分了。
同时,双指针法需要考虑指针是否超出界限的问题。
我的这个答案写的确实挺丑的,也花了一些时间来调试、填坑。想追求时间与空间,但实力不允许,还需要多学习、多刷题。
我的代码:
class Solution(object):
def canTransform(self, start, end):
"""
:type start: str
:type end: str
:rtype: bool
"""
check_start = []
check_end = []
for x in start:
if x != 'X':
check_start.append(x)
for y in end:
if y != 'X':
check_end.append(y)
if len(check_start) != len(check_end):
return False
else:
for i in range(len(check_start)):
if check_start[i] != check_end[i]:
return False
i, j = 0, 0
n = len(start)
while i < n and j < n:
while i < n and start[i] == 'X':
i += 1
while j < n and end[j] == 'X':
j += 1
if i == n or j == n:
return True
if start[i] != end[j]:
return False
if start[i] == 'L' and i < j:
return False
if start[i] == 'R' and i > j:
return False
i += 1
j += 1
return True