Given an array of integers nums and an integer target, return 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.
2 <= nums.length <= 104-109 <= nums[i] <= 109-109 <= target <= 109Can you come up with an algorithm that is less than $O(n^{2})$ time complexity?
We have two nested loops, each iterating through the array of length n, resulting in time complexity.
We only use a constant amount of extra space for the indices and temporary variables.
The brute force approach is straightforward: we check every possible pair of numbers in the array to see if they add up to the target. We use two nested loops, where the outer loop picks the first number and the inner loop checks for the second number that complements it to reach the target.
The in operator (or includes method) checks for the presence of an element in the list, which takes time. Since we do this for each of the n elements, the overall time complexity is .
We store at most n elements in the list.
In this approach, we maintain a list of numbers we have seen so far. For each number in the array, we calculate its complement (the number needed to reach the target) and check if it exists in our list. If it does, we return the indices of the complement and the current number. If it doesn't, we add the current number to the list for future reference.
We iterate through the array once, and each lookup in the hash map is on average.
We store at most n elements in the hash map.
In this approach, we use a hash map (dictionary in Python, Map in JavaScript) to store numbers we have already seen along with their indices. For each number in the array, we calculate its complement (the number needed to reach the target) and check if this complement is already in our hash map. If it is, we return the indices of the complement and the current number. If not, we add the current number and its index to the hash map.
Sorting the list takes time, and the two-pointer traversal takes time, resulting in an overall time complexity of .
We store n pairs in the array, so the space complexity is .
In this approach, we first create a list of pairs where each pair contains a number from the input array and its corresponding index. We then sort this list based on the numbers. After sorting, we can use the two-pointer technique to find the two numbers that add up to the target. We initialize one pointer at the beginning of the list and another at the end. We calculate the sum of the numbers at these pointers and compare it to the target. If the sum is equal to the target, we return their indices. If the sum is less than the target, we move the left pointer to the right to increase the sum. If the sum is greater than the target, we move the right pointer to the left to decrease the sum.
| Approach | Rating | Time Complexity | Space Complexity | Advantages | Disadvantages |
|---|---|---|---|---|---|
| Brute Force | Simple to understand; No extra space needed | ⚠️ Very slow for large inputs | |||
| Using a List | Cleaner intent than brute force | ⚠️ Still due to linear search; Uses extra space | |||
| Using a Hash Map | Optimal time complexity; Single pass through array | Requires extra space for hash map | |||
| Sorting and Two Pointers | Demonstrates two-pointer technique; Good sorting practice | Slower than hash map; Requires sorting step |
The recommended approach for this problem is Solution 3: Using a Hash Map. It achieves the best time complexity of by trading a small amount of extra space for a hash map that enables lookups. This eliminates the need for nested loops or sorting, making it the most efficient approach for this problem.
class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: for i in range(len(nums)): # Calculate the complement of the current number for j in range(i + 1, len(nums)): if nums[j] == target - nums[i]: return [i, j]class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: list = []
for i in range(len(nums)): diff = target - nums[i]
# check if the diff is in the list, if it is, return the index of the diff and the current index if diff in list: return [list.index(diff), i] else: list.append(nums[i])class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: dict = {}
for i, num in enumerate(nums): neededValue = target - num
# check if the needed value is already in the dict if neededValue in dict and dict[neededValue] != i: return [i, dict[neededValue]]
dict[num] = i