字符串替换处理
原题:https://leetcode-cn.com/problems/push-dominoes/
题意是:
一个字符串由".","L","R"三种字符构成,其中L会向左,R会向右衍变
特别的是,当"."左右分别同时遇到"R"和"L"时,此"."不变。
问最终字符串。
传统解法:
class Solution { public: struct node { int x, id; node() : x(), id() {} node(int x) : x(x), id(100009) {} node(int x, int y) : x(x), id(y) {} }; string pushDominoes(string dominoes) { int l = dominoes.length(); vector<node> s(0); queue<int> q; for (int i = 0; i < l; ++i) { if (dominoes[i] == '.') s.emplace_back(0); else if (dominoes[i] == 'L') s.emplace_back(-1,0), q.push(i - 1); else s.emplace_back(1,0), q.push(i + 1); } while (q.size()) { int x = q.front(); q.pop(); if (x < 0 || x >= l || s[x].x != 0) continue; int y = 0, id = l + 1; if (x + 1 < l && (x - 1 < 0 || s[x + 1].id <= s[x - 1].id)) y += s[x + 1].x, id = s[x + 1].id + 1; if (x - 1 >= 0 && (x + 1 >= l || s[x - 1].id <= s[x + 1].id)) y += s[x - 1].x, id = s[x - 1].id + 1; if (y > 0) { s[x].x = 1; s[x].id = id; q.push(x + 1); } if (y < 0) { s[x] = -1; s[x].id = id; q.push(x - 1); } } for (int i = 0; i < l; ++i) if (s[i].x == 1) dominoes[i] = 'R'; else if (s[i].x == 0) dominoes[i] = '.'; else dominoes[i] = 'L'; return dominoes; } };
优化后:
class Solution { public: string pushDominoes(string dominoes) { int l = dominoes.length(); vector<int> s(l, -1); queue<int> q; for (int i = 0; i < l; ++i) if (dominoes[i] != '.') q.push(i), s[i] = 0; while (q.size()) { int x = q.front(); q.pop(); //该侧 if (dominoes[x] == 'L') { while (--x >= 0 && (s[x + 1] < s[x] || s[x] == -1)) { if (s[x + 1] + 1 == s[x]) { dominoes[x] = '.'; break; } dominoes[x] = 'L'; s[x] = s[x + 1] + 1; } } else { while (++x < l && (s[x - 1] < s[x] || s[x] == -1)) { if (s[x - 1] + 1 == s[x]) { dominoes[x] = '.'; break; } dominoes[x] = 'R'; s[x] = s[x - 1] + 1; } } } return dominoes; } };
官方解法:
class Solution { public: string pushDominoes(string dominoes) { int n = dominoes.size(), i = 0; char left = 'L'; while (i < n) { int j = i; while (j < n && dominoes[j] == '.') { // 找到一段连续的没有被推动的骨牌 j++; } char right = j < n ? dominoes[j] : 'R'; if (left == right) { // 方向相同,那么这些竖立骨牌也会倒向同一方向 while (i < j) { dominoes[i++] = right; } } else if (left == 'R' && right == 'L') { // 方向相对,那么就从两侧向中间倒 int k = j - 1; while (i < k) { dominoes[i++] = 'R'; dominoes[k--] = 'L'; } } left = right; i = j + 1; } return dominoes; } };
我在题解区看到的巧解:
用了python里的库函数replace,虽然复杂度高了些,但是在理解难度和解题速度和帅气程度方面远优于其他解法:
class Solution: def pushDominoes(self, dominoes: str) -> str: new = "" while dominoes != new: new = dominoes dominoes = dominoes.replace("R.L", "T") dominoes = dominoes.replace(".L", "LL") dominoes = dominoes.replace("R.", "RR") dominoes = dominoes.replace("T", "R.L") print(new) return dominoes
replace:
描述
Python replace() 方法把字符串中的 old(旧字符串) 替换成 new(新字符串),如果指定第三个参数max,则替换不超过 max 次。
语法
replace()方法语法:
str.replace(old, new[, max])

浙公网安备 33010602011771号