Given an array of integers nums
and an integer target
, your task is to return the indices of two numbers such that they add up to the target
.
Problem Description:
- You may assume that each input has exactly one solution.
- You cannot use the same element twice.
- The order of the indices in the result does not matter.
Function Signature:
def twoSum(nums: List[int], target: int) -> List[int]:
- Input:
nums
(List[int]): A list of integers, where2 <= len(nums) <= 104
and-109 <= nums[i] <= 109
.target
(int): The target sum you are trying to achieve, where-109 <= target <= 109
.
- Output:
- A list of two integers that represent the indices of the numbers in
nums
that add up to thetarget
.
- A list of two integers that represent the indices of the numbers in
Example 1:
Input:
nums = [2,7,11,15]
target = 9
Output:
[0, 1]
Explanation:
Because nums[0] + nums[1] == 9
, the answer is [0, 1]
.
Example 2:
Input:
nums = [3,2,4]
target = 6
Output:
[1, 2]
Explanation:
Because nums[1] + nums[2] == 6
, the answer is [1, 2]
.
Example 3:
Input:
nums = [3,3]
target = 6
Output:
[0, 1]
Explanation:
Because nums[0] + nums[1] == 6
, the answer is [0, 1]
.
Constraints:
2 <= len(nums) <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
- Only one valid answer exists.
Follow-up:
Can you come up with an algorithm that runs in less than O(n^2)
time complexity?
Problem Description
In this problem, we have an array of integers called nums
and a target integer called target
. Our task is to find two distinct numbers within the array that when added together, equal the target
. One important rule is that we cannot use the same element from the array twice in our sum. The output will be the indices (positions in the array) of these two numbers, and it does not matter in which order we provide these indices. Each valid input to the problem is guaranteed to have exactly one solution.
Intuition
To solve this problem efficiently, we avoid the brute force approach of trying every possible pair of numbers to see if they add up to the target. Instead, we employ a hash table (dictionary in Python), which offers fast lookup times that average out to O(1) complexity. The basic idea is to iterate through the list once, and for each number, we check if the number required to reach the target (target - current_number
) has already been seen in the array. If it has, then we have found the two numbers whose sum is equal to the target.
As we iterate through the nums
array, we keep track of each number and its index in the hash table. So for each number x
, we calculate y
which is the difference between target
and x
. If y
is found in the hash table, it means we have previously processed another number such that x + y = target
. In that case, we immediately return the pair of indices: one for the current number x
, and one for the previously stored number y
. If y
is not found in the hash table, we store x
along with its index in the hash table and move on to the next element in the array. This approach only requires a single pass through the array, making the solution efficient and elegant.
Solution Approach
The solution provided uses a hash table to map each element’s value to its index in the array. This allows for constant-time look-ups which are critical for efficiency. The algorithm proceeds as follows:
- Initialize an empty hash table (dictionary in Python dialect), we’ll call it
m
. - Iterate over the
nums
array, enumerating both the valuex
and its indexi
. Enumeration provides a convenient way of getting both the value and the index without additional overhead. - For every value
x
, calculate its complementy
by subtractingx
fromtarget
(y = target - x
). - Check if
y
is present as a key in the hash table. If it is found, it means we had already seen the necessary pair earlier in the array. We then retrievem[y]
, which is the index ofy
we had stored, and return a list containing the indices ofy
andx
([m[y], i]
). This satisfies the requirement as their sum is equal to thetarget
. - If
y
is not in the hash table, add the current valuex
along with its indexi
to the hash table (m[x] = i
). This storesx
for future reference if we later come across its complementy
.
By only traversing the array once, the overall time complexity is O(n)
, where n
is the number of elements in nums
. The space complexity is also O(n)
as in the worst case, we could potentially store all elements in the hash table before finding a match.
Here’s the provided solution approach step in the code:
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
m = {} # Step 1: Initialize the hash table
# Step 2: Enumerate through nums
for i, x in enumerate(nums):
y = target - x # Step 3: Calculate complement y
# Step 4: Check if y is present in the hash table
if y in m:
# Return the indices of the two elements adding up to target
return [m[y], i]
# Step 5: Store x with its index in the hash table for future reference
m[x] = i
The strength of this approach is that it smartly utilizes the hash table to avoid nested loops and thus reducing the time complexity. The algorithm is linear time as it eliminates the need to examine every possible pair by keeping a record of what is needed to reach the target with the current number.
Example Walkthrough
Let’s work through a small example to illustrate the solution approach.
Suppose our input array nums
is [2, 7, 11, 15]
and the target
is 9
.
Following the solution steps:
- Initialize an empty hash table (dictionary), which we’ll name
m
. - Now we start iterating over the
nums
array:- First iteration (i = 0):
- We take the first element
nums[0]
which is2
. - Calculate its complement
y = target - nums[0]
, which gives usy = 9 - 2 = 7
. - Check if
7
is present in the hash tablem
. It isn’t, sincem
is empty. - Store the current value
2
along with its index0
in the hash table:m[2] = 0
.
- We take the first element
- Second iteration (i = 1):
- Take the next element
nums[1]
, which is7
. - Calculate its complement
y = target - nums[1]
, which gives usy = 9 - 7 = 2
. - Check if
2
is in the hash tablem
. Yes, it is! The complement2
was stored during the first iteration. - Since the complement is found, we retrieve
m[2]
which is0
, the index of the complement2
. This gives us the indices[0, 1]
.
- Take the next element
- First iteration (i = 0):
The sum of the numbers at these indices (nums[0] + nums[1]
) equals the target
(2 + 7 = 9). As expected, the original problem statement guarantees that there is exactly one solution, so the problem is now solved with the output [0, 1]
.
By using this hash table approach, we efficiently found the two numbers that add up to the target in a single pass through the array, thereby using O(n)
time complexity instead of O(n^2)
which would result from using a brute force approach with nested loops.
Solution Implementation
class Solution {
public:
// Function to find two indices whose values sum up to the target
vector<int> twoSum(vector<int>& nums, int target) {
// Loop through the array using the first index 'i'
for (int i = 0; i < nums.size(); i++) {
// Loop through the array using the second index 'j', starting from 'i + 1' to avoid repeating pairs
for (int j = i + 1; j < nums.size(); j++) {
// Check if the sum of the two elements equals the target
if (nums[i] + nums[j] == target) {
// If the condition is true, return the indices as a vector
return {i, j};
}
}
}
// Return an empty vector if no solution is found
return {};
}
};
import java.util.HashMap;
import java.util.Map;
class Solution {
public int[] twoSum(int[] nums, int target) {
// Create a map to store numbers and their indices
Map<Integer, Integer> indexMap = new HashMap<>();
// Enumerate through the list of numbers
for (int i = 0; i < nums.length; i++) {
// Calculate the complement of the current number
int complement = target - nums[i];
// If the complement is in the map, a solution is found
if (indexMap.containsKey(complement)) {
// Return the indices of the two numbers
return new int[] { indexMap.get(complement), i };
}
// Otherwise, add the current number and its index to the map
indexMap.put(nums[i], i);
}
// If no solution is found, return an empty array (although not needed as per the problem description)
return new int[] {}; // This line is added to avoid the "missing return value" error
}
}
from typing import List # Import List for type annotati
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
# Create a dictionary to store numbers and their indices
index_map = {}
# Enumerate through the list of numbers
for index, number in enumerate(nums):
# Calculate the complement of the current number
complement = target - number
# If the complement is in the index_map, a solution is found
if complement in index_map:
# Return the indices of the two numbers
return [index_map[complement], index]
# Otherwise, add the current number and its index to the index_map
index_map[number] = index
# If no solution is found, return an empty list (although problem guarantees one)
return [] # This line ensures the function always returns something
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
// Set the return size to 2 because the result will always have 2 indices
*returnSize = 2;
// Allocate memory for the result array to hold 2 integers (the indices)
int* result = (int*)malloc(*returnSize * sizeof(int));
// Loop through the array using the first pointer 'i'
for(int i = 0; i < numsSize; i++) {
// Loop through the array using the second pointer 'j', starting from 'i+1' to avoid repeating pairs
for(int j = i + 1; j < numsSize; j++) {
// Check if the sum of the two elements equals the target
if(nums[i] + nums[j] == target) {
// If the condition is true, store the indices in the result array
result[0] = i;
result[1] = j;
// Return the result array with the indices
return result;
}
}
}
// If no solution is found, set return size to 0 and return NULL
*returnSize = 0;
return NULL;
}
public class Solution
{
// Method to find two indices whose values sum up to the target
public int[] TwoSum(int[] nums, int target)
{
// Iterate through the array using the first index 'i'
for (int i = 0; i < nums.Length; i++)
{
// Iterate through the array using the second index 'j', starting from 'i + 1' to avoid repeating pairs
for (int j = i + 1; j < nums.Length; j++)
{
// Check if the sum of the two elements equals the target
if (nums[i] + nums[j] == target)
{
// If the condition is true, return the indices in an array
return new int[] { i, j };
}
}
}
// Return an empty array if no solution is found
return new int[0];
}
}
function twoSum(nums, target) {
// Loop through the array with the first index 'i'
for (let i = 0; i < nums.length; i++) {
// Loop through the array with the second index 'j', starting from 'i + 1' to avoid repeating pairs
for (let j = i + 1; j < nums.length; j++) {
// Check if the sum of the two elements equals the target
if (nums[i] + nums[j] === target) {
// If the condition is true, return the indices in an array
return [i, j];
}
}
}
}
function twoSum(nums: number[], target: number): number[] {
// Loop through the array with the first index 'i'
for(let i = 0; i < nums.length; i++) {
// Loop through the array with the second index 'j', starting from 'i + 1' to avoid repeating pairs
for(let j = i + 1; j < nums.length; j++) {
// Check if the sum of the two elements equals the target
if(nums[i] + nums[j] === target) {
// If the condition is true, return the indices as an array
return [i, j];
}
}
}
// Return an empty array if no solution is found
return [];
}
class Solution {
function twoSum(array $nums, int $target): array {
// Loop through the array using the first index '$i'
for($i = 0; $i < count($nums); $i++) {
// Loop through the array using the second index '$j', starting from '$i + 1' to avoid repeating pairs
for($j = $i + 1; $j < count($nums); $j++) {
// Check if the sum of the two elements equals the target
if($nums[$i] + $nums[$j] == $target) {
// If the condition is true, return the indices in an array
return [$i, $j];
}
}
}
// Return an empty array if no solution is found
return [];
}
}
class Solution {
func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
// Step 1: Initialize a dictionary for fast lookups.
var dict: [Int: Int] = [:]
// Step 2: Go through each number in the array.
for (index, num) in nums.enumerated() {
let complement = target - num
// Step 3: If the complement is found in the dictionary, return its index along with the current number's index.
if let complementIndex = dict[complement] {
return [complementIndex, index]
}
// Step 4: Otherwise, store the current number and its index in the dictionary.
dict[num] = index
}
// Step 5: If no matching pair is found, return an empty array.
return []
}
}
class Solution {
fun twoSum(nums: IntArray, target: Int): IntArray {
// Step 1: Start the first loop to iterate over each number in the array.
for (i in nums.indices) {
// Step 2: Begin the second loop to go through the numbers following the current one.
for (j in i + 1 until nums.size) {
// Step 3: Check if the current pair of numbers add up to the target.
if (nums[i] + nums[j] == target) {
return intArrayOf(i, j)
}
}
}
// Step 4: If no such pair is identified, return an empty array.
return intArrayOf()
}
}
class Solution {
// Function to find two indices whose values sum up to the target
List twoSum(List<int> nums, int target) {
// Loop through the array using the first index 'i'
for (int i = 0; i < nums.length; i++) {
// Loop through the array using the second index 'j', starting from 'i + 1' to avoid repeating pairs
for (int j = i + 1; j < nums.length; j++) {
// Check if the sum of the two elements equals the target
if (nums[i] + nums[j] == target) {
// If the condition is true, return the indices in a list
return [i, j];
}
}
}
// Return an empty list if no solution is found
return [];
}
}
func twoSum(nums []int, target int) []int {
// Step 1: Iterate over the numbers in the array.
for i := 0; i < len(nums); i++ {
// Step 2: For each number, iterate over the rest of the numbers.
for j := i + 1; j < len(nums); j++ {
// Step 3: Check if the current two numbers add up to the target.
if nums[i]+nums[j] == target {
return []int{i, j} // Return their indices.
}
}
}
// Step 4: If no pair is found, return nil.
return nil
}
Time and Space Complexity
The time complexity of the code is O(n)
, where n
is the length of the array nums
. This is because the code loops through each element in nums
exactly once, and each operation within the loop—including checking if an element exists in the map m
and adding an element to m
—is O(1)
.
The space complexity of the code is also O(n)
, since in the worst case, the code may insert each element of the array nums
into the map m
. Therefore, the space used by the map m
grows linearly with the number of elements in nums
.
You will get all the other posts soon
Hiya, I am really glad I have found this info. Today bloggers publish only about gossips and net and this is really frustrating. A good website with interesting content, that’s what I need. Thank you for keeping this web-site, I’ll be visiting it. Do you do newsletters? Cant find it.