|
| 1 | +# 1. Two Sum |
| 2 | + |
| 3 | +Given an array of integers `nums` and an integer `target`, return indices of the two numbers such that they add up to `target`. |
| 4 | + |
| 5 | +You may assume that each input would have exactly one solution, and you may not use the same element twice. |
| 6 | + |
| 7 | +You can return the answer in any order. |
| 8 | + |
| 9 | +**Constraints:** |
| 10 | + |
| 11 | +- `2 <= nums.length <= 10^4` |
| 12 | +- `-10^9 <= nums[i] <= 10^9` |
| 13 | +- `-10^9 <= target <= 10^9` |
| 14 | +- Only one valid answer exists. |
| 15 | + |
| 16 | +## 基礎思路 |
| 17 | + |
| 18 | +題目要求找出兩個陣列中的元素,使其總和為指定目標值 `target`,並回傳其索引。由於輸入保證只有一組正確答案,我們不需要處理多解或無解情況。 |
| 19 | + |
| 20 | +為了在 $O(n)$ 時間內完成,我們可以在遍歷陣列時,動態維護一個**值到索引的映射表**。 |
| 21 | +對每個當前元素 `value`,只要查詢 `target - value` 是否已出現過即可(即是否存在某前一個數加上 `value` 為 `target`)。 |
| 22 | + |
| 23 | +這樣,我們只需一次遍歷陣列,利用「一邊掃描、一邊查表」的方式,即可在 $O(n)$ 時間內找到答案。 |
| 24 | + |
| 25 | +## 解題步驟 |
| 26 | + |
| 27 | +### Step 1:宣告映射表作為輔助空間 |
| 28 | + |
| 29 | +使用 `Map<number, number>` 來建立一個從值到其最早出現索引的映射,這樣查找補數是否存在可達成 $O(1)$。 |
| 30 | + |
| 31 | +```typescript |
| 32 | +// 建立從值映射至其最早出現位置的 Map |
| 33 | +const indexByValue = new Map<number, number>(); |
| 34 | +``` |
| 35 | + |
| 36 | +### Step 2:單趟 for 迴圈處理每個元素 |
| 37 | + |
| 38 | +在這一步中,我們邊遍歷 `nums` 陣列,邊查表是否出現過目標補數(`target - value`): |
| 39 | + |
| 40 | +- 若有則立即回傳答案; |
| 41 | +- 若沒有,則把當前值加入映射表中。 |
| 42 | + |
| 43 | +```typescript |
| 44 | +// 單次遍歷:對每個值檢查其補數是否已出現 |
| 45 | +for (let index = 0; index < nums.length; index++) { |
| 46 | + const value = nums[index]; |
| 47 | + const required = target - value; |
| 48 | + |
| 49 | + // 若補數已存在,代表找到正確配對,回傳兩個索引 |
| 50 | + const complementIndex = indexByValue.get(required); |
| 51 | + if (complementIndex !== undefined) { |
| 52 | + return [complementIndex, index]; |
| 53 | + } |
| 54 | + |
| 55 | + // 儲存目前值的索引,僅儲存第一次出現的位置以避免重複使用 |
| 56 | + if (!indexByValue.has(value)) { |
| 57 | + indexByValue.set(value, index); |
| 58 | + } |
| 59 | +} |
| 60 | +``` |
| 61 | + |
| 62 | +### Step 3:安全保底回傳(理論上不會進入) |
| 63 | + |
| 64 | +由於題目保證有解,我們不會真的執行到這一步,但為了完整性,仍然加入一個回傳空陣列的保底。 |
| 65 | + |
| 66 | +```typescript |
| 67 | +// 題目保證有解,這是保險用的 fallback。 |
| 68 | +return []; |
| 69 | +``` |
| 70 | + |
| 71 | +## 時間複雜度 |
| 72 | + |
| 73 | +- 單次遍歷陣列為 $O(n)$。 |
| 74 | +- 每次查表與插入 Map 為 $O(1)$(平均情況下)。 |
| 75 | +- 總時間複雜度為 $O(n)$。 |
| 76 | + |
| 77 | +> $O(n)$ |
| 78 | +
|
| 79 | +## 空間複雜度 |
| 80 | + |
| 81 | +- 使用一個映射表儲存最多 $n$ 筆資料。 |
| 82 | +- 總空間複雜度為 $O(n)$。 |
| 83 | + |
| 84 | +> $O(n)$ |
0 commit comments