刷题的日常-在LR字符串中交换相邻字符

72 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情

刷题的日常-2022年10月2号

一天一题,保持脑子清爽

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

来自leetcode的 777 题,题意如下:

在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时, 返回True。

理解题意

我们可以从题意中提取的条件如下:

  • 题目给出两个字符串,要求我们通过一系列的转换规则
    • "RX"可用"XR"进行替换
    • "XL"可用"LX"进行替换
  • 重复以上规则,如果最后start可以转为end,则返回true,否则返回false

做题思路

这里采用暴力解,从题意中不难看出,限定规则只是交换顺序,没有减少对应的字符数量,所以我们以开始可以判断所有的字符数量是否相等,如果不等直接返回false即可。
接下来逐个判断,如果不等,那么有几种情况:

  • 当前字符为 L,这种情况没办法替换,直接返回false即可
  • 当前是可替换字符 X 或 R
    • 如果下一个字符满足直接替换的话,那么直接替换即可
    • 如果下一个字符不满足替换规则,需要往前继续搜索,我们来看这样一个用例
      • "XXXXXLXXXX" 和 "LXXXXXXXXX",L 在中间出现,但是最终往前一直替换还是可以成功
      • 所以我们需要记住第一个不满足条件的点,等往前替换的时候再进行判断
    • 如果满足条件进行替换,需要将当前遍历的指针回溯,查看是否相等
  • 如果走完全程发现都相等,返回true即可。

代码实现

代码实现如下:

public class Solution {
    public boolean canTransform(String start, String end) {
        if (!checkCnt(start, end)) {
            return false;
        }

        char[] startChars = start.toCharArray();
        char[] endChars = end.toCharArray();
        int sIdx = 0, len = end.length(), cIdx = 0;

        while (sIdx < len) {
            if (startChars[sIdx] == endChars[sIdx]) {
                sIdx++;
                cIdx++;
                continue;
            }
            if (startChars[cIdx] == 'L' || cIdx == len - 1) {
                return false;
            }
            if (startChars[cIdx] == 'R') {
                if (startChars[cIdx + 1] != 'X') {
                    cIdx++;
                    continue;
                }
                startChars[cIdx] = 'X';
                startChars[cIdx + 1] = 'R';
                if (cIdx > 0 && startChars[cIdx - 1] == 'R') {
                    cIdx--;
                }
                continue;
            }
            if (startChars[cIdx] == 'X') {
                if (startChars[cIdx + 1] != 'L') {
                    cIdx++;
                    continue;
                }
                startChars[cIdx] = 'L';
                startChars[cIdx + 1] = 'X';
                if (cIdx > 0 && startChars[cIdx - 1] == 'X') {
                    cIdx--;
                }
            }

        }
        return true;
    }

    private boolean checkCnt(String start, String end) {
        if (start.length() != end.length()) {
            return false;
        }
        int x = 0, l = 0, r = 0;
        for (int i = 0; i < start.length(); i++) {
            char c = start.charAt(i);
            if (c == 'X') {
                x++;
            }
            if (c == 'L') {
                l++;
            }
            if (c == 'R') {
                r++;
            }
        }
        for (int i = 0; i < end.length(); i++) {
            char c = end.charAt(i);
            if (c == 'X') {
                x--;
            }
            if (c == 'L') {
                l--;
            }
            if (c == 'R') {
                r--;
            }
        }
        return x == 0 && l == 0 && r == 0;
    }
}

image.png