推多米诺

60 阅读1分钟

838. 推多米诺 - 力扣(LeetCode)

n 张多米诺骨牌排成一行,将每张多米诺骨牌垂直竖立。在开始时,同时把一些多米诺骨牌向左或向右推。

每过一秒,倒向左边的多米诺骨牌会推动其左侧相邻的多米诺骨牌。同样地,倒向右边的多米诺骨牌也会推动竖立在其右侧的相邻多米诺骨牌。

如果一张垂直竖立的多米诺骨牌的两侧同时有多米诺骨牌倒下时,由于受力平衡, 该骨牌仍然保持不变。

就这个问题而言,我们会认为一张正在倒下的多米诺骨牌不会对其它正在倒下或已经倒下的多米诺骨牌施加额外的力。

给你一个字符串 dominoes 表示这一行多米诺骨牌的初始状态,其中:

  • dominoes[i] = 'L',表示第 i 张多米诺骨牌被推向左侧,
  • dominoes[i] = 'R',表示第 i 张多米诺骨牌被推向右侧,
  • dominoes[i] = '.',表示没有推动第 i 张多米诺骨牌。

返回表示最终状态的字符串。

示例 1:

输入: dominoes = "RR.L"
输出: "RR.L"
解释: 第一张多米诺骨牌没有给第二张施加额外的力。

示例 2:

输入: dominoes = ".L.R...LR..L.."
输出: "LL.RR.LLRRLL.."

提示:

  • n == dominoes.length
  • 1 <= n <= 10^5
  • dominoes[i]'L''R''.'

思路

解本题是要确定初始状态为竖立(.)的多米诺骨牌的最终状态。他的状态只和他两端初始态不为竖立状态的骨牌有关。

  • 如果左边为L,右边为 R,左边往左倒,右边往右倒,中间的竖立骨牌不受影响。
  • 如果左边为L,右边为 L,左边往左倒,右边往左倒,中间的竖立骨牌往左倒。
  • 如果左边为R,右边为 L,左边往右倒,右边往左倒,中间的竖立骨牌根据到两边的距离不同,状态也不同。
    • 当左边距离小于右边距离,往右倒。
    • 当左边距离大于右边距离,往左倒。
    • 当左边距离等于右边距离,竖立。
  • 如果左边为R,右边为 R,左边往左倒,右边往左倒,中间的竖立骨牌往右倒。
  • 当起始的几张骨牌竖立时,如果右侧为R,不受影响,如果为L,往左倒
  • 当结束的几张骨牌竖立时,如果左侧为L,不受影响,如果为R,往右倒

解题

/**
 * @param {string} dominoes
 * @return {string}
 */
var pushDominoes = function (dominoes) {
  const n = dominoes.length;
  let i = 0;
  let start = "L";
  let chars = Array.from(dominoes);
  let end = "";
  while (i < n) {
    let j = i;
    while (j < n && dominoes[j] === ".") {
      j++;
    }
    end = dominoes[j] || "R";
    if (end === "R") {
      if (start === "R") {
        while (i < j) {
          chars[i] = "R";
          i++;
        }
      }
    } else {
      let mid = -1;
      if (start === "R") {
        mid = (i + j - 1) / 2;
      }
      while (i < j) {
        chars[i] = i < mid ? "R" : i > mid ? "L" : ".";
        i++;
      }
    }
    start = dominoes[j];
    i = j + 1;
  }
  return chars.join("");
};