Skip to content

Commit e961124

Browse files
committed
refactor: update README for Two-Sum and Add-Two-Numbers with UMPIRE format, enhancing clarity and consistency in problem descriptions and solution strategies
1 parent 90f52dd commit e961124

2 files changed

Lines changed: 144 additions & 168 deletions

File tree

Lines changed: 59 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,133 +1,106 @@
11
---
2-
title: UMPIRE 1.Two-Sum
3-
subtitle: "https://leetcode.com/problems/two-sum/description/"
4-
date: 2025-04-11T20:16:46+08:00
5-
lastmod: 2025-04-11T20:16:46+08:00
6-
draft: false
7-
author: "Kimi.Tsai"
8-
authorLink: "https://kimi0230.github.io/"
9-
description: "Two-Sum"
10-
license: ""
11-
images: []
12-
13-
tags: [LeetCode, Go, Easy, Array, Hash Table]
14-
categories: [LeetCode]
15-
16-
featuredImage: ""
17-
featuredImagePreview: ""
18-
19-
hiddenFromHomePage: false
20-
hiddenFromSearch: false
21-
twemoji: false
22-
lightgallery: true
23-
ruby: true
24-
fraction: true
25-
fontawesome: true
26-
linkToMarkdown: false
27-
rssFullText: false
28-
29-
toc:
30-
enable: true
31-
auto: true
32-
code:
33-
copy: true
34-
maxShownLines: 200
35-
math:
36-
enable: false
37-
mapbox:
38-
share:
39-
enable: true
40-
comment:
41-
enable: true
42-
library:
43-
css:
44-
js:
45-
seo:
46-
images: []
2+
title: UMPIRE 0001.Two-Sum
3+
tags:
4+
- Easy
5+
author: Kimi Tsai <kimi0230@gmail.com>
6+
description: UMPIRE Solution for Two Sum problem
477
---
48-
# Solution - UMPIRE
8+
9+
# UMPIRE 0001.Two-Sum
4910

5011
## Output 1: UMPIRE 解題(完整思考版)
5112

5213
### U – Understand(理解題目)
53-
- **題目描述**:給定一個整數陣列 `nums` 和一個目標值 `target`找出陣列中兩個整數,使其相加等於 `target`,並回傳這兩個數字的索引值
14+
- **題目描述**:給定一個整數陣列 `nums` 和一個目標值 `target`請在該陣列中找出和為目標值的那兩個整數,並返回它們的陣列下標
5415
- **關鍵限制**
55-
- 每種輸入剛好只有一個解
56-
- 同一個元素不能使用兩次
57-
- 回傳索引的順序不限
16+
- 每種輸入只會對應一個答案
17+
- 不能重複使用陣列中同樣的元素(即同一個 index 不能用兩次)
18+
- 答案可以按任意順序返回
5819
- **潛在陷阱**
59-
- 負數的存在(`target``nums[i]` 可能為負)。
60-
- 陣列長度最小為 2。
61-
- **測試案例**
62-
- **Happy Path**: `nums = [2, 7, 11, 15], target = 9` -> `[0, 1]`
63-
- **Edge Case 1 (重複數字)**: `nums = [3, 3], target = 6` -> `[0, 1]`
64-
- **Edge Case 2 (負數)**: `nums = [-1, -8, 5], target = -9` -> `[0, 1]`
20+
- 陣列中可能包含負數。
21+
- 陣列可能未排序(此題未註明排序,不能直接用雙指針而不先排序)。
22+
- **Happy Path**
23+
- `nums = [2, 7, 11, 15], target = 9` -> 返回 `[0, 1]`
24+
- **Edge Cases**
25+
- `nums = [3, 3], target = 6` -> 返回 `[0, 1]`(數值相同但 index 不同)。
26+
- `nums = [3, 2, 4], target = 6` -> 返回 `[1, 2]`(目標值由非連續元素組成)。
6527

