持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情
777. 在LR字符串中交换相邻字符
在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时, 返回True。
样例1 :
输入: start = "RXXLRXRXL", end = "XRLXXRRLX"
输出: true
解释:
我们可以通过以下几步将start转换成end:
RXXLRXRXL ->
XRXLRXRXL ->
XRLXRXRXL ->
XRLXXRRXL ->
XRLXXRRLX
样例2 :
输入: start = "LXXLXRLXXL", end = "XLLXRXLXLX"
输出: false
解释:
我们可以通过以下几步将start转换成end:
思路
题目允许我们使用两种转换:
- 一个"LX"替换一个"XL"
- 或者用一个"XR"替换一个"RX"
说人话就是说,我们的L只能够向左移动,我们的R只能够向右移动
比如现在是 RXXXXXXX, 我们可以这样移动:
RXXXXXXX ->
XRXXXXXX ->
XXRXXXXX ->
XXXRXXXX ->
XXXXRXXX ->
我们的L则和R是相反的移动方式
现在考虑一下,如何做呢?
我们可以先忽略掉
X, 因为X在是可以忽略的,忽略完之和的字符串一定相等!
然后,我们在来考虑不合法的问题,也就是可能存在 L 向 右移动 R 向左移动
对于这一个的判断,你可以使用双指针来滑动做,也可以使用计数的方式来做
反正满足如下条件:
- 若字符是
L, 则start字符串左边的字符比end字符串右边的字符多 - 若字符是
R, 则start字符串左边的字符比end字符串右边的字符少
代码
class Solution {
public:
bool check(string& start, string& end) {
string a, b;
for (auto v : start) if (v != 'X') a.push_back(v);
for (auto v : end) if (v != 'X') b.push_back(v);
return a == b;
}
bool canTransform(string start, string end) {
if (!check(start, end)) return false;
int i = 0, j = 0, n = start.size();
while (i < n && j < n) {
while (i < n && start[i] == 'X') ++ i;
while (j < n && end[j] == 'X') ++ j;
if (i < n && j < n) {
if (start[i] != end[j]) return false;
int ch = end[j];
if (ch == 'L' && i < j) return false;
if (ch == 'R' && i > j) return false;
i ++, j ++;
}
}
return true;
}
};