以下是 LeetCode 2147 的 C 语言实现:

```c
#define MOD 1000000007

int numberOfWays(char* corridor) {
    int n = strlen(corridor);
    int seatPositions[n];
    int seatCount = 0;
    
    // 记录所有座位的位置
    for (int i = 0; i < n; i++) {
        if (corridor[i] == 'S') {
            seatPositions[seatCount++] = i;
        }
    }
    
    // 如果没有座位或座位数为奇数,无法分割
    if (seatCount == 0 || seatCount % 2 != 0) {
        return 0;
    }
    
    long long ways = 1;
    
    // 遍历每一对座位(每对构成一个段)
    // 需要在第1对和第2对之间、第2对和第3对之间...放置隔板
    for (int i = 2; i < seatCount; i += 2) {
        // 当前对的后一个座位 和 下一对的前一个座位 之间的植物数
        // 例如:第1对是 [0,1],第2对是 [2,3]
        // 需要看 seatPositions[1] 和 seatPositions[2] 之间的植物
        int gapPlants = seatPositions[i] - seatPositions[i - 1] - 1;
        // 可放置隔板的位置数 = 植物数 + 1
        ways = (ways * (gapPlants + 1)) % MOD;
    }
    
    return (int)ways;
}
```

算法说明

1. 核心思想:
   · 将座位每 2 个分为一组(一对),每组作为一个段
   · 在相邻两组之间需要放置隔板
   · 隔板只能放在植物之间或两端
2. 关键观察:
   · 假设第一组的最后一个座位在位置 a,第二组的第一个座位在位置 b
   · 两者之间(不包含 a 和 b)都是植物(因为如果有座位,它就会属于某一组)
   · 中间有 b - a - 1 个植物
   · 可放置隔板的位置有 (b - a - 1) + 1 = b - a 个
3. 示例:
   ```
   "SSPPSPS"
   座位位置: 0,1,4,6
   第1组: (0,1)
   第2组: (4,6)
   之间: 位置 2-3 ("PP"),2个植物
   可放隔板位置: 3个(位置2前、2和3之间、3后)
   ```
4. 特殊情况:
   · 没有座位 → 0
   · 座位数为奇数 → 0(每段需要2个座位)
   · 只有一个组(2个座位)→ 1(不需要隔板)

时间复杂度

· O(n),只需遍历一次字符串和一次座位数组

空间复杂度

· O(n),需要存储座位位置(最坏情况全部是座位)

 

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