6628
### M – Match(匹配知識)
67-
- **主要演算法/資料結構****Hash Table (Map)**
68-
- **為什麼匹配**
69-
- 暴力法 (O(n²)) 需要兩層迴圈
70-
- 使用 Hash Table 可以將查找時間從 O(n) 降低到 O(1),總時間複雜度優化至 O(n)。
71-
- **其他嘗試**
72-
- **排序 + 雙指針**: 雖然空間複雜度可降至 O(1),但因為需要回傳原始索引,排序會打亂索引,處理起來較複雜且時間複雜度為 O(n log n),不如 Hash Table 快
29+
- **主要模式****Hash Map (Hash Table)**
30+
- **為什麼適合**
31+
- 我們需要快速尋找「當前數值的互補值」(即 `target - nums[i]`)是否已經在之前出現過。Hash Map 的查找時間複雜度為 $O(1)$,比起線性尋找的 $O(n)$ 快得多
32+
- **其他方案**
33+
- **暴力解 (Brute Force)**雙層迴圈遍歷所有組合。時間複雜度 $O(n^2)$,效率較低。
34+
- **排序 + 雙指針**:先排序再從兩端逼近。時間複雜度 $O(n \log n)$(受限於排序),雖然空間複雜度可降至 $O(1)$,但若題目要求返回原始下標,排序會打亂位置,需額外處理,不如 Hash Map 直觀且快
7335

7436
### P – Plan(制定計畫)
75-
- 建立一個空的 Map `m`,Key 存數字的值,Value 存該數字的索引。
76-
- 遍歷 `nums` 陣列,對於當前數字 `v` 與索引 `i`
77-
1. 計算所需的差值 `complement = target - v`
78-
2. 檢查 `complement` 是否已存在於 Map `m` 中。
79-
3. 如果存在,代表找到了這兩個數,直接回傳 `[]int{m[complement], i}`
80-
4. 如果不存在,將當前數字與索引存入 Map:`m[v] = i`
81-
- 預防 Bug:確保先檢查再存入,以避免「同一個元素使用兩次」(例如 target 是 6,當前數字是 3)。
37+
1. 初始化一個空的分佈式雜湊表 (Map),用來儲存 `數值 : 下標` 的映射。
38+
2. 遍歷陣列 `nums`,對於每個元素 `v` 和其索引 `i`
39+
- 計算需要的互補值 `complement = target - v`
40+
- 在 Map 中檢查 `complement` 是否已存在:
41+
- 如果**存在**:表示找到答案,返回 `[Map[complement], i]`
42+
- 如果**不存在**:將當前數值與索引存入 Map `Map[v] = i`
43+
3. 如果遍歷結束仍未找到(根據題目假設這不會發生),返回空或預設值。
44+
- **避免的 Bug**:先檢查再存入,可以自然避免「重複使用同一個元素」的問題(因為 Map 裡只會有之前處理過的元素)。
8245

8346
### I – Implement(實際實作,Golang)
8447
```go
8548
func twoSum(nums []int, target int) []int {
86-
// 建立 hash map 存儲 {值: 索引}
49+
// 建立一個 map,key 是數值,value 是對應的索引
8750
m := make(map[int]int)
8851

8952
for i, v := range nums {
9053
complement := target - v
91-
// 檢查差值是否已在 map 中
54+
// 檢查互補值是否已經在 map 中
9255
if idx, ok := m[complement]; ok {
9356
return []int{idx, i}
9457
}
95-
// 將當前數字存入 map
58+
// 如果沒找到,把當前數值存入 map
9659
m[v] = i
9760
}
98-
return nil
61+
62+
return []int{}
9963
}
10064
```
10165

10266
### R – Review(檢查與回顧)
103-
- **Dry Run (`nums = [2, 7, 11, 15], target = 9`)**:
104-
- `i=0, v=2`: complement=7。Map 空,存入 `{2: 0}`
105-
- `i=1, v=7`: complement=2。Map 中有 2 (索引 0),回傳 `[0, 1]`。正確。
106-
- **狀態轉換**:Map 動態增長,確保我們只會跟「之前出現過」的數字做比較,完美避開重複使用同一元素。
67+
- **Dry Run**:以 `nums = [3, 2, 4], target = 6` 為例:
68+
1. `i=0, v=3``complement=3`。Map 為空,不匹配。Map 存入 `{3: 0}`
69+
2. `i=1, v=2``complement=4`。Map 只有 `{3: 0}`,不匹配。Map 存入 `{3: 0, 2: 1}`
70+
3. `i=2, v=4``complement=2`。Map 存在鍵 `2`,其索引為 `1`。匹配成功。
71+
4. 返回 `[1, 2]`
72+
- **狀態轉換**:Map 會動態紀錄掃描過的數字,將原本需要二次掃描的查找降為 $O(1)$。
10773

