力扣 777. 在LR字符串中交换相邻字符

题目来源:https://leetcode.cn/problems/swap-adjacent-in-lr-string/

大致题意:
给两个由 L、R、X 组成的字符串 start 和 end,其中字符串 start 中的 XL 可以被替换为 LX,RX 可以被替换为 XR。
求字符串 start 替换之后能否变成字符串 end

思路

已知第一个字符串中的 XL 可以被替换为 LX,RX 可以被替换为 XR

那么等价于在 L 左侧是 X 时,L 可以左移一位;R 右侧是 X 时,R 可以右移一位

那么什么情况下,L 需要左移呢?

举个例子,字符串 start 为 XXXLX,end 为 LXXXX,这时候就可以通过左移 start 中的 L 使 start 变为 end。而以下情况则不需要左移

  • start 为 XLXXX,end 为 XXLXX。start 中的 L 在 end 左侧,而 L 只能左移,此时 start 无法变为 end

同理,当 start 中有 R 在 end 左侧时,可以通过右移 R 使位置相同,将 start 变为 end。但是start 中 R 在 end 右侧时则不可以

还有一种情况

  • start 为 XRXLX,end 为 XLRXX。可以看到,在 R 右移时由于遇到右侧 的 L 会无法右移,L 左移时也会碰到 R 而无法左移,造成 start 无法变为 end

综合以上情况,可以使用双指针表示当前两个字符串的遍历位置,然后根据遍历位置的字符做如下判断。这里假设 idx1 表示 start 的遍历指针,idx2 表示 end 的遍历指针

  • 若 idx1 和 idx2 对应字符有一个为 X,则对应的指针 +1
  • 若 idx1 和 idx2 对应字符都不为 X。如果字符不相同,表示 L 遇到 R,或者 R 遇到 L,即 start 不能变为 end,直接返回 false;如果 idx1 对应字符为 L 且当前 idx1 指针在 idx2 左侧,或者 idx1 对应字符为 R 且当前 idx1 指针在 idx2 右侧,则为上述 start 不能变为 end 的条件,返回 false;否则,表示start 目前遍历的 L 和 R 移动后能与 end 对应位置一致,更新指针值
  • 若 idx1 已经等于 start 长度,或者 idx2 已经等于 end 长度,则更新对方的指针值,并且判读对方字符是否为 X,若不为 X 表示两字符串含有的 L 或者 R 数量不同,返回 false

具体看代码:

class Solution {
    public boolean canTransform(String start, String end) {
        int n = start.length();
        // 初始化指针值
        int idx1 = 0;
        int idx2 = 0;
        // 当有一个指针未到对应字符串末尾时,遍历检查
        while (idx1 < n || idx2 < n) {
        	// 若 start 已经遍历结束
            if (idx1 == n) {
            	// 判断 end 是否有非 X 字符
                if (end.charAt(idx2++) != 'X') {
                    return false;
                }
                continue;
            }
        	// 若 end 已经遍历结束
            if (idx2 == n) {
            	// 判断 start 是否有非 X 字符
                if (start.charAt(idx1++) != 'X') {
                    return false;
                }
                continue;
            }
            // 若双指针对应字符都不为 X
            if (start.charAt(idx1) != 'X' && end.charAt(idx2) != 'X') {
            	// 如果对应字符不相同,直接返回 false
                if (start.charAt(idx1) != end.charAt(idx2)) {
                    return false;
                }
                // 判断是否有 start L 在 end L 左侧
                // 或者 start R 在 end R 右侧的情况
                if ((start.charAt(idx1) == 'L' && idx1 < idx2) || (start.charAt(idx1) == 'R' && idx1 > idx2)) {
                    return false;
                }
                // 更新指针
                idx1++;
                idx2++;
            } else if (start.charAt(idx1) == 'X') {	// 更新对应位置为 X 的指针值
                idx1++;
            } else {
                idx2++;
            } 
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

三更鬼

谢谢老板!

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

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

打赏作者

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

抵扣说明:

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

余额充值