Medium
题目描述
给你一个长度为 n 的数组 complexity。
房间里有 n 台被锁定的计算机,标签从 0 到 n - 1,每台都有自己独特的密码。计算机 i 的密码复杂度为 complexity[i]。
标签为 0 的计算机密码已经被解密,作为根节点。所有其他计算机必须使用它或另一台之前已解锁的计算机来解锁,遵循以下信息:
- 你可以使用计算机 j 的密码来解密计算机 i 的密码,其中 j 是任何小于 i 且复杂度更低的整数。(即 j < i 且 complexity[j] < complexity[i])
- 要解密计算机 i 的密码,你必须已经解锁了一台计算机 j,使得 j < i 且 complexity[j] < complexity[i]。
找出表示计算机可以解锁的有效顺序的排列 [0, 1, 2, …, (n - 1)] 的数量,从计算机 0 作为唯一初始解锁的计算机开始。
由于答案可能很大,返回结果模 10^9 + 7。
注意,标签为 0 的计算机密码已解密,而不是排列中第一个位置的计算机。
示例 1:
输入:complexity = [1,2,3]
输出:2
示例 2:
输入:complexity = [3,3,3,4,4,4]
输出:0
约束条件:
- 2 <= complexity.length <= 10^5
- 1 <= complexity[i] <= 10^9
解题思路
这道题的关键在于理解解锁规则:要解锁计算机 i,必须存在一台已解锁的计算机 j,满足 j < i 且 complexity[j] < complexity[i]。
首先分析题目条件:
- 计算机 0 已经解锁,作为根节点
- 要解锁计算机 i(i > 0),必须存在 j < i 且 complexity[j] < complexity[i] 的已解锁计算机
关键观察:如果 complexity[0] 不是数组中的最小值,或者存在其他元素与 complexity[0] 相等,那么某些计算机将无法解锁。
具体分析:
- 如果 complexity[0] 不是唯一最小值,那么存在某个 i > 0,使得 complexity[i] ≤ complexity[0]
- 对于这样的 i,不存在 j < i 且 complexity[j] < complexity[i],因此无法解锁
当 complexity[0] 是唯一最小值时:
- 所有其他计算机都可以通过计算机 0 解锁(因为它们的复杂度都大于 complexity[0])
- 计算机 0 必须排在第一位
- 剩余 n-1 台计算机可以任意排列
因此答案为:
- 如果 complexity[0] 是唯一最小值:(n-1)!
- 否则:0
代码实现
class Solution {
public:
int countPermutations(vector<int>& complexity) {
const int MOD = 1e9 + 7;
int n = complexity.size();
// 检查complexity[0]是否是唯一最小值
for (int i = 1; i < n; i++) {
if (complexity[i] <= complexity[0]) {
return 0;
}
}
// 计算(n-1)!
long long result = 1;
for (int i = 1; i < n; i++) {
result = (result * i) % MOD;
}
return result;
}
};
class Solution:
def countPermutations(self, complexity: List[int]) -> int:
MOD = 10**9 + 7
n = len(complexity)
# 检查complexity[0]是否是唯一最小值
for i in range(1, n):
if complexity[i] <= complexity[0]:
return 0
# 计算(n-1)!
result = 1
for i in range(1, n):
result = (result * i) % MOD
return result
public class Solution {
public int CountPermutations(int[] complexity) {
const int MOD = 1000000007;
int n = complexity.Length;
// 检查complexity[0]是否是唯一最小值
for (int i = 1; i < n; i++) {
if (complexity[i] <= complexity[0]) {
return 0;
}
}
// 计算(n-1)!
long result = 1;
for (int i = 1; i < n; i++) {
result = (result * i) % MOD;
}
return (int)result;
}
}
var countPermutations = function(complexity) {
const MOD = 1e9 + 7;
const n = complexity.length;
// 检查complexity[0]是否是唯一最小值
for (let i = 1; i < n; i++) {
if (complexity[i] <= complexity[0]) {
return 0;
}
}
// 计算(n-1)!
let result = 1;
for (let i = 1; i < n; i++) {
result = (result * i) % MOD;
}
return result;
};
复杂度分析
| 复杂度类型 | 复杂度 |
|---|---|
| 时间复杂度 | O(n) |
| 空间复杂度 | O(1) |
相关题目
- . Clumsy Factorial (Medium)