原题链接:https://leetcode-cn.com/problems/push-dominoes/
1、 模拟法
双指针法,把各种情况都判断一下即可。
class Solution {
public:
string pushDominoes(string dominoes) {
int n = dominoes.size();
int i = 0, j = 0; // i指向左边的L或R,j指向右边的L或R
while (i < n) {
while (j < n && dominoes[j] == '.') j++;
cout << " i is " << i << " j is " << j << endl;
if (dominoes[i] == 'R' && dominoes[j] == 'L') { // 两边往中间到
for (int x = i, y = j; x < y; ++x, --y) {
dominoes[x] = 'R';
dominoes[y] = 'L';
}
} else if (dominoes[j] == 'L') { // 向左到
for (int y = i; y < j; ++y) dominoes[y] = 'L';
} else if (dominoes[i] == 'R') { // 向右到
for (int x = i; x < j; ++x) dominoes[x] = 'R';
}
i = j; // 将i指向j,并且j指向下一个
j = i + 1;
}
return dominoes;
}
};
2、 BFS
- times表示时间的传播
- force表示受力
- 对任一个骨牌在force最多有两个元素,左边和右边,倒了的骨牌就不再受力
class Solution {
public:
string pushDominoes(string dominoes) {
int n = dominoes.size();
vector<string> force(n);
vector<int> times(n, -1);
queue<int> q;
for (int i = 0; i < n; ++i) {
if (dominoes[i] == '.') continue;
q.push(i);
times[i] = 0;
force[i].push_back(dominoes[i]);
}
string res = dominoes;
while(q.size()) {
int i = q.front();
q.pop();
if (force[i].size() == 1) {
res[i] = force[i][0];
int t = times[i];
int j = (force[i][0] == 'L') ? i - 1 : i + 1;
if (j < 0 || j >= n) continue;
if (times[j] == -1) { // 直立的骨牌
times[j] = t + 1;
q.push(j);
force[j].push_back(force[i][0]);
} else if (times[j] == t + 1) {
force[j].push_back(force[i][0]);
}
}
}
return res;
}
};