昔年浅巷

昔年浅巷

算法挑战-移动片段得到字符串

7
2024-10-19

LEETCODE-移动片段得到字符串

题目简述

给你两个字符串 starttarget ,长度均为 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 。

解题思路

1.先判断字符串除'_'以外的'L'、'R'顺序是否一致,若不一致,则直接返回false;

2.观察'L'只能向左移动,那么target与start相同位置上,target的'L'字符必不可能少于start;

3.观察'R'只能向右移动,那么target与start相同位置上,target的'R'字符必不可能大于start;

解题编码

public boolean canChange(String start, String target) {
        if (start.equals(target)){
            return true;
        }

        // 校验字符顺序是否一致
        String newStart = start.replace("_", "");
        String newTarget = target.replace("_", "");
        if (!newStart.equals(newTarget)){
            return false;
        }

        long targetR = 0;
        long targetL = 0;
        long startR = 0;
        long startL = 0;
        char[] targetCharArray = target.toCharArray();
        char[] startCharArray = start.toCharArray();
        long index = 0;
        for (int i = 0; i < targetCharArray.length; i++) {
            if (targetCharArray[i] != '_'){
                if (targetCharArray[i] == 'R'){
                    targetR++;
                    index = i;
                }

                if (targetCharArray[i] == 'L'){
                    targetL++;
                    index = i;
                }
            }

            if (startCharArray[i] != '_'){
                if (startCharArray[i] == 'R'){
                    startR++;
                    index = i;
                }

                if (startCharArray[i] == 'L'){
                    startL++;
                    index = i;
                }
            }

            if (index == i){
                // 观察'L'只能向左移动,那么target与start相同位置上,target的'L'字符必不可能少于start;
                // 观察'R'只能向右移动,那么target与start相同位置上,target的'R'字符必不可能大于start;
                if (targetL<startL || targetR>startR){
                    return false;
                }
            }
        }

        return true;
    }