目录
2337. 移动片段得到字符串 - 力扣(LeetCode)
2337. 移动片段得到字符串 - 力扣(LeetCode)
解题思路
根据题目“L”只能向左移动,“R”只能向右移动。值得注意的是“L”和“R”为占位符,即不可互穿过。
基于此,如果我们提出非占位符“_”后,两个字符串序列应该一致。 所以,我们可以进行一次扫描。但是,"_"的位置对于我们的答案有所影响,所以我们不能真正的完全无视它。
策略1:碰撞(互扰) --> 保持原状
这里我们知道一个点。以示例1为例子,我们知道应该是“R”字符应该是按照顺序匹配的。但是,我们率先扫描到是左边的“R”。而在移动中间的字符时,我们“R”是收到影响的。但是我们使用一个策略就是假定“R”与“R”之间是可以互换的。那么我们先后匹配的问题就得以解决。
为了方便理解,我们举一个例子:
target = “__R_____R”
start = "R(1)R(2)_____"
为了方便说明,我们将start中的R做出标记以示区别。
步骤1:
start = “_R(2)R(1)____”
步骤2:
start = “__R(1)_____R(2)”
AC代码如下:
class Solution {
public:
bool canChange(string start, string target) {
int n = start.length();
int i = 0, j = 0;
while (i < n && j < n) {
while (i < n && start[i] == '_') {
i++;
}
while (j < n && target[j] == '_') {
j++;
}
if (i < n && j < n) {
if (start[i] != target[j]) {
return false;
}
char c = start[i];
if ((c == 'L' && i < j) || (c == 'R' && i > j)) {
return false;
}
i++;
j++;
}
}
while (i < n) {
if (start[i] != '_') {
return false;
}
i++;
}
while (j < n) {
if (target[j] != '_') {
return false;
}
j++;
}
return true;
}
};
可以说因为采取策略1,所以我们只需要一次扫描即可。当然 “越位” 情况是显然错误的。
策略2:两遍扫描
关注到“L”的匹配优先匹配左边,“R”的匹配优先匹配右边。如果你没有想到策略1。那么就可以试试策略2:两遍扫描。
AC代码:
class Solution {
public:
bool canChange(string start, string target) {
int len = start.size();
int i = 0, j = 0;
//判断L的位序是否正确
for (; i < len && j < len;i += 1, j += 1) {
while (i < len && start[i] == '_') i += 1;
while (j < len && target[j] == '_') j += 1;
if (i == len && j < len || i < len && j == len) return false;
if (i < len && j < len && start[i] != target[j]) return false;
if (i < len && start[i] == 'R') continue;
if (i < j) return false;
}
while (i < len) {
if (start[i] == 'L') return false;
i += 1;
}
while (j < len) {
if (target[j] == 'L') return false;
j += 1;
}
//判断R的位序是否正确
for (i = len - 1, j = len - 1; i >= 0 && j >= 0;i -= 1, j -= 1) {
while (i >= 0 && start[i] == '_') i -= 1;
while (j >= 0 && target[j] == '_') j -= 1;
if (i >= 0 && j < 0 || i < 0 && j >= 0) return false;
if (i >= 0 && j >= 0 && start[i] != target[j]) return false;
if (i >= 0 && start[i] == 'L') continue;
if (i > j) return false;
}
while (i >= 0) {
if (start[i] == 'R') return false;
i -= 1;
}
while (j >= 0) {
if (target[j] == 'R') return false;
j -= 1;
}
return true;
}
};