题目链接:力扣
思路:
一开始的思路是dp,依次移动每个字符串,进行dp遍历,只是想了一下,觉得太复杂了,不太可能这么做。后来又想,L和R虽然可以左右移动,但是他们的相对位置是不变的。
因此可以遍历原字符串,同时用left1和right1记录L字符和R字符的个数,只要遍历到原字符串有L和R,就从上次目标字符串的位置继续遍历目标字符串,用left2和right2记录目标字符串中L和R的个数(一开始是从0位置开始遍历)得到的第一个字符如果是L或者R的话,让对应的Left2和right2加一,然后比较left1和left2是否相等,right1和right2是否相等。如果不相等的话,就可以返回false了,直到遍历到最后,返回true。
但是这样的话,案例3:"_R"和“R_”过不了,虽然满足字符串的相对位置不变了,但是R是不能左移的,是不能右移的。为了解决这个问题,继续修改。当原字符串遍历到i时碰到了L或者R。目标字符串遍历到j时,碰到了L或者R,判断一下
- 如果是字符L的话,由于L只能向左移动,所以i>=j, 如果i<j,则返回false。
- 如果是字符R的话,由于R只能向右移动,所以i<=j,如果 i>j ,则返回false。
这样做的话,案例 "_______" “L_RR____"过不了,因为原字符串没有遍历到L或者R,所以压根不会遍历目标字符串,所以在while外部再写一个继续遍历目标字符串的循环,检查剩下的目标字符串是否还有L或者R字符,如果有的话,直接返回false,否则,返回true。
代码:
class Solution {
public boolean canChange(String start, String target) {
if(start.length()!=target.length()) {
return false;
}
int len = start.length()-1;
int left1 = 0, left2 = 0,right1 = 0,right2 =0;
int i = 0;
int j = 0;
while(i <= len) {
if(start.charAt(i)!='_') {
if(start.charAt(i) == 'L') {
left1++;
} else if(start.charAt(i) == 'R') {
right1++;
}
while(j <= len && target.charAt(j)=='_') {
j++;
}
if(j > len) {
return false;
}
if(target.charAt(j) == 'L') {
left2++;
if(j>i) {
return false;
}
j++;
} else if(target.charAt(j) == 'R'){
right2++;
if(j < i) {
return false;
}
j++;
}
if(left2!=left1 || right1 != right2) {
return false;
}
}
i++;
}
// 检查剩下的目标字符串是否有L或者R字符
while(j <= len) {
if(target.charAt(j) != '_') {
return false;
}
j++;
}
return true;
}
}