LeetCode探索(138):777-在LR字符串中交换相邻字符

175 阅读1分钟

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

题目

在一个由 '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
  • startend中的字符串仅限于'L', 'R''X'

思考

本题难度中等。

首先是读懂题意。 题目中给出了在一个由 'L' , 'R''X' 三个字符组成的字符串,我们的一次移动操作可以用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。判断当存在一系列移动操作使得start可以转换成end时, 返回true。否则返回false

需要注意的是,我们可以将'XL'替换成'LX',将'RX'替换成'XR',不能反过来操作!比如经过多次移动操作,我们可以实现:

  • 'XXXL' -> 'LXXX'

  • 'RXXX' -> 'XXXR'

  • 'RXXXL' -> 'XXRLX'

我们首先判断两个字符串的长度是否相等,不相等则一定无法通过移动操作实现转换。

接着,我们定义两个指针 i 和 j,分别指向两个字符串的索引。遍历两个字符串,跳过'X',直至字符不为'X',这样就找到了字符'L'或'R'的索引。此时,需要满足:

  • start[i] === end[j]

  • (start[i] === "L" && i >= j) || (start[i] === "R" && i <= j)

若满足,继续遍历字符串。当其中一个字符串遍历到了末尾,那么另一个字符串的其余字符只能都是'X'。若条件满足,返回true。若以上条件有一不满足,则返回false。

解答

方法一:双指针

/**
 * @param {string} start
 * @param {string} end
 * @return {boolean}
 */
var canTransform = function (start, end) {
  if (start.length !== end.length) {
    return false
  }
  const n = start.length
  let i = 0, j = 0
  while (i < n && j < n) {
    // 跳过'X',找到'L'或'R'的索引
    while (i < n && start[i] === "X") {
      i++
    }
    while (j < n && end[j] === "X") {
      j++
    }
    // 此时,需要满足:
    // start[i] === end[j]
    // (start[i] === "L" && i >= j) || (start[i] === "R" && i <= j)
    if (i < n && j < n) {
      if (start[i] !== end[j]) {
        return false
      }
      if ((start[i] === "L" && i < j) || (start[i] === "R" && i > j)) {
        return false
      }
      i++
      j++
    }
  }
  // 其中一个字符串遍历到了末尾
  while (i < n) {
    if (start[i] !== "X") {
      return false
    }
    i++
  }
  while (j < n) {
    if (end[j] !== "X") {
      return false
    }
    j++
  }
  return true
}

复杂度分析:

  • 时间复杂度:O(n),其中 n 是字符串 start 和 end 的长度。我们需要遍历两个字符串各一次。
  • 空间复杂度:O(1)。

参考