LWC 70: 777. Swap Adjacent in LR String

LWC 70: 777. Swap Adjacent in LR String

传送门:777. Swap Adjacent in LR String

Problem:

In a string composed of ‘L’, ‘R’, and ‘X’ characters, like “RXXLRXRXL”, a move consists of either replacing one occurrence of “XL” with “LX”, or replacing one occurrence of “RX” with “XR”. Given the starting string start and the ending string end, return True if and only if there exists a sequence of moves to transform one string to the other.

Example:

Input: start = “RXXLRXRXL”, end = “XRLXXRRLX”
Output: True
Explanation:
We can transform start to end following these steps:
RXXLRXRXL ->
XRXLRXRXL ->
XRLXRXRXL ->
XRLXXRRXL ->
XRLXXRRLX

Note:

  • 1 <= len(start) = len(end) <= 10000.
  • Both start and end will only consist of characters in {‘L’, ‘R’, ‘X’}.

思路:
初始想法:暴力搜索,遇到”XL”,且对应位置不相等的情况,就replace成”LX”, 而且一旦replace之后,它不再可逆,所以最终一定能够自动终止,在所有可能的replace中,找出end态,可惜DFS超时,所以代码也就不上了。

参考了top10的代码,清一色统计个数,很巧妙,先上代码:

     public boolean canTransform(String start, String end) {
         if (!start.replace("X", "").equals(end.replace("X", ""))) return false;
         char[] s = start.toCharArray();
         char[] e = end.toCharArray();
         int n = s.length;
         int i = 0, j = 0;
         while (i < n && j < n) {
             while (j < n && e[j] == 'X') j ++;
             while (i < n && s[i] == 'X') i ++;
             if (i == n || j == n) break;
             if (s[i] == 'R' && i > j) return false;
             if (s[i] == 'L' && i < j) return false;
             i ++;
             j ++;
         }
         return true;
     }

第一行容易理解,去除X之后,只剩L和R,它们的位置是严格对应的,不对应返回false。因为只有两种replace模式,RX -> XR 和XL -> LX,所以无论如何都不会出现LR,变成RL的情况。而X的出现只是可以让R或者L可以左右浮动到相应的位置而已。

比如:

start = XXXXXL
end   = LXXXXX

L只需要有能力浮动到第一个位置即可,显然没问题。

嘿,这个能力如何体现呢?我们依次比较对应的L的坐标,比如上述例子中:
L 在 start 的坐标为: 5
L 在 end   的坐标为: 0

因为L只能往左走,5 > 0 刚好满足向左走的条件,因此有能力从 start -> end

再看:
start = XXLXXX
end   = XXXXXL

L 在 start 的坐标为: 2
L 在 end   的坐标为: 5

因为L只能往左走,显然在这个例子中,它丧失了replace的能力,只能返回false了

再来看:
start = XRXXXXXL
end   = XXRXXXLX

同理找出R所在的坐标:
R 在 start 的坐标为: 1
R 在 end   的坐标为: 2

因为R只能往右走,所以该例子是可以replace的。不过,需要注意的是:为啥不需要关注R后面是否有足够的X呢?

比如:
start = XRLXXXXX
end   = XXRXXXLX

在这种情况下,R是没有replace能力的,被L给卡住了,不过没有关系,虽然错过了R的判断。
在后续判断L时,在end中R所在的位置,end中L的位置至少在R的后一格。
start中的R丧失replace能力时,L的位置只可能在start的R 和 end R之间,而end中L的位置在end R之后,那么start 中的L 的位置是显然大于 end L中的位置,因此在下一个L中就能把前面的误判给纠出来。

Python版本:

class Solution(object):
    def canTransform(self, start, end):
        """
        :type start: str
        :type end: str
        :rtype: bool
        """
        n = len(start)
        i = j = 0
        while i < n and j < n:
            while (j < n and end[j] == 'X'): j += 1
            while (i < n and start[i] == 'X'): i += 1
            if i == n and j == n: break
            if i == n or j == n or end[j] != start[i]: 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值