Skip to content

Commit eab643c

Browse files
committed
Add: Add 2025/11/19
1 parent 3f7db4f commit eab643c

File tree

3 files changed

+155
-0
lines changed

3 files changed

+155
-0
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# 2154. Keep Multiplying Found Values by Two
2+
3+
You are given an array of integers `nums`.
4+
You are also given an integer `original` which is the first number that needs to be searched for in `nums`.
5+
6+
You then do the following steps:
7+
8+
1. If `original` is found in `nums`, multiply it by two (i.e., set original = 2 * original).
9+
2. Otherwise, stop the process.
10+
3. Repeat this process with the new number as long as you keep finding the number.
11+
12+
Return the final value of `original`.
13+
14+
**Constraints:**
15+
16+
- `1 <= nums.length <= 1000`
17+
- `1 <= nums[i], original <= 1000`
18+
19+
## 基礎思路
20+
21+
本題要求我們從一個整數 `original` 開始,檢查它是否存在於陣列 `nums` 中:
22+
23+
- 若存在,則將 `original` 變為 `original * 2`,然後繼續檢查新的數值;
24+
- 若不存在,流程立即停止並回傳此時的 `original`
25+
26+
重點在於:
27+
這是一個 **「重複檢查是否存在 → 若存在就倍增」** 的過程,而整個陣列 `nums` 的大小最多為 1000,且值域也在 1 到 1000 之間。因此,我們可以利用以下觀察來設計高效方法:
28+
29+
- 陣列值域僅到 1000,因此可以建立一個固定大小的 presence map(存在表)來標記哪些數值在 `nums` 中出現;
30+
- 由於 `original` 每次倍增,因此它的值會非常快速地超過 1000;
31+
- 一旦 `original` 超過 1000,就不可能出現在 `nums` 中,因此流程必然會停止。
32+
33+
基於以上,我們可以利用一個固定長度(1001)的 `Uint8Array` 存取存在資訊,使查詢達到 O(1)。
34+
35+
整體流程時間複雜度可以降至 $O(n)$,其中 n 為陣列長度。
36+
37+
## 解題步驟
38+
39+
### Step 1:建立存在表(presence map)並初始化
40+
41+
利用 `Uint8Array(1001)` 來標記 `nums` 中出現的數,確保後續查詢存在否為 O(1)。
42+
43+
```typescript
44+
// 使用緊湊的 TypedArray 建立 nums 中數值的存在表
45+
const presenceMap = new Uint8Array(MAXIMUM_ALLOWED_VALUE + 1);
46+
47+
const length = nums.length;
48+
```
49+
50+
### Step 2:遍歷 nums 並標記出現數值
51+
52+
掃描整個 `nums`,只要數值在合法範圍(≤1000),就記錄為存在。
53+
54+
```typescript
55+
// 將 nums 中的所有數值標記為存在(僅標記合法範圍內的數值)
56+
for (let index = 0; index < length; index += 1) {
57+
const value = nums[index];
58+
59+
if (value <= MAXIMUM_ALLOWED_VALUE) {
60+
// 標記此數值已出現
61+
presenceMap[value] = 1;
62+
}
63+
}
64+
```
65+
66+
### Step 3:執行倍增檢查流程
67+
68+
`original` 開始,只要它仍在存在表中,就一直倍增。
69+
70+
```typescript
71+
// 使用給定的 original 作為起始值
72+
let currentValue = original;
73+
74+
// 只要 currentValue 存在於 nums,就持續倍增
75+
// 若 currentValue 超過值域上限,便不可能出現在 nums 中,因此可直接停止
76+
while (
77+
currentValue <= MAXIMUM_ALLOWED_VALUE &&
78+
presenceMap[currentValue] === 1
79+
) {
80+
// 將 currentValue 倍增並繼續檢查
81+
currentValue = currentValue * 2;
82+
}
83+
```
84+
85+
### Step 4:回傳最終數值
86+
87+
當某次倍增後的 `currentValue` 不再出現在 `nums` 中,即回傳答案。
88+
89+
```typescript
90+
// 當不再找到此數值時,回傳最終結果
91+
return currentValue;
92+
```
93+
94+
## 時間複雜度
95+
96+
- 建立存在表需要掃描整個陣列 → $O(n)$
97+
- 每次倍增最多 log₂(1000) ≈ 10 次 → 可視為常數時間 O(1)
98+
- 查詢存在表皆為 O(1)
99+
- 總時間複雜度為 $O(n)$。
100+
101+
> $O(n)$
102+
103+
## 空間複雜度
104+
105+
- 使用固定大小的 1001-byte 存在表 → $O(1)$
106+
(與輸入大小無關,為常數級空間)
107+
- 總空間複雜度為 $O(1)$。
108+
109+
> $O(1)$
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
const MAXIMUM_ALLOWED_VALUE = 1000;
2+
3+
/**
4+
* Repeatedly doubles `original` while it is present in `nums`,
5+
* then returns the final value when it is no longer found.
6+
*
7+
* @param nums - The list of numbers to search within.
8+
* @param original - The starting value that will be repeatedly doubled.
9+
* @returns The final value of original after the doubling process stops.
10+
*/
11+
function findFinalValue(nums: number[], original: number): number {
12+
// Presence map for values in nums, using a compact typed array
13+
const presenceMap = new Uint8Array(MAXIMUM_ALLOWED_VALUE + 1);
14+
15+
const length = nums.length;
16+
17+
// Mark all values in nums as present (within the allowed range)
18+
for (let index = 0; index < length; index += 1) {
19+
const value = nums[index];
20+
21+
if (value <= MAXIMUM_ALLOWED_VALUE) {
22+
// Mark this value as present
23+
presenceMap[value] = 1;
24+
}
25+
}
26+
27+
// Start with the given original value
28+
let currentValue = original;
29+
30+
// Keep doubling while the current value exists in nums
31+
// As soon as currentValue exceeds the constraint upper bound,
32+
// it cannot be in nums anymore, so we can stop.
33+
while (
34+
currentValue <= MAXIMUM_ALLOWED_VALUE &&
35+
presenceMap[currentValue] === 1
36+
) {
37+
// Multiply the current value by 2 and continue checking
38+
currentValue = currentValue * 2;
39+
}
40+
41+
// When it is no longer found, return the final value
42+
return currentValue;
43+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function findFinalValue(nums: number[], original: number): number {
2+
3+
}

0 commit comments

Comments
 (0)