[每日一题] leetcode 777. 在LR字符串中交换相邻字符

160 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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;
    }
};