10874
### E – Evaluate(總結與評估)
109-
- **Time Complexity**: **O(n)**。只需遍歷陣列一次,Map 的查找與插入均為 O(1)。
110-
- **Space Complexity**: **O(n)**。最差情況下需要將所有數字存入 Map。
111-
- **Trade-offs**: 犧牲了空間(O(n))來換取最快的時間(O(n))
75+
- **時間複雜度**:$O(n)$。我們只需遍歷陣列一次,且每次 Map 的存取與查找均為 $O(1)$
76+
- **空間複雜度**:$O(n)$。最壞情況下需要將 $n$ 個元素存入 Map。
77+
- **權衡**:使用空間換取時間。這是處理「尋找特定配對」問題最經典的優化方式
11278

11379
---
11480

11581
## Output 2: 面試官口語回答腳本(精簡可直接說)
11682

11783
### 1️⃣ 開場:題目理解
118-
這題是要在陣列中找到兩個數,相加等於給定的 `target`。比較關鍵的要求是每個輸入只有一個正確解,而且同一個元素不能重複用兩次
84+
這題是要在陣列中找到兩個數字,讓它們加起來等於目標值 `target`,並回傳這兩個數字的索引。題目保證一定有一個解,且每個數字不能重複使用
11985

12086
### 2️⃣ 解法選擇說明
121-
最直觀的方法是兩層迴圈的暴力破解,但時間複雜度是 O(n²)。我會選擇使用 **Hash Map** 來優化,這樣可以把查找的時間降到 O(1),讓整體的效率提升到 **O(n)**
87+
我選擇使用 **Hash Map** 來解這題,因為它能將尋找「互補數字」的時間從 $O(n)$ 降到 $O(1)$。雖然暴力解用雙層迴圈也能做,但 $O(n^2)$ 的效率在數據量大時會太慢
12288

12389
### 3️⃣ 解題策略概覽
124-
我會遍歷陣列一次,每遇到一個數字,就去算一下「還差多少(complement)」才能達到目標值。如果這個差值已經在 Map 裡面了,就代表找到了;如果還沒出現過,就把現在這個數字存進 Map,留給後面的數字匹配
90+
我會遍歷一次陣列。對於每個數字,我先去計算「還差多少才到 target」,然後檢查這個「差額」是否已經存在 Hash Map 中。如果有,就代表找到了;如果沒有,我就把當前的數字和它的索引存進 Map,繼續往後看
12591

12692
### 4️⃣ 寫程式時會補充的關鍵說明
127-
在實作時,我會注意**先檢查再存入**。這樣可以確保我們不會誤用同一個索引兩次,例如當 target 是 6 而當前數字是 3 的時候。
93+
在實作時有兩個細節要注意:
94+
1. 我們要「先檢查、再存入」,這樣可以保證我們不會找到自己,滿足題目「不能重複使用同一個元素」的要求。
95+
2. 在 Golang 中,使用 `if idx, ok := m[complement]; ok` 可以很優雅地同時完成查找和判斷是否存在。
12896

12997
### 5️⃣ 快速 Dry Run 說明
130-
`[2, 7, 11, 15]` 目標 9 為例。第一個數字 2 進去時 Map 是空的,所以把 `2` 存起來。到第二個數字 7 時,差值是 2,這時發現 Map 裡已經有 2 了,就直接回傳它們的索引。
98+
假設輸入 `[3, 2, 4]` 目標是 `6`
99+
看到 `3` 時 Map 是空的,存入 `{3:0}`
100+
看到 `2` 時去找 `4`,沒找到,存入 `{2:1}`
101+
最後看到 `4` 時去找 `2`,在 Map 裡找到了索引 `1`,所以直接回傳 `[1, 2]`
131102

132103
### 6️⃣ 收尾總結
133-
這個解法在時間上非常高效,是 **O(n)**。雖然空間上因為用了 Map 需要 **O(n)** 的額外空間,但在現代面試中,這通常是時間與空間權衡下的最優解。
104+
這個演算法的**時間複雜度是 $O(n)$****空間複雜度也是 $O(n)$**。這是在這類尋找配對問題中最優的時間效率。
105+
106+
---

0 commit comments

Comments
 (0)