题目地址
解题思路
这道题的关键之处在于: 多米诺骨牌的受力是以每秒来传递的,即一块多米诺骨牌在一秒内至多给一块多米诺骨牌施加力。
我们定义一个队列:queue<int> q;
用他来记录多米诺骨牌从左到右的操作队列。然后再对每个在队列中的骨牌进行广度优先搜索(为期一秒)。
我们还需要确保多米诺骨牌是否已经受过力,这就需要定义:vector<int> time(n,-1);
,用它来记录多米诺骨牌翻倒或者确定不翻倒的时间。
我们还要定义一个:vector<string> force(n);
,用它来记录每一块多米诺骨牌的受力情况,以string
类型记录进去。
如果一块多米诺骨牌受到一个力,则会偏倒;如果受到两个力,则保持不动。这依赖于我们对force[i]
的长度的判断。
代码实现(C++)
class Solution {
public:
string pushDominoes(string dominoes)
{
int n=dominoes.size();
queue<int> q; //搜索队列
vector<string> force(n); //每一块受到的力的方向
vector<int> time(n,-1); //记录每一块的时间状态
for(int i=0;i<n;i++) //初始化确定需要进入搜索队列的块
{
if(dominoes[i]!='.')
{
force[i].push_back(dominoes[i]);
q.emplace(i);
time[i]=0;
}
}
string res(n,'.');
//对每一个queue中的骨牌进行BFS操作
while(!q.empty())
{
int i=q.front();
q.pop(); //操作完就把他pop掉,以免重复操作
if(force[i].size()==1)
{
char f=force[i][0];
res[i]=f;
int ni=(f=='L') ? (i-1) : (i+1);//对于每一块在队列中的骨牌,判断其向左还是向右施力
if(ni>=0&&ni<n)
{
//下面也适用于判断R.L这种情况
if(time[ni]==-1)
{
q.emplace(ni);
time[ni]=time[i]+1;//改变多米诺骨牌的状态
force[ni].push_back(f);
}
else if(time[ni]==time[i]+1)
{
force[ni].push_back(f);
}
}
}
}
return res;
}
};