838. 推多米诺
n 张多米诺骨牌排成一行,将每张多米诺骨牌垂直竖立。在开始时,同时把一些多米诺骨牌向左或向右推。
每过一秒,倒向左边的多米诺骨牌会推动其左侧相邻的多米诺骨牌。同样地,倒向右边的多米诺骨牌也会推动竖立在其右侧的相邻多米诺骨牌。
如果一张垂直竖立的多米诺骨牌的两侧同时有多米诺骨牌倒下时,由于受力平衡, 该骨牌仍然保持不变。
就这个问题而言,我们会认为一张正在倒下的多米诺骨牌不会对其它正在倒下或已经倒下的多米诺骨牌施加额外的力。
给你一个字符串 dominoes 表示这一行多米诺骨牌的初始状态,其中:
dominoes[i] = 'L',表示第 i 张多米诺骨牌被推向左侧,
dominoes[i] = 'R',表示第 i 张多米诺骨牌被推向右侧,
dominoes[i] = '.',表示没有推动第 i 张多米诺骨牌。
返回表示最终状态的字符串。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/push-dominoes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
模拟(一)
import java.util.Scanner;
class Solution {
    /**
     * .L.R...LR..L..
     * LL.RR.LLRRLL..
     */
    public String pushDominoes(String dominoes) {
        if (dominoes == null || dominoes.length() == 0) {
            return dominoes;
        }
        int[] left = new int[dominoes.length()];
        int[] right = new int[dominoes.length()];
        for (int i = 0; i < dominoes.length(); ++i) {
            if (dominoes.charAt(i) == 'L') {
                right[i] = 0;
            } else if (dominoes.charAt(i) == 'R') {
                right[i] = 1;
            } else {
                if (i == 0 || right[i - 1] == 0) {
                    right[i] = 0;
                } else {
                    right[i] = right[i - 1] + 1;
                }
            }
        }
        for (int i = dominoes.length() - 1; i >= 0; --i) {
            if (dominoes.charAt(i) == 'R') {
                left[i] = 0;
            } else if (dominoes.charAt(i) == 'L') {
                left[i] = 1;
            } else {
                if (i == dominoes.length() - 1 || left[i + 1] == 0) {
                    left[i] = 0;
                } else {
                    left[i] = left[i + 1] + 1;
                }
            }
        }
        char[] ans = new char[dominoes.length()];
        for (int i = 0; i < ans.length; ++i) {
            if (left[i] == right[i]) {
                ans[i] = '.';
            } else if (left[i] == 0 && right[i] != 0) {
                ans[i] = 'R';
            } else if (right[i] == 0 && left[i] != 0) {
                ans[i] = 'L';
            } else {
                if (left[i] > right[i]) {
                    ans[i] = 'R';
                } else {
                    ans[i] = 'L';
                }
            }
        }
        return new String(ans);
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            System.out.println(new Solution().pushDominoes(in.next()));
        }
    }
}
BFS
import java.util.*;
class Solution {
    public String pushDominoes(String dominoes) {
        int n = dominoes.length();
        Deque<Integer> queue = new ArrayDeque<>();
        int[] time = new int[n];
        Arrays.fill(time, -1);
        List<Character>[] force = new List[n];
        for (int i = 0; i < n; i++) {
            force[i] = new ArrayList<>();
        }
        for (int i = 0; i < n; i++) {
            char f = dominoes.charAt(i);
            if (f != '.') {
                queue.offer(i);
                time[i] = 0;
                force[i].add(f);
            }
        }
        char[] res = new char[n];
        Arrays.fill(res, '.');
        while (!queue.isEmpty()) {
            int i = queue.poll();
            if (force[i].size() == 1) {
                char f = force[i].get(0);
                res[i] = f;
                int ni = f == 'L' ? i - 1 : i + 1;
                if (ni >= 0 && ni < n) {
                    if (time[ni] == -1) {
                        queue.offer(ni);
                        time[ni] = time[i] + 1;
                        force[ni].add(f);
                    } else if (time[ni] == time[i] + 1) {
                        force[ni].add(f);
                    }
                }
            }
        }
        return new String(res);
    }
}
双指针
class Solution {
    public String pushDominoes(String dominoes) {
        char[] s = dominoes.toCharArray();
        int n = s.length, i = 0;
        char left = 'L';
        while (i < n) {
            int j = i;
            while (j < n && s[j] == '.') { // 找到一段连续的没有被推动的骨牌
                j++;
            }
            char right = j < n ? s[j] : 'R';
            if (left == right) { // 方向相同,那么这些竖立骨牌也会倒向同一方向
                while (i < j) {
                    s[i++] = right;
                }
            } else if (left == 'R' && right == 'L') { // 方向相对,那么就从两侧向中间倒
                int k = j - 1;
                while (i < k) {
                    s[i++] = 'R';
                    s[k--] = 'L';
                }
            }
            left = right;
            i = j + 1;
        }
        return new String(s);
    }
}
    心之所向,素履以往 生如逆旅,一苇以航

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号