英文:
Given an array of integers nums
and an integer target
, return the indices of the two numbers such that they add up to target
.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
You can return the answer in any order.
中文:
給定一個整數陣列 nums
和一個整數 target
,返回兩個數字的索引,這兩個數字的和等於 target
。
你可以假設每個輸入都只有一個解,而且你不可以使用相同的元素兩次。
你可以以任何順序返回答案。
這個問題要求給定一個整數陣列 nums
和一個整數 target
,找出陣列中兩個數字的索引,使得這兩個數字的和等於 target
。你可以假設每個輸入只有一個解,並且不可以使用相同的元素兩次。最後,你需要返回這兩個數字的索引。
這個問題的解決方案是使用哈希表(Dictionary 或 Python 的字典)來記錄每個數字和其對應的索引。我們遍歷整個陣列一次,對於每個元素,計算出目標值減去該元素的差值,我們稱之為 complement
。然後,檢查這個 complement
是否已經存在於哈希表中。
如果存在,則找到了答案,我們可以返回這兩個數字的索引,一個是 complement
的索引,另一個是目前元素的索引。這樣我們就能保證這兩個數的和等於目標值 target
。
如果遍歷完整個陣列都找不到答案,則拋出異常(C# 使用 ArgumentException,Python 使用 ValueError),表示找不到解。
這個解法的時間複雜度是 O(N),其中 N 為陣列的長度,因為我們只需遍歷一次陣列。空間複雜度也是 O(N),用於存儲哈希表,其中 N 是陣列中不同數字的數量。這個方法能夠高效地找到兩個數字的索引,使其和等於目標值。
1Input:
2 nums = [2, 7, 11, 15]
3 target = 9
4Output:
5 Result: [0, 1]
nums
的長度介於 2 到 10^4 之間。target
的值介於 -10^9 到 10^9 之間。 1namespace UnitTestDay1_TwoSum
2{
3 public class Solution
4 {
5 public int[] TwoSum( int[] nums, int target )
6 {
7 Dictionary<int, int> numIndexMap = new Dictionary<int, int>();
8
9 for (int i = 0; i < nums.Length; i++)
10 {
11 int complement = target - nums[i];
12 if (numIndexMap.ContainsKey( complement ))
13 {
14 return new int[] { numIndexMap[complement], i };
15 }
16 numIndexMap[nums[i]] = i;
17 }
18
19 throw new ArgumentException( "No solution found." );
20 }
21 }
22}
這個 C# 解法使用哈希表(Dictionary)來記錄每個數字對應的索引。我們遍歷一次整個陣列,對於每個元素,計算目標值減去該元素的差值 complement
。然後檢查這個 complement
是否已經存在於哈希表中,如果存在,就找到了答案,返回這兩個數字的索引。如果遍歷完整個陣列都找不到答案,則拋出異常。
1namespace UnitTestDay1_TwoSumTests
2{
3 [TestClass()]
4 public class SolutionTests
5 {
6 private Solution UT = new Solution();
7
8 [TestMethod()]
9 public void Test1()
10 {
11 int[] nums = { 2, 7, 11, 15 };
12 int target = 9;
13 int[] expected = { 0, 1 };
14 int[] actual = UT.TwoSum( nums, target );
15 CollectionAssert.AreEqual( expected, actual );
16 }
17
18 [TestMethod()]
19 public void Test2()
20 {
21 int[] nums = { 3, 2, 4 };
22 int target = 6;
23 int[] expected = { 1, 2 };
24 int[] actual = UT.TwoSum( nums, target );
25 CollectionAssert.AreEqual( expected, actual );
26 }
27
28 [TestMethod()]
29 public void Test3()
30 {
31 int[] nums = { 3, 3 };
32 int target = 6;
33 int[] expected = { 0, 1 };
34 int[] actual = UT.TwoSum( nums, target );
35 CollectionAssert.AreEqual( expected, actual );
36 }
37 }
38}
1class Solution:
2 def twoSum(self, nums, target):
3 num_index_map = {}
4 for i, num in enumerate(nums):
5 complement = target - num
6 if complement in num_index_map:
7 return [num_index_map[complement], i]
8 num_index_map[num] = i
9 raise ValueError("No solution found.")
這個 Python 解法使用哈希表(Dictionary)來記錄每個數字對應的索引。我們遍歷一次整個陣列,對於每個元素,計算目標值減去該元素的差值 complement
。然後檢查這個 complement
是否已經存在於哈希表中,如果存在,就找到了答案,返回這兩個數字的索引。如果遍歷完整個陣列都找不到答案,則拋出異常。
1import unittest
2
3class TestTwoSum(unittest.TestCase):
4
5 def test_case_1(self):
6 nums = [2, 7, 11, 15]
7 target = 9
8 expected = [0, 1]
9 actual = Solution().twoSum(nums, target)
10 self.assertEqual(expected, actual)
11
12 def test_case_2(self):
13 nums = [3, 2, 4]
14 target = 6
15 expected = [1, 2]
16 actual = Solution().twoSum(nums, target)
17 self.assertEqual(expected, actual)
18
19 def test_case_3(self):
20 nums = [3, 3]
21 target = 6
22 expected = [0, 1]
23 actual = Solution().twoSum(nums, target)
24 self.assertEqual(expected, actual)
25
26if __name__ == '__main__':
27 unittest.main()
這個題目要求找到一對數字,它們的和等於目標值 target
。使用雙重迴圈會過慢,改用雜湊表儲存數字和索引可以降低時間複雜度到 O(N),所以我們使用哈希表(dictionary)來加速查找,降低時間複雜度。
nums
的長度。解題技巧在於善用雜湊表快速查找是否存在補數,避免使用兩層迴圈。時間複雜度從 O(N^2) 降到 O(N),空間複雜度為 O(N)。
這是一道很典型的使用雜湊表優化時間複雜度的題目,適合用來練習基礎算法技巧。
哈希表(Hash Table)是一種非常高效的資料結構,可以在 O(1) 的時間複雜度內完成插入、查詢和刪除操作。
哈希表的基本原理是:
哈希表的優點是:
哈希表的缺點是: