LeetCode777. 在LR字符串中交换相邻字符

在一个由 ‘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;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AlwaysDayOne

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值