Skip to content

Commit 803e719

Browse files
committed
Add: Add 2025/9/22
1 parent 9dca7db commit 803e719

File tree

4 files changed

+137
-8
lines changed

4 files changed

+137
-8
lines changed

1912-Design Movie Rental System/Note.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,13 @@ and `drop` will only be called if the shop had previously rented out the movie.
5353

5454
設計策略:
5555

56-
* **緊湊狀態表**:對每筆拷貝賦予 `entryId`,用定長陣列(TypedArray)存放 `price / shop / movie / state / version`,O(1) 讀寫。
57-
* **直接索引**:建 `movie → (shop → entryId)` 映射,使 `rent/drop` 能 O(1) 取得對應拷貝。
58-
* **雙堆 + 惰性刪除**
59-
60-
* 每部電影一個「可租堆」:按(價格、店編)排序。
61-
* 全域一個「已租堆」:按(價格、店編、電影)排序。
62-
* **不做中間刪除**:每次狀態改變就讓該 `entryId`**版本號 +1**,把 `(entryId, version)` 打包入堆;取堆頂時若版本不符或狀態不符就丟棄,直到遇到有效元素。
63-
* **可重用二元堆**:以通用 `BinaryHeap`(由比較器決定排序)承載上述兩類優先順序。
56+
- **緊湊狀態表**:對每筆拷貝賦予 `entryId`,用定長陣列(TypedArray)存放 `price / shop / movie / state / version`,O(1) 讀寫。
57+
- **直接索引**:建 `movie → (shop → entryId)` 映射,使 `rent/drop` 能 O(1) 取得對應拷貝。
58+
- **雙堆 + 惰性刪除**
59+
- 每部電影一個「可租堆」:按(價格、店編)排序。
60+
- 全域一個「已租堆」:按(價格、店編、電影)排序。
61+
- **不做中間刪除**:每次狀態改變就讓該 `entryId`**版本號 +1**,把 `(entryId, version)` 打包入堆;取堆頂時若版本不符或狀態不符就丟棄,直到遇到有效元素。
62+
- **可重用二元堆**:以通用 `BinaryHeap`(由比較器決定排序)承載上述兩類優先順序。
6463

6564
## 解題步驟
6665

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# 3005. Count Elements With Maximum Frequency
2+
3+
You are given an array `nums` consisting of positive integers.
4+
5+
Return the total frequencies of elements in `nums` such that those elements all have the maximum frequency.
6+
7+
The frequency of an element is the number of occurrences of that element in the array.
8+
9+
**Constraints:**
10+
11+
- `1 <= nums.length <= 100`
12+
- `1 <= nums[i] <= 100`
13+
14+
## 基礎思路
15+
16+
本題要我們找出陣列中出現頻率最高的數字,並回傳這些數字的**總出現次數**
17+
在思考解法時,我們需要特別注意幾個重點:
18+
19+
- 每個元素可能會重複出現,因此我們必須先統計每個數字的出現次數;
20+
- 最後的答案不是最大頻率本身,也不是擁有最大頻率的數字個數,而是**這些數字總共出現了幾次**
21+
22+
為了解決這個問題,我們可以採用以下策略:
23+
24+
- **頻率統計**:先掃過整個陣列,記錄每個數字的出現次數;
25+
- **即時追蹤最大頻率**:在統計的同時,隨時記錄目前出現過的最大頻率;
26+
- **同步累加**:如果某個數字的頻率等於或超過目前最大值,我就更新目前的累加總和;
27+
- **常數空間優化**:由於數字的取值範圍已知是 1 到 100,我可以直接使用定長陣列來記錄頻率,這樣不但記憶體使用固定,也能提升查詢與更新的效率。
28+
29+
## 解題步驟
30+
31+
### Step 1:初始化直方圖與輔助變數
32+
33+
建立用來統計每個數字出現次數的直方圖,並初始化最大頻率與累加總和。
34+
35+
```typescript
36+
// 固定大小直方圖(索引 0 不使用),TypedArray 預設為 0
37+
const frequencyTable = new Uint8Array(101);
38+
39+
// 追蹤目前最大頻次與對應的總和
40+
let maximumFrequency = 0;
41+
let sumAtMaximum = 0;
42+
43+
// 快取長度以減少屬性存取
44+
const length = nums.length;
45+
```
46+
47+
### Step 2:單趟遍歷陣列並更新統計
48+
49+
逐一處理每個元素,更新其頻次,並根據狀況調整最大頻率與累加總和。
50+
51+
```typescript
52+
// 單趟掃描輸入,更新頻次與答案
53+
for (let index = 0; index < length; index += 1) {
54+
const value = nums[index]; // 題目保證 1 <= value <= 100
55+
56+
// 更新該數值的頻次
57+
const nextFrequency = frequencyTable[value] + 1;
58+
frequencyTable[value] = nextFrequency;
59+
60+
// 若產生新的最大頻次,重設總和
61+
if (nextFrequency > maximumFrequency) {
62+
maximumFrequency = nextFrequency;
63+
sumAtMaximum = nextFrequency;
64+
} else if (nextFrequency === maximumFrequency) {
65+
// 若追平最大頻次,將最大頻次加總
66+
sumAtMaximum += maximumFrequency;
67+
}
68+
}
69+
```
70+
71+
### Step 3:回傳總和結果
72+
73+
回傳所有出現頻率等於最大值的元素的總出現次數。
74+
75+
```typescript
76+
// 回傳所有達到最大頻次的總出現次數
77+
return sumAtMaximum;
78+
```
79+
80+
## 時間複雜度
81+
82+
- 遍歷陣列一次,每次操作為 $O(1)$。
83+
- 總時間複雜度為 $O(n)$。
84+
85+
> $O(n)$
86+
87+
## 空間複雜度
88+
89+
- 使用固定長度的直方圖與常數變數。
90+
- 總空間複雜度為 $O(1)$。
91+
92+
> $O(1)$
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
function maxFrequencyElements(nums: number[]): number {
2+
// Fixed-size histogram (index 0 unused). Zero-initialized by TypedArray spec.
3+
const frequencyTable = new Uint8Array(101);
4+
5+
// Track the current maximum frequency and the sum of all frequencies at that maximum.
6+
let maximumFrequency = 0;
7+
let sumAtMaximum = 0;
8+
9+
// Cache length locally to avoid repeated property lookups.
10+
const length = nums.length;
11+
12+
// Single pass over input; tight loop with minimal branching and typed array ops.
13+
for (let index = 0; index < length; index += 1) {
14+
const value = nums[index]; // Per constraints, 1 <= value <= 100.
15+
16+
// Increment the frequency for this value.
17+
const nextFrequency = frequencyTable[value] + 1;
18+
frequencyTable[value] = nextFrequency;
19+
20+
// Update running maximum and the aggregated sum at maximum.
21+
if (nextFrequency > maximumFrequency) {
22+
// New higher maximum: this value is the only one at the new maximum.
23+
maximumFrequency = nextFrequency;
24+
sumAtMaximum = nextFrequency; // reset to the new maximum
25+
} else if (nextFrequency === maximumFrequency) {
26+
// Another value has tied the maximum; add that maximum to the sum.
27+
// This equals: sumAtMaximum += maximumFrequency.
28+
sumAtMaximum += maximumFrequency;
29+
}
30+
// If nextFrequency < maximumFrequency, nothing to do for sumAtMaximum.
31+
}
32+
33+
// The running sum directly equals "max * numberOfValuesAtMax".
34+
return sumAtMaximum;
35+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function maxFrequencyElements(nums: number[]): number {
2+
3+
}

0 commit comments

Comments
 (0)