iT邦幫忙

2025 iThome 鐵人賽

DAY 1
0

題目敘述

給定一個整數陣列 nums 和一個整數 target,請找出陣列中兩個數字的索引值,使得這兩個數字加總起來剛好等於 target

  • 每筆測資保證有且只有一組解
  • 同一個元素在答案中不能重複使用。

解題思路

對於沒接觸過這類問題的人來說,第一直覺可能是使用雙層迴圈暴力解法,嘗試所有可能的數對來找出符合條件的組合:

n = len(nums)
for i in range(n):
    for j in range(i + 1, n):
        if nums[i] + nums[j] == target:
            return [i, j]

然而,這樣的解法時間複雜度為 $O(n^2)$,當陣列長度達到 $10^4$ 時,效率將無法接受。

如何優化至 $O(n)$?

為了在一次遍歷中完成搜尋,我們可以使用一個字典來記錄數字與其對應的索引。這種做法的核心概念是:

  • 當遍歷到第 i 個數字 num 時,我們需要檢查字典中是否存在 target - num,也就是另一個能湊出 target 的數字。
  • 如果有,代表之前已經遇過這個「互補數」,現在找到配對了。
  • 否則,我們將當前的「互補數 target - num」與當前索引記錄進字典中,等待未來可能的配對。

程式碼實作:

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        num_dict = {}  # 用來儲存需要的補數與其對應的索引

        for i, num in enumerate(nums):
            if num in num_dict:
                return [num_dict[num], i]
            else:
                num_dict[target - num] = i

        return []

時間與空間複雜度分析

  • 時間複雜度(Time Complexity):$O(n)$

    • 我們僅需遍歷 nums 一次,每次操作包含查找與插入 dict,這些操作平均為 $O(1)$。
  • 空間複雜度(Space Complexity):$O(n)$

    • 最壞情況下,字典會存下 n 個鍵值對(所有元素的互補數)。

下一篇
3. Longest Substring Without Repeating Characters
系列文
深入淺出 Grind 754
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Wolke
iT邦研究生 4 級 ‧ 2025-10-10 16:26:16

版主您好,感謝您對於 Two Sum 問題的深入淺出分享!從暴力解到優化解的思路講解非常清晰,讓我對時間複雜度的重要性有更深刻的體會,尤其 $O(n^2)$ 到 $O(n)$ 的演進更是經典。

對於使用字典(或雜湊表)的 $O(n)$ 解法,您的程式碼實作非常精簡且有效。我在閱讀時,對於字典 num_dict 中鍵值對的儲存邏輯,例如:「將當前的『互補數 target - num』與當前索引記錄進字典中,等待未來可能的配對」,這段說明與程式碼 num_dict[target - num] = i 對應得很好。不過,為了讓讀者更直觀理解,或許也可以補充說明當我們檢查 if num in num_dict: 時,這個 num 其實就是我們預期會遇到的「補數」本身,而 num_dict[num] 則儲存著它所需配對數字的索引。這樣或許能讓這個經典的邏輯轉折點更一目瞭然!

再次感謝您的分享,寫得非常棒!

也歡迎版主有空參考我的系列文「南桃AI重生記」:
https://ithelp.ithome.com.tw/users/20046160/ironman/8311

我要留言

立即登入留言