题目概述
题解
??这个题需要多看图,仔细看图会发现你只能在第
2
i
2i
2i个椅子和第
2
i
+
1
2i+1
2i+1个椅子之间摆放屏风(
i
=
1
,
2
,
3
,
.
.
.
i = 1,2,3,...
i=1,2,3,...),其他位置都不能摆放屏风,因为其他位置在上一个屏风到这个位置之前的椅子数不够2个。 ??那既然只能在第
2
i
2i
2i个椅子和第
2
i
+
1
2i+1
2i+1个椅子之间摆放屏风,那么两个位置之间摆放屏风的方法数就是第
2
i
+
1
2i + 1
2i+1个椅子的下标和第
2
i
2i
2i个椅子的下标之差,然后根据乘法原理,把这些第2个椅子和第3个椅子之间摆放屏风的方法数、第4个椅子和第5个椅子之间摆放屏风的方法数…乘起来就可以了。 ??另外,本题要注意边界条件:如果椅子的个数是奇数个,那么不可能通过摆放屏风分成每块都有两个椅子的块,所以如果椅子个数是奇数个,直接返回0;另外,如果压根没有椅子,那何谈摆放屏风的方法,也返回0. ??下面提供两种实现思路的代码,一种比较蠢,是我理解了大佬的思路后自己实现的,具体就是用一个数组记录每个椅子的下标,然后挑数组中第3个元素和第2个元素作差与返回结果累乘、数组中第5个元素和第4个元素累乘…因为数据比较大记得取模。
class Solution {
public:
int numberOfWays(string corridor)
{
int mod = 1e9 + 7;
vector<int> chairlocation;
int size = corridor.size();
for (int i = 0; i < size; ++i)
{
if (corridor[i] == 'S')
{
chairlocation.push_back(i);
}
}
int chairnum = chairlocation.size();
if (chairnum == 0)
{
return 0;
}
if (chairnum % 2 != 0)
{
return 0;
}
long long ret = 1;
for (int i = 1; 2 * i <= chairnum; ++i)
{
if (2 * i + 1 < chairnum)
{
long long ways = chairlocation[2 * i + 1 - 1] - chairlocation[2 * i - 1];
ret = (ret * ways) % mod;
}
}
return ret % mod;
}
};
??这个思路完全没必要实现的这么麻烦,由于只需要奇数的前继,只要遍历时一直更新前继椅子的下标就好了。
class Solution {
public:
int numberOfWays(string corridor)
{
int mod = 1e9 + 7;
int chairnum = 0;
int size = corridor.size();
int ret = 1;
int prev = 0;
for (int i = 0; i < size; ++i)
{
if (corridor[i] == 'S')
{
++chairnum;
if (chairnum >= 3 && chairnum % 2 == 1)
{
ret = (long)ret * (i - prev) % mod;
}
prev = i;
}
}
return chairnum == 0? 0 : (chairnum % 2 == 0 ? ret : 0);
}
};
时间复杂度:
O
(
n
)
O(n)
O(n) 空间复杂度:
O
(
1
)
O(1)
O(1)
|