Skip to content

Commit 4dc42e7

Browse files
committed
feat: 20260309 check in
1 parent 97aa6a9 commit 4dc42e7

3 files changed

Lines changed: 120 additions & 0 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# 3129. 找出所有稳定的二进制数组 I
2+
3+
> **日期**:2026-03-09
4+
> **所用时间**:20min
5+
> **知识点**:动态规划、记忆化搜索
6+
7+
## 1. 动态规划 + 记忆化搜索
8+
9+
题意:给定 `zero`(0 的个数)、`one`(1 的个数)和 `limit`,统计所有满足:
10+
- 恰好包含 `zero` 个 0 和 `one` 个 1;
11+
- 任意长度大于 `limit` 的子数组中**必须同时**包含 0 和 1(即最多连续 `limit` 个相同数字)
12+
的二进制数组个数,结果对 $10^9+7$ 取模。
13+
14+
做法:用 `dfs(i, j, k)` 表示还剩 `i` 个 0、`j` 个 1 要放,且当前连续段的**类型**`k`(0 或 1)时的方案数。直接按“再放一个 0/1”会多一维记录连续长度,状态较大。这里使用“前缀和/容斥”的写法:
15+
- 若当前放 0(`k == 0`),可以从前面若干连续 0 的结尾转移过来,相当于把最近 `limit` 个放 0 的状态和加起来,再减去超过 `limit` 的那一段;
16+
- 放 1 时同理,只是交换 0、1 的角色。
17+
18+
递归边界:
19+
- 若某一边(0 或 1)用完,则只能在连续段类型正确、且剩余个数不超过 `limit` 时继续,否则无解。
20+
21+
复杂度分析:
22+
23+
- 时间复杂度:$O(\text{zero} \cdot \text{one})$(状态数约为 $2 \cdot \text{zero} \cdot \text{one}$,每个状态转移 $O(1)$)
24+
- 空间复杂度:$O(\text{zero} \cdot \text{one})$(记忆化表)
25+
26+
**Python3**
27+
28+
```python
29+
class Solution:
30+
def numberOfStableArrays(self, zero: int, one: int, limit: int) -> int:
31+
MOD = int(1e9 + 7)
32+
@cache
33+
def dfs(i, j, k):
34+
if i == 0:
35+
return int(k == 1 and j <= limit)
36+
if j == 0:
37+
return int(k == 0 and i <= limit)
38+
if k == 0:
39+
return (dfs(i - 1, j, 0) + dfs(i - 1, j, 1) - (dfs(i - limit - 1, j, 1) if i > limit else 0)) % MOD
40+
return (dfs(i, j - 1, 0) + dfs(i, j - 1, 1) - (dfs(i, j - limit - 1, 0) if j > limit else 0)) % MOD
41+
ans = (dfs(zero, one, 0) + dfs(zero, one, 1)) % MOD
42+
dfs.cache_clear()
43+
return ans
44+
```
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# 3861. 容量最小的箱子
2+
3+
> **日期**:2026-03-08
4+
> **所用时间**:2min
5+
> **知识点**:模拟、线性扫描
6+
7+
## 1. 一次遍历
8+
9+
题意可以抽象为:在数组 `capacity` 中找出所有容量 $\ge itemSize$ 的箱子里,容量**最小**的那个的下标,不存在则返回 `-1`
10+
最直接的做法就是线性扫描一遍数组,用一个变量 `ans` 维护当前「最合适箱子」的下标:
11+
12+
- 初始 `ans = -1` 表示还没找到能装下的箱子;
13+
- 遍历每个下标 `i`,容量为 `x = capacity[i]`
14+
-`x < itemSize`,这个箱子装不下,跳过;
15+
-`x >= itemSize`,说明能装下:
16+
- 若当前还没选过箱子(`ans == -1`),直接令 `ans = i`
17+
- 否则比较 `x``capacity[ans]`,如果 `x` 更小,就更新为新的答案下标。
18+
19+
扫描结束后,`ans` 要么是容量最小且能装下物品的箱子下标,要么仍为 `-1`(表示不存在这样的箱子)。
20+
21+
复杂度分析:
22+
23+
- 时间复杂度:$O(n)$
24+
- 空间复杂度:$O(n)$
25+
26+
**Python3**
27+
28+
```python
29+
class Solution:
30+
def minimumIndex(self, capacity: list[int], itemSize: int) -> int:
31+
ans = -1
32+
for i, x in enumerate(capacity):
33+
if x >= itemSize:
34+
if ans == -1 or x < capacity[ans]:
35+
ans = i
36+
return ans
37+
```
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# 3862. 找出最小平衡下标
2+
3+
> **日期**:2026-03-08
4+
> **所用时间**:20min
5+
> **知识点**:前缀和
6+
7+
## 1. 逆向遍历 + 前缀和与乘积比较
8+
9+
从右往左遍历数组,用一个变量 `s` 维护当前下标左侧所有元素的和(通过总和不断减去当前元素得到),
10+
11+
同时用变量 `mul` 维护当前下标右侧所有元素的乘积(初始化为 1,每次乘上当前元素)。
12+
13+
在遍历过程中,一旦出现某个下标使得 `s == mul`,就返回该下标;如果发现 `s < mul`,说明之后乘积只会更大,无需继续遍历。
14+
15+
注意一定要从后向前遍历,因为如果从前往后遍历,可能会出现乘积过大,导致运算速度变慢,会超时。
16+
17+
复杂度分析:
18+
19+
- 时间复杂度:$O(n)$
20+
- 空间复杂度:$O(1)$
21+
22+
**Python3**
23+
24+
```python
25+
class Solution:
26+
def smallestBalancedIndex(self, nums: list[int]) -> int:
27+
s = sum(nums)
28+
mul = 1
29+
n = len(nums)
30+
31+
for i in range(n - 1, -1, -1):
32+
s -= nums[i]
33+
if s == mul:
34+
return i
35+
if s < mul:
36+
break
37+
mul *= nums[i]
38+
return -1
39+
```

0 commit comments

Comments
 (0)