头脑风暴

Swap Adjacent in LR String

  • 给定2个string, start and end, 只包含L, X, R char

  • 可以replace "XL" with "LX", replace "RX" with "XR", 求问start 是否能transform成end string

  • 一开始自然的想到了word ladder的思路,给定source and dest求问最短路径

  • 暴力写了个BFS结果TLE了

    • start: "XXRXXXXXXXRXRXXXLXXLXXLXXXXXRXXXXXXXXLXX"

    • end: "XXXRXXXXRXXXXXXRXXXLXXXXXXXLXXLXXRXXLXXX"

class Solution {
    public boolean canTransform(String start, String end) {
        if (start.equals(end)) return true;
        Queue<String> queue = new LinkedList<>();
        Set<String> visited = new HashSet<>();
        queue.offer(start);
        visited.add(start);
        while (!queue.isEmpty()) {
            String cur = queue.poll();
            for (int i = 0; i < cur.length() - 1; i++) {
                if (cur.substring(i, i + 2).equals("XL")) {
                    String next = cur.substring(0, i) + "LX" + cur.substring(i + 2);
                    if (next.equals(end)) return true;
                    if (visited.contains(next)) continue;
                    queue.offer(next);
                    visited.add(next);
                }
                if (cur.substring(i, i + 2).equals("RX")) {
                    String next = cur.substring(0, i) + "XR" + cur.substring(i + 2);
                    if (next.equals(end)) return true;
                    if (visited.contains(next)) continue;
                    queue.offer(next);
                    visited.add(next);
                }
            }
        }
        return false;
    }
}
  • 然后就去Discuss里看了其它答案,发现这题是个数学推演题

  • since we can only move R to the right RX->XR, move L to the left, XL->LX L and R can never cross each other

  • just skip X character and compare position of L and R in 2 strings

  • for start[i] = end[j] = L, check i>=j, 因为 L只能左移

  • start[i] = end[j] = R, check i<=j, 因为R只能右移

  • 转换成了two pointer

  • 这里有个非常tricky的case

    • start:"XXRXLXRXXX"

    • end: "XXRLXXXXXR"

  • 因为end的最后一个char是R, 但是start最后一个R之后还有一堆X, 所以不能简单的写while (p1 < n && p2 < n), 需要特殊处理p1==n和p2==n的情况

class Solution {
    public boolean canTransform(String start, String end) {
        if (start.length() != end.length()) return false;
        int n = start.length();
        int p1 = 0, p2 = 0;
        while (p1 <= n && p2 <= n) {
            while (p1 < n && start.charAt(p1) == 'X') p1++;
            while (p2 < n && end.charAt(p2) == 'X') p2++;
            if (p1 == n && p2 == n) return true;
            if (p1 == n) {
                while (p2 < n && end.charAt(p2) == 'X') p2++;
                return p2 == n;
            }
            if (p2 == n) {
                while (p1 < n && start.charAt(p1) == 'X') p1++;
                return p1 == n;
            }
            if (start.charAt(p1) != end.charAt(p2)) return false;
            if (start.charAt(p1) == 'L' && p1 < p2) return false;
            if (start.charAt(p1) == 'R' && p1 > p2) return false;
            p1++;
            p2++;
        }
        return p1 == n && p2 == n;
    }
}

Last updated

Was this helpful?