每日一题:2337 移动片段得到字符串

给你两个字符串 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 。

思路:

1、暴力模拟,考虑start和target不同的时候的每种情况,针对不同的情况进行判断。具体可以看看code。

ac code:

class Solution {
    public boolean canChange(String start, String target) {
        int right = 0; // start之前还没有匹配上的R个数
        int left = 0;  // start之前还没有匹配上的L个数
        int n = start.length();
        for (int i=0;i<n;i++) {
            if (start.charAt(i) == target.charAt(i)) {
                // 如果是L,但是之前start还有R等待与target匹配,则return false
                if (start.charAt(i) == 'L' && right > 0) return false;
                else continue;
            }else {
                if (start.charAt(i) == 'L') {
                    // start是L,target是_,需要判断之前是否有没有匹配上的L
                    if (target.charAt(i) == '_' && left > 0) left -= 1;
                    else return false;
                } else if (start.charAt(i) == '_') {
                    // 同理
                    if (target.charAt(i) == 'L' && right == 0) left++;
                    else if (target.charAt(i) == 'R' && right > 0) right--;
                    else return false;
                } else {
                    // start是R,target是_,需要判断left有没有没有匹配上的
                    if (target.charAt(i) == '_' && left == 0) right++;
                    else return false;
                }
            }
        }
        return left == 0 && right == 0 ? true : false;
    }
}

2、双指针,我们可以想到,LR是可以进行移动的,那么其实‘_’就没有什么含义,因为LR的相对位置不会改变。

如果LR的相对位置不对,那么一定是false的

还有就是如果start是 ‘L___’而target是'___L'那么也是false

同理R也是一样

也就是说,start = L 的下标需要大于target的下标, start = R的下标需要小于target的下标。

ac code:

class Solution {
    public boolean canChange(String start, String target) {
        int n = start.length();
        int index1 = 0;
        int index2 = 0;
        while (index1 < n || index2 < n) {
            while (index1 < n && start.charAt(index1) == '_') index1++;
            while (index2 < n && target.charAt(index2) == '_') index2++;

            if (index1 == n || index2 == n) return index1 == n && index2 == n;

            if (start.charAt(index1) != target.charAt(index2) || (start.charAt(index1) == 'L' && index1<index2) || (start.charAt(index1) == 'R' && index1>index2)) {
                return false;
            }
            index1++;
            index2++;
        }
        return true;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值