给你两个字符串 start 和 target ,长度均为 n 。每个字符串 仅 由字符 'L'、'R' 和 '_' 组成,其中:
- 字符
'L'和'R'表示片段,其中片段'L'只有在其左侧直接存在一个 空位 时才能向 左 移动,而片段'R'只有在其右侧直接存在一个 空位 时才能向 右 移动。 - 字符
'_'表示可以被 任意'L'或'R'片段占据的空位。
如果在移动字符串 start 中的片段任意次之后可以得到字符串 target ,返回 true ;否则,返回 false 。
示例 1:
输入: start = "_L__R__R_", target = "L______RR"
输出: true
解释: 可以从字符串 start 获得 target ,需要进行下面的移动:
- 将第一个片段向左移动一步,字符串现在变为 "L___R__R_" 。
- 将最后一个片段向右移动一步,字符串现在变为 "L___R___R" 。
- 将第二个片段向右移动散步,字符串现在变为 "L______RR" 。
可以从字符串 start 得到 target ,所以返回 true 。
示例 2:
输入: start = "R_L_", target = "__LR"
输出: false
解释: 字符串 start 中的 'R' 片段可以向右移动一步得到 "_RL_" 。
但是,在这一步之后,不存在可以移动的片段,所以无法从字符串 start 得到 target 。
示例 3:
输入: start = "_R", target = "R_"
输出: false
解释: 字符串 start 中的片段只能向右移动,所以无法从字符串 start 得到 target 。
提示:
n == start.length == target.length1 <= n <= 10^5start和target由字符'L'、'R'和'_'组成
思路
在写代码之前,先来看看满足题目要求的 start 和 target 应满足什么样的要求:
start和target中L和R的数量应该相等- 分别移除
start和target中的_,得到新的字符串s和t,s===t - 设
s[i]对应start中的下标为m,t[i]对应target的下标为n,- 如果
s[i]==='L',则m>=n - 如果
s[i]==='R',则m<=n
- 如果
理清了上面这些条件,我们可以用双指针求解,分别遍历 start 和 target,代码如下
解题
/**
* @param {string} start
* @param {string} target
* @return {boolean}
*/
var canChange = function (start, target) {
const n = start.length;
let i = 0;
let j = 0;
while (i < n && j < n) {
while (i < n && start[i] === "_") {
i++;
}
while (j < n && target[j] === "_") {
j++;
}
if (start[i] !== target[j]) {
return false;
} else if ((target[j] === "L" && j > i) || (target[j] === "R" && j < i)) {
return false;
}
i++;
j++;
}
while (i < n) {
if (start[i] !== "_") {
return false;
}
i++;
}
while (j < n) {
if (target[j] !== "_") {
return false;
}
j++;
}
return true;
};