838. 推多米诺
n
张多米诺骨牌排成一行,将每张多米诺骨牌垂直竖立。在开始时,同时把一些多米诺骨牌向左或向右推。
每过一秒,倒向左边的多米诺骨牌会推动其左侧相邻的多米诺骨牌。同样地,倒向右边的多米诺骨牌也会推动竖立在其右侧的相邻多米诺骨牌。
如果一张垂直竖立的多米诺骨牌的两侧同时有多米诺骨牌倒下时,由于受力平衡, 该骨牌仍然保持不变。
就这个问题而言,我们会认为一张正在倒下的多米诺骨牌不会对其它正在倒下或已经倒下的多米诺骨牌施加额外的力。
给你一个字符串 dominoes
表示这一行多米诺骨牌的初始状态,其中:
dominoes[i] = 'L'
,表示第 i
张多米诺骨牌被推向左侧,dominoes[i] = 'R'
,表示第 i
张多米诺骨牌被推向右侧,dominoes[i] = '.'
,表示没有推动第 i
张多米诺骨牌。返回表示最终状态的字符串。
示例 1:
输入:dominoes = "RR.L" 输出:"RR.L" 解释:第一张多米诺骨牌没有给第二张施加额外的力。
示例 2:
输入:dominoes = ".L.R...LR..L.." 输出:"LL.RR.LLRRLL.."
提示:
n == dominoes.length
1 <= n <= 105
dominoes[i]
为 'L'
、'R'
或 '.'
原站题解
python3 解法, 执行用时: 176 ms, 内存消耗: 18.4 MB, 提交时间: 2022-12-09 12:42:20
class Solution: def pushDominoes(self, d: str) -> str: d = "L" + d + "R" res = [] l = 0 for r in range(1, len(d)): if d[r] == '.': continue mid = r - l - 1 if l: # 虚拟的牌不放入结果 res.append(d[l]) if d[l] == d[r]: res.append(d[l] * mid) elif d[l] == 'L' and d[r] == 'R': res.append('.' * mid) else: res.append('R' * (mid // 2) + '.' * (mid % 2) + 'L' * (mid // 2)) l = r return "".join(res)
golang 解法, 执行用时: 56 ms, 内存消耗: 16.4 MB, 提交时间: 2022-12-09 12:41:10
func pushDominoes(dominoes string) string { n := len(dominoes) q := []int{} time := make([]int, n) for i := range time { time[i] = -1 } force := make([][]byte, n) for i, ch := range dominoes { if ch != '.' { q = append(q, i) time[i] = 0 force[i] = append(force[i], byte(ch)) } } ans := bytes.Repeat([]byte{'.'}, n) for len(q) > 0 { i := q[0] q = q[1:] if len(force[i]) > 1 { continue } f := force[i][0] ans[i] = f ni := i - 1 if f == 'R' { ni = i + 1 } if 0 <= ni && ni < n { t := time[i] if time[ni] == -1 { q = append(q, ni) time[ni] = t + 1 force[ni] = append(force[ni], f) } else if time[ni] == t+1 { force[ni] = append(force[ni], f) } } } return string(ans) }
java 解法, 执行用时: 45 ms, 内存消耗: 64.2 MB, 提交时间: 2022-12-09 12:40:54
class Solution { public String pushDominoes(String dominoes) { int n = dominoes.length(); Deque<Integer> queue = new ArrayDeque<Integer>(); 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<Character>(); } 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) { int t = time[i]; if (time[ni] == -1) { queue.offer(ni); time[ni] = t + 1; force[ni].add(f); } else if (time[ni] == t + 1) { force[ni].add(f); } } } } return new String(res); } }
python3 解法, 执行用时: 564 ms, 内存消耗: 29.3 MB, 提交时间: 2022-12-09 12:40:42
class Solution: def pushDominoes(self, dominoes: str) -> str: n = len(dominoes) q = deque() time = [-1] * n force = [[] for _ in range(n)] for i, f in enumerate(dominoes): if f != '.': q.append(i) time[i] = 0 force[i].append(f) res = ['.'] * n while q: i = q.popleft() if len(force[i]) == 1: res[i] = f = force[i][0] ni = i - 1 if f == 'L' else i + 1 if 0 <= ni < n: t = time[i] if time[ni] == -1: q.append(ni) time[ni] = t + 1 force[ni].append(f) elif time[ni] == t + 1: force[ni].append(f) return ''.join(res)
python3 解法, 执行用时: 144 ms, 内存消耗: 16.6 MB, 提交时间: 2022-12-09 12:40:32
class Solution: def pushDominoes(self, dominoes: str) -> str: s = list(dominoes) n, i, left = len(s), 0, 'L' while i < n: j = i while j < n and s[j] == '.': # 找到一段连续的没有被推动的骨牌 j += 1 right = s[j] if j < n else 'R' if left == right: # 方向相同,那么这些竖立骨牌也会倒向同一方向 while i < j: s[i] = right i += 1 elif left == 'R' and right == 'L': # 方向相对,那么就从两侧向中间倒 k = j - 1 while i < k: s[i] = 'R' s[k] = 'L' i += 1 k -= 1 left = right i = j + 1 return ''.join(s)
java 解法, 执行用时: 9 ms, 内存消耗: 42.9 MB, 提交时间: 2022-12-09 12:40:16
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); } }
golang 解法, 执行用时: 12 ms, 内存消耗: 6.2 MB, 提交时间: 2022-12-09 12:40:02
func pushDominoes(dominoes string) string { s := []byte(dominoes) i, n, left := 0, len(s), byte('L') for i < n { j := i for j < n && s[j] == '.' { // 找到一段连续的没有被推动的骨牌 j++ } right := byte('R') if j < n { right = s[j] } if left == right { // 方向相同,那么这些竖立骨牌也会倒向同一方向 for i < j { s[i] = right i++ } } else if left == 'R' && right == 'L' { // 方向相对,那么就从两侧向中间倒 k := j - 1 for i < k { s[i] = 'R' s[k] = 'L' i++ k-- } } left = right i = j + 1 } return string(s) }
javascript 解法, 执行用时: 96 ms, 内存消耗: 52.9 MB, 提交时间: 2022-12-09 12:39:49
/** * @param {string} dominoes * @return {string} */ var pushDominoes = function(dominoes) { const s = [...dominoes]; let n = s.length, i = 0; let left = 'L'; while (i < n) { let j = i; while (j < n && s[j] == '.') { // 找到一段连续的没有被推动的骨牌 j++; } const right = j < n ? s[j] : 'R'; if (left === right) { // 方向相同,那么这些竖立骨牌也会倒向同一方向 while (i < j) { s[i++] = right; } } else if (left === 'R' && right === 'L') { // 方向相对,那么就从两侧向中间倒 let k = j - 1; while (i < k) { s[i++] = 'R'; s[k--] = 'L'; } } left = right; i = j + 1; } return s.join(''); };