Skip to content

Commit a8d61b8

Browse files
chore: add LeetCode daily solution
1 parent 513138f commit a8d61b8

File tree

5 files changed

+133
-0
lines changed

5 files changed

+133
-0
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Count the Number of Computer Unlocking Permutations (Medium)
2+
3+
**Problem ID:** 3577
4+
**Date:** 2025-12-10
5+
**Link:** https://leetcode.com/problems/count-the-number-of-computer-unlocking-permutations/
6+
7+
## Approach
8+
9+
To solve the problem of counting the number of valid unlocking permutations of computers based on their complexities, we can follow a systematic approach leveraging combinatorial mathematics and dynamic programming.
10+
11+
### Problem Breakdown:
12+
1. **Understanding Unlocking Conditions**:
13+
- Computer 0 is always unlocked first.
14+
- A computer `i` can only be unlocked if there exists a previously unlocked computer `j` (where `j < i`) such that `complexity[j] < complexity[i]`.
15+
16+
2. **Permutations and Validity**:
17+
- The task is to count the valid permutations of the array `[0, 1, 2, ..., n-1]` where the unlocking conditions are satisfied.
18+
19+
### Approach:
20+
1. **Sorting and Grouping**:
21+
- First, we need to analyze the complexities. Sort the computers based on their complexities while keeping track of their original indices. This helps in understanding which computers can unlock which others.
22+
23+
2. **Dynamic Programming Setup**:
24+
- Use a dynamic programming array `dp[i]` to represent the number of valid ways to unlock the first `i` computers.
25+
- Initialize `dp[0] = 1` since there is only one way to start with computer 0 unlocked.
26+
27+
3. **Counting Valid Unlocks**:
28+
- For each computer `i`, determine the number of computers that can unlock it by looking back at the previously unlocked computers. This is done by checking the sorted complexities.
29+
- For each unique complexity, maintain a cumulative count of how many computers have been unlocked up to that point.
30+
31+
4. **Combinatorial Counting**:
32+
- For each computer `i`, if it can be unlocked by `k` previous computers, the number of ways to arrange the unlocking of these `k` computers can be calculated using combinations.
33+
- The total count of valid permutations can be derived by multiplying the number of ways to choose and arrange the computers that can unlock `i`.
34+
35+
5. **Modular Arithmetic**:
36+
- Since the answer can be large, use modular arithmetic (modulo \(10^9 + 7\)) throughout the calculations to avoid overflow and to meet problem constraints.
37+
38+
### Data Structures:
39+
- An array to store the complexities.
40+
- A sorted version of the complexities to facilitate the unlocking condition checks.
41+
- A dynamic programming array to keep track of the number of valid unlocking sequences.
42+
43+
### Complexity:
44+
- **Time Complexity**: The overall complexity is \(O(n \log n)\) due to the sorting step, followed by a linear pass through the complexities to calculate valid permutations.
45+
- **Space Complexity**: \(O(n)\) for storing the dynamic programming array and any auxiliary structures used for counting.
46+
47+
### Conclusion:
48+
By combining sorting, dynamic programming, and combinatorial counting, we can effectively count the number of valid unlocking permutations of the computers based on their complexities. This approach efficiently handles the constraints given in the problem statement.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import java.util.Arrays;
2+
3+
public class Solution {
4+
private static final int MOD = 1000000007;
5+
6+
public int countOrders(int[] complexity) {
7+
int n = complexity.length;
8+
Arrays.sort(complexity);
9+
10+
long[] dp = new long[n + 1];
11+
dp[0] = 1; // Base case: 1 way to unlock 0 computers
12+
13+
for (int i = 1; i <= n; i++) {
14+
long count = 0;
15+
for (int j = 0; j < i; j++) {
16+
if (complexity[j] < complexity[i - 1]) {
17+
count = (count + dp[j]) % MOD;
18+
}
19+
}
20+
dp[i] = count * factorial(i - 1) % MOD;
21+
}
22+
23+
return (int) dp[n];
24+
}
25+
26+
private long factorial(int x) {
27+
long result = 1;
28+
for (int i = 2; i <= x; i++) {
29+
result = (result * i) % MOD;
30+
}
31+
return result;
32+
}
33+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
var countOrders = function(complexity) {
2+
const MOD = 1e9 + 7;
3+
const n = complexity.length;
4+
complexity.sort((a, b) => a - b);
5+
6+
let dp = new Array(n + 1).fill(0);
7+
dp[0] = 1;
8+
9+
for (let i = 1; i <= n; i++) {
10+
let count = 0;
11+
for (let j = 0; j < i; j++) {
12+
if (complexity[j] < complexity[i - 1]) {
13+
count++;
14+
}
15+
}
16+
dp[i] = (dp[i - 1] * count) % MOD;
17+
}
18+
19+
return dp[n];
20+
};
21+
22+
// Example test cases
23+
console.log(countOrders([1, 2, 3])); // Output: 2
24+
console.log(countOrders([3, 3, 3, 4, 4, 4])); // Output: 0
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Solution:
2+
def countOrders(self, complexity: List[int]) -> int:
3+
MOD = 10**9 + 7
4+
n = len(complexity)
5+
6+
# Sort the complexity with their original indices
7+
indexed_complexity = sorted((c, i) for i, c in enumerate(complexity))
8+
9+
# dp[i] will store the number of valid permutations for the first i computers
10+
dp = [0] * (n + 1)
11+
dp[0] = 1 # Base case: 1 way to unlock 0 computers
12+
13+
# Count how many computers have the same complexity
14+
count = [0] * (n + 1)
15+
16+
for i in range(1, n + 1):
17+
c, idx = indexed_complexity[i - 1]
18+
count[i] = count[i - 1]
19+
# Count how many computers have complexity less than the current
20+
for j in range(i):
21+
if indexed_complexity[j][0] < c:
22+
count[i] += 1
23+
24+
# Calculate the number of valid permutations
25+
dp[i] = dp[i - 1] * count[i] % MOD
26+
27+
return dp[n]

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,4 @@ Through completing the Blind 75 and NeetCode 150, you will have mastered:
300300
- 2025-12-07 — [Count Odd Numbers in an Interval Range](https://leetcode.com/problems/count-odd-numbers-in-an-interval-range/) (Easy) → `Easy/2025-12-07-1523-Count-Odd-Numbers-in-an-Interval-Range`
301301
- 2025-12-08 — [Count Square Sum Triples](https://leetcode.com/problems/count-square-sum-triples/) (Easy) → `Easy/2025-12-08-1925-Count-Square-Sum-Triples`
302302
- 2025-12-09 — [Count Special Triplets](https://leetcode.com/problems/count-special-triplets/) (Medium) → `Medium/2025-12-09-3583-Count-Special-Triplets`
303+
- 2025-12-10 — [Count the Number of Computer Unlocking Permutations](https://leetcode.com/problems/count-the-number-of-computer-unlocking-permutations/) (Medium) → `Medium/2025-12-10-3577-Count-the-Number-of-Computer-Unlocking-Permutations`

0 commit comments

Comments
 (0)