在一个由 ‘L’ , ‘R’ 和 ‘X’ 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时, 返回True。
示例 :
输入: start = "RXXLRXRXL", end = "XRLXXRRLX"
输出: True
解释:
我们可以通过以下几步将start转换成end:
RXXLRXRXL ->
XRXLRXRXL ->
XRLXRXRXL ->
XRLXXRRXL ->
XRLXXRRLX
提示:
1 <= len(start) = len(end) <= 10000。
start和end中的字符串仅限于'L', 'R'和'X'。
解题思路
“LX"替换一个"XL” 表示 将L向左移动
“XR"替换一个"RX” 表示 将R向右移动
- 如果L的左侧有多个X,就可以一直向左移动
- 如果R的右侧有多个X,也可以一直向右移动
- 如果L的左侧遇到了R,就无法向左移动了
- 如果R的右侧遇到了L,就无法向右移动了
转化题意为 : 判断是否有左右LR互相阻挡
一次遍历判断是否可行:
- 从左到右遍历两个字符串,用r记录start中当前要右移R的个数,用l记录end中需要从start后面被左移过来的L
- 如果当前start[i] = R, r++,
- 如果当前end[i] = L, l++,
- 如果当前位置要右移的数量r>0,则一定R和L会冲突,一定不成立
- 如果当前end[i] = R, 则说明可以将start中已记录的R消除一个
- 若r>0即左侧有需要移动来的R,且l=0 没有需要左移发生冲突的 r–
- 否则 消除一个R
- 如果当前start[i] == 'L’需要左移,有l的话才能-1
- 最后判断l 和 r都已经消除完了即可
代码
class Solution {
public:
bool canTransform(string start, string end) {
int r = 0; // 可以往后移动的 R
int l = 0; // 需要往左移动的 L
for (int i = 0; i < start.size(); ++i) {
if (start[i] == 'R') ++ r; // 可以往后移动的 R 的个数 + 1
if (end[i] == 'L') {
if (r) return false;
++ l; // 需要被匹配的 L 个数 + 1
} else if (end[i] == 'R') {
if (l || r == 0) return false;
-- r;
}
if (start[i] == 'L') {
if (l == 0) return false; // 前面如果没有需要匹配的 L 那么 start[i] 将不可能被匹配
-- l;
}
}
return l == 0 && r == 0;
}
};