Two Sum

Identifying Problem Isomorphism

An approximate isomorphism: “Subarray Sum Equals K”

“Two Sum” asks for the indices of two numbers in an array such that they add up to a target number.

“Subarray Sum Equals K” requires you to find the total number of continuous subarrays whose sum equals a specific target.

The isomorphism is in the shared objective: find elements in an array that satisfy a specific sum condition. In “Two Sum”, you are searching for two elements that add up to a target, while in “Subarray Sum Equals K”, you are looking for a subarray (which could be composed of two elements) that sums up to the target.

“Two Sum” problem is simpler because it’s only looking for a pair of numbers. The “Subarray Sum Equals K” is more complex because it deals with subarrays of varying lengths, thereby increasing the potential combinations to check.

“Two Sum” requires you to search and find elements in a collection. It introduces the usage of hash maps (or dictionaries) to achieve solutions with good time complexity.

10 Prerequisite LeetCode Problems

From the list provided, the following problems are simpler and can be approached before tackling “Two Sum”:

  1. “283. Move Zeroes”: This problem is about array manipulation and can help understand traversing an array and rearranging its elements.
  2. “217. Contains Duplicate”: This problem also uses a hash map and is simpler than “Two Sum”.
  3. “136. Single Number”: This problem also deals with an array and can be solved with a hash map.
  4. “242. Valid Anagram”: This problem introduces the concept of checking if two strings are anagrams using a hash map.
  5. “204. Count Primes”: This problem can introduce you to using arrays for efficient lookup in a similar way to hash maps.

These problems help familiarize you with basic array manipulation, using hash maps, and some mathematical concepts. After solving these problems, “Two Sum” should seem more approachable. After “Two Sum”, you can tackle the following problems and continue to build on the concepts used in “Two Sum”.

“Two Sum” is a basic problem that introduces the concept of using a hash map to keep track of elements for quick lookup. Here are some easier problems to prepare for this problem:

  1. “1. Two Sum II - Input array is sorted”: This is a variant of the original problem with a sorted array.
  2. “167. Two Sum II - Input array is sorted”: This is another variant of the original problem with a sorted array. It can be solved using two pointers instead of a hash map.
  3. “349. Intersection of Two Arrays”: This problem introduces the concept of set intersection which can also be solved using hash maps.
  4. “350. Intersection of Two Arrays II”: This problem is a bit more complex than the previous one as it involves keeping count of elements.
  5. “202. Happy Number”: This problem involves using a hash set to detect cycles, similar to how a hash map can be used to track previous elements.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Solution:
   def twoSum(self, nums: List[int], target: int) -> List[int]:
       seen = {}
       for i, value in enumerate(nums):
           remaining = target - nums[i]

           if remaining in seen:
               return [i, seen[remaining]]
           else:
               seen[value] = i

Problem Classification

  1. Array Manipulation: The problem involves working with an array (or list in Python). Specifically, the code iterates over the array and performs operations on the array elements.

  2. Search Problem: The goal is to find two numbers in the array that add up to a target number. This involves searching the array for specific elements.

  3. Hash Table Usage: The problem involves storing seen numbers in a hash table (dictionary in Python) and checking if certain numbers exist in the hash table. Hash tables are often used for quick lookups and checks, which is crucial for this problem.

  4. Index Manipulation: The problem requires returning the indices of two numbers in the array. This means the solution must keep track of array indices and manipulate them as necessary.

This is an Array Manipulation and Search Problem with a focus on Hash Table Usage and Index Manipulation.

Visual Model of the Problem

Two Sum can be thought of as a search problem. You’re given a list of numbers and a target value, and you’re asked to find the indices of two numbers that add up to the target.

One way to visualize this problem is to imagine the numbers in the list plotted on a number line. You start with your target number and then you ‘search’ through the number line for pairs of numbers that will sum up to the target.

Another way to visualize this is to think of the problem as a balancing act. Imagine each number in the array as a weight on one side of a balance scale, and the target number as the desired weight on the other side of the scale. Your job is to find two weights (numbers) that, when combined, balance the scale (sum up to the target).

You can also imagine this problem as a journey through a graph or a map, where each number is a point or a destination. You start at a certain point (number), and your task is to find a path to another point so that the total distance traveled (the sum of the two numbers) equals the target.

These are just some ways to visualize the problem. The best visualization may depend on your personal thinking style and how you best understand and solve problems.

The Two Sum problem can also be visualized in a few ways:

  1. Number Line Visualization: In this method, we can imagine the array as points on a number line. The task is to find two points such that their sum equals the target value. The number line helps visualize the idea of moving from both ends towards the middle, or of moving a sliding window.

  2. Pair Mapping Visualization: This method imagines the array as a collection of potential pairs, and our task is to find the pair that adds up to the target. Each number in the array could be seen as a potential “first half” of the pair we’re looking for, and we can create a map that shows what “second half” would complete each pair.

  3. Bucket Filling Visualization: Imagine having a set of empty buckets, each representing a possible sum of two numbers. For each number in the array, you “fill” its corresponding bucket. The task is to find the bucket that corresponds to the target sum.

These names are not standardized, but they do provide useful metaphors for understanding the problem.

Problem Simplification and Explanation

This problem can be seen as a form of the classic “two-sum” problem, where you are given an array of numbers and a target sum, and you are asked to find two numbers in the array that add up to the target sum.

To break it down into simpler terms, imagine you’re shopping at a store, and you have a specific amount of money to spend (the target). The store sells a variety of different items, each with its own price (the numbers in the array). Your goal is to find exactly two items in the store that together cost exactly the amount of money you have to spend. You’re not allowed to buy the same item twice (you can’t use the same number twice).

The key concepts involved here are:

  1. Array traversal: You need to look at each item in the array at least once to see if it’s part of the solution.

  2. Pair finding: You need to find two numbers that add up to a given target.

  3. Hashing: This can be used to store the numbers you’ve seen and their indices, making it faster to check if the other half of the pair has been seen when you look at a new number.

Here is a metaphor to help you understand the problem:

Think of the array of numbers as a party, and the target as a dance song. The numbers at the party are all guests. The DJ announces that the next dance is a pairs dance, and the sum of the ages of the two partners must be equal to the length of the song. Each guest can only dance once. Your task is to find the two guests who can dance to this song.

In more technical terms, you need to find two numbers in the array that add up to the target. You’ll iterate through the array, and for each number, check if the “dance partner” (the number that, added to the current number, equals the target) is already in the array. If it is, you’ve found your pair. If it isn’t, you move on to the next number. You can use a hash table to remember the guests (numbers) you’ve seen and where they are (their indices), which will make it faster to find the “dance partner” when you encounter a potential one.

The key is to remember who is at the party (traverse the array) and keep track of potential dance partners (use a hash table). Once you find a pair that can dance to the song (their ages sum up to the target), you’ve solved the problem.

Constraints

  1. Each input has exactly one solution: The fact that we know there’s exactly one pair of numbers that add up to the target eliminates the need for us to consider multiple potential solutions. This means we can stop searching as soon as we’ve found a pair of numbers that meet the requirement.

  2. Numbers and target are within a specific range: The problem states that the integers in the array and the target number are within the range of -10^9 to 10^9. While this is a large range, the fact that it’s bounded may allow for potential optimizations depending on the specific solution approach. For instance, if we were considering a sort-based approach, knowing the range could allow us to choose a more efficient sorting algorithm.

  3. May not use the same element twice: This means if we found a number in the array that is half of the target, we must ensure there is another number that is the same in the array. This helps to quickly rule out some numbers.

  4. Array length is between 2 and 10^4: This gives us a sense of the maximum possible size of the input, which can help when considering the time complexity of potential solutions. For example, a solution with a time complexity of O(n^2) might be feasible given the maximum input size, although a linear O(n) solution would still be preferable.

  5. Return indices, not values: The problem asks for the indices of the numbers, not the numbers themselves. This can be used to guide the choice of data structures used in the solution. For instance, using a hash table to store numbers and their indices would allow us to efficiently retrieve the required indices when we’ve found a solution.

Thought Process

The problem requires us to find two numbers in a list that add up to a given target. There are a few important points to consider:

  1. “Return the indices of the two numbers”: We are not simply returning the numbers themselves but their positions or indices in the list. This suggests that we need to keep track of not just the numbers but also their locations.

  2. “You may not use the same element twice”: This means that the solution pair cannot contain the same number at the same index twice.

  3. “Only one valid answer exists”: This tells us that there will always be a solution to our problem, and we won’t have a case where no such pair exists.

These cues in the problem suggest using a data structure that can efficiently store numbers from the list along with their indices, and that allows quick lookup to check if a number exists. A Python dictionary or hash map is a great fit for this.

1
2
3
4
5
6
7
8
def twoSum(nums, target):
    hashmap = {}
    for i, num in enumerate(nums):
        complement = target - num
        if complement in hashmap:
            return [hashmap[complement], i]
        hashmap[num] = i
    return []

In this function, we create a dictionary hashmap to store the numbers from nums as keys and their indices as values. For each num in nums, we calculate the complement that would add up to target. We then check if this complement already exists in hashmap. If it does, we have found our pair, and we return the indices. If it doesn’t, we add the current num and its index i to hashmap and continue to the next number. This way, we are able to check all possible pairs in nums while maintaining an efficient O(n) time complexity.

Solution Approach and Analysis

Let’s think of this problem as a party where people are wearing numbered badges, and you’re trying to find two people such that their badge numbers add up to a specific number, let’s say 10.

Here’s a detailed step-by-step process:

  1. Step One - Preparation: Start by creating an empty hash map, which can be thought of as a notebook to keep a record of everyone you’ve met so far at the party. The hash map allows you to look up the record of a person based on their badge number in constant time.

  2. Step Two - Meeting People: Now start meeting people one by one in the party. For every person you meet, first check your notebook to see if you’ve met someone in the past whose badge number plus this person’s badge number equals 10. This is equivalent to looking for target - current_num in the hash map, where current_num is the badge number of the person you’re currently meeting.

  3. Step Three - Found or Not Found: If you found such a person, great! You have found the two people whose badge numbers add up to 10. You can return the indices of these two numbers. If you didn’t find such a person, it means you haven’t met the ‘complement’ of the current person yet. So, you make a note of the current person and their badge number in your notebook. This is equivalent to storing current_num and its index in the hash map.

  4. Step Four - Repeat: Repeat step 2 and 3 for each person in the party (each number in the array).

For example, consider the list [2,7,11,15] with a target of 9. Initially, your hash map (notebook) is empty. As you iterate over the list:

  • You meet the first person wearing a 2 badge. You haven’t met anyone before, so you add them to your notebook: {2: 0}.
  • Next, you meet the person wearing a 7 badge. You check if you’ve met someone with a badge number of 9 - 7 = 2. You find that you have, and their index (0) combined with the current index (1) [0, 1] is your answer.

If the list or target changes, you simply adjust your search accordingly. For example, if the target was 26, you would be looking for people whose badge numbers add up to 26 instead of 10. You would still use the same process of keeping track of everyone you’ve met and constantly checking if the person required to reach the target has been met before.

This method is extremely efficient because you are only going through the list once (O(n) time complexity), and lookup operations in the hash map take constant time (O(1)). It’s like quickly navigating through a crowded party by efficiently keeping track of everyone you’ve met!

Identification of Applicable Theoretical Concepts

There are several mathematical and algorithmic concepts that can be applied to this problem:

  1. Complement principle: In this problem, for every number num in the array, you are essentially looking for its “complement” such that num + complement equals the target value. This can simplify the problem from finding two numbers that add up to a certain value to finding if a certain number exists in the array.

  2. Hashing: This is a concept in computer science that can be used to implement the complement principle efficiently. A hash table or hash map can be used to store each number and its index as key-value pairs. Then, for each number, you can instantly check if its complement is in the table (which is a O(1) operation). This allows you to solve the problem in a single pass through the array.

  3. Two-pointer technique: If the array is sorted or can be sorted, the problem could also be solved by a two-pointer technique, where you maintain two pointers at the beginning and end of the array. Depending on the sum of the values at the pointers, you move the pointers accordingly to find the pair that adds up to the target. This also yields a O(n) solution, but it requires the array to be sorted or sortable, which is not guaranteed in the problem statement.

In general, the key to an efficient solution to this problem is realizing that you can turn a two-variable problem (finding two numbers) into a one-variable problem (finding one number, given the other), and then use data structures or techniques that allow you to solve the simplified problem quickly.

Coding Constructs

  1. The code utilizes a problem-solving strategy called hashing, which allows constant-time average complexity for search and insert operations. By maintaining a dictionary (a hash map), we store each element of the list along with its index. This allows us to quickly check if an element exists and retrieve its index if it does.

  2. If I were explaining to a non-programmer, I would say: “Imagine you’re given a list of numbers, and you’re asked to find two numbers that add up to a specific target number. One way to do it would be to look at each number and then look at every other number to see if they add up to the target. However, this can take a lot of time, especially if the list is long. Instead, this code uses a clever shortcut. For each number, it calculates what the ‘complement’ would be to reach the target. Then, it checks a dictionary (think of it as a book’s index, where you can look up information quickly) to see if this complement is present. This method saves time because looking up something in the dictionary is faster than checking every number.”

  3. The logical constructs used in this code include loops, conditionals, and dictionary operations. The loop is used to iterate over the list of numbers. The conditional (if statement) is used to check if the complement of a number is already present in the dictionary. The dictionary operations include checking if a key is present (in operation) and setting a key-value pair (assignment operation).

  4. The algorithmic approach in plain English would be: “Iterate over each number in the list. For each number, calculate the complement that would add up to the target. Check if this complement is already in our dictionary. If it is, we’ve found our two numbers. If it’s not, add the current number and its index to the dictionary and move to the next number. Continue this process until we’ve checked all numbers.”

  5. The key steps are:

    • Iterating over the input list of numbers.
    • For each number, computing the complement that would add up to the target.
    • Checking if this complement is already in the dictionary.
    • If the complement is in the dictionary, return the index of the complement (which was stored as its value) and the current index.
    • If the complement is not in the dictionary, add the current number along with its index to the dictionary.

    This is done to quickly identify the two numbers that add up to the target, by storing numbers and their indices for efficient lookup.

  6. The algorithmic pattern here is a single-pass hash table. We use a hash table to achieve a time complexity of O(1) for searching and inserting elements. By doing this in a single pass (i.e., by checking for the complement and updating the hash table in the same iteration), we’re able to solve the problem efficiently in linear time.

Language Agnostic Coding Drills

The code is solving the Two Sum problem using a dictionary to store seen numbers and their indices. This approach makes use of the concepts of array traversal, dictionary usage, and simple arithmetic operations.

Here are the steps or “units of learning” which build up the solution, arranged in increasing level of difficulty:

  1. Enumerating over an array: The first step involves looping over the provided list of numbers using enumerate(), which allows you to handle both the index i and the value of each element. This is crucial for keeping track of seen numbers and their indices.

  2. Arithmetic operations: For each number in the array, the code calculates the remaining value to reach the target. This is done by subtracting the current number from the target.

  3. Using a dictionary to check for a value: In this step, the code checks if the remaining value is already in the dictionary of seen numbers. This is essentially searching for a value in a dictionary, which is a fundamental operation in data structures.

  4. Returning the indices: If the remaining value is found in the dictionary, the code returns the current index and the index of the remaining value (which is stored as the value in the dictionary entry). This involves accessing dictionary values and building a list.

  5. Updating a dictionary: If the remaining value is not found, the code adds the current number and its index to the dictionary. This requires knowledge of how to update a dictionary in Python.

The problem-solving approach goes like this:

  • Start by initializing an empty dictionary to store the seen numbers and their indices.
  • Loop over the list of numbers. For each number, calculate the remaining value needed to reach the target.
  • If the remaining value is already in the dictionary, we have found a pair of numbers that add up to the target. Return their indices.
  • If not, add the current number and its index to the dictionary, and move on to the next number.
  • Continue this process until a pair is found or all numbers have been examined.

By combining these drills, you can understand and implement the solution to the Two Sum problem.

Targeted Drills in Python

  1. Enumerating over an array: Enumerating over an array is a fundamental operation in Python that lets you handle both the index and value of each element in the array.

    1
    2
    3
    4
    5
    
    def drill_enumerate(nums):
        for i, value in enumerate(nums):
            print(f'Index: {i}, Value: {value}')
    
    drill_enumerate([10, 20, 30, 40])
    
  2. Arithmetic operations: Simple arithmetic operations like addition and subtraction are fundamental for many algorithms. Here’s a drill to practice subtraction.

    1
    2
    3
    4
    5
    
    def drill_arithmetic(num1, num2):
        result = num1 - num2
        print(f'Result: {result}')
    
    drill_arithmetic(50, 25)
    
  3. Using a dictionary to check for a value: Here’s a drill to practice using a dictionary to check if a value is present.

    1
    2
    3
    4
    5
    6
    7
    
    def drill_dict_check(d, value):
        if value in d:
            print(f'Value {value} found in dictionary.')
        else:
            print(f'Value {value} not found in dictionary.')
    
    drill_dict_check({'apple': 1, 'banana': 2}, 'apple')
    
  4. Returning the indices: To practice creating and returning lists of indices, you could use the following drill.

    1
    2
    3
    4
    
    def drill_return_indices(i, j):
        return [i, j]
    
    print(drill_return_indices(1, 2))
    
  5. Updating a dictionary: Lastly, a drill to practice adding entries to a dictionary.

    1
    2
    3
    4
    5
    
    def drill_dict_update(d, key, value):
        d[key] = value
        return d
    
    print(drill_dict_update({'apple': 1}, 'banana', 2))
    

By combining these drills and applying the problem-solving approach described earlier, you can build the final solution for the Two Sum problem.

Q&A

In interview, I was asked what if duplicates exists.. How do we handle this? My original thought is worst case nums = [1,1,1,1] target is 2 then the complexity if N^2… Is it true? Is there any way to improve this?

The solution I provided earlier assumes that there is exactly one valid answer in the input, which is the condition mentioned in the problem statement. But if we extend the problem to have multiple valid answers, and we need to return all of them, then things change a bit.

First of all, if you’re asked to find all pairs that sum to a target and there could be duplicate pairs, then using a dictionary alone would not be enough because it can’t store duplicate keys. One potential solution is to store the indices in a list for each number as the value in the dictionary, and then when you find a pair that sums to the target, you could iterate over the Cartesian product of the two lists of indices. However, in the worst case scenario where all numbers are the same and they add up to the target (like your [1,1,1,1] with target 2 example), this will indeed result in a time complexity of O(N^2), because you would need to return all N^2 pairs.

However, if you are asked to find all distinct pairs, then there is an efficient solution with O(N log N) or O(N) time complexity. You can sort the array first, then use two pointers approach from both ends to find the pairs, or use a hash table similar to the original problem, but this time, each time you find a pair, you remove the elements from the hash table or decrease their counts.

Keep in mind that depending on the exact problem requirements, the solution may vary. For example, the requirements on whether to return duplicate pairs, whether the input array can be modified, and whether to return the indices or the actual numbers, etc., all can affect the choice of solution.

Then your follow up must be:

can I simply return any of the two indices that match the criteria or Do I have to return all the answers? If 1, it doesn’t matter. If 2, it’s going to be O(n^2) or you could use a map with keys as numbers and values as indices. That is O(n) Find the complement of the target with each number. That is O(n) if the complement happens to be the same number, then a permutation (set of 2 number permutations) of all the values present for that key. Technically speaking, finding permutations need not be calculated for the answer. But if done, the worst, if all the values in the list are same, it could be O(n^2). I couldn’t think of how to get it any lesser. Comments are appreciated on my mistakes or improvements

In general, the exact requirements will depend on the particular instructions given in the problem statement. If the problem specifies that you should return any one pair of indices that satisfies the conditions, then you can indeed return the first pair that you find. This can be accomplished in O(n) time by using the hash map approach described above.

However, if the problem asks you to return all pairs of indices that satisfy the conditions, the solution becomes more complex. While you can still use a hash map to store the numbers and their indices, you would also need to iterate through the hash map to find all pairs of numbers that sum up to the target. This would increase the time complexity to O(n^2) in the worst case scenario.

If the problem permits, one way to potentially optimize this is to sort the array first, which can allow you to use a two-pointer technique to find all pairs in O(n log n) time. However, this would alter the original indices, so it may not be suitable if the problem specifically asks for the original indices. Here’s an example of how you might do this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
def twoSum(nums, target):
    nums = sorted([(num, i) for i, num in enumerate(nums)])
    left, right = 0, len(nums) - 1
    results = []

    while left < right:
        curr_sum = nums[left][0] + nums[right][0]

        if curr_sum == target:
            results.append((nums[left][1], nums[right][1]))
            left += 1
            right -= 1
        elif curr_sum < target:
            left += 1
        else:
            right -= 1

    return results

Again, the best approach depends on the exact requirements of the problem. For most two-sum problems, it’s typically assumed that there is exactly one solution, and you are to return the indices of any one pair that sums to the target.

Can we use two pointer technique?

The two-pointer technique could indeed be applied to this problem, but with one important caveat: the list of numbers would first need to be sorted.

Here’s a step-by-step breakdown of how the two-pointer technique could be applied:

  1. Sort the list: Before we can use the two-pointer technique, we need to sort the list of numbers in ascending order. This is because the two-pointer technique relies on the ability to move one pointer to increase the sum (by moving the right pointer to the right) or decrease the sum (by moving the left pointer to the right).

  2. Initialize two pointers: Initialize a left pointer at the start of the list and a right pointer at the end of the list.

  3. Calculate the sum: Calculate the sum of the numbers at the left and right pointers.

  4. Compare the sum to the target: If the sum equals the target, then the numbers at the left and right pointers are the solution. If the sum is less than the target, then increase the left pointer to increase the sum. If the sum is greater than the target, then decrease the right pointer to decrease the sum.

  5. Repeat steps 3-4: Repeat steps 3-4 until the pointers meet. If the pointers meet and no solution has been found, then no solution exists.

However, it’s important to note that this approach requires sorting the list first, which has a time complexity of O(n log n) in the best case (using a sorting algorithm like quicksort or mergesort). Since the problem asks for the indices of the original unsorted array, you’ll need to keep track of the original indices before sorting, which adds to the complexity.

The approach of using a hash map to store the complements of the numbers, as shown in the previous code, has a time complexity of O(n) as it only requires a single pass through the list. This makes it a more efficient solution for this problem.

Way 1 –> Brute force –>O(n2) simply check if ith element is making a pair with any of the other element on the right side

Way 2–>Using Two Pointer approach–>O(n log n ) time complexity is nlogn because in this approach, the array will be first sorted and then , two pointer approach will be used

Way 3–>Using HashMap –>O(n) keep on storing the elements that we reach , also keep on check if target-element is already present in the hashmap or not , if it is , then we found a pair

You’ve perfectly summarized the three main approaches to solving this problem:

  1. Brute Force: This is the most straightforward approach where we simply check all possible pairs of numbers. For each number, we check if there’s another number in the array that, when added together, gives us the target. The time complexity of this approach is O(n^2), where n is the length of the array. This is because, in the worst-case scenario, we’re making n comparisons for each of the n elements in the array. This approach doesn’t require any extra space, so the space complexity is O(1).

  2. Two Pointer Approach: This approach involves first sorting the array, then using two pointers - one at the beginning and one at the end of the array - to find the pair. If the sum of the pair is greater than the target, we move the right pointer to the left. If the sum is less than the target, we move the left pointer to the right. The time complexity is O(n log n) due to the sorting step. If we need to preserve the original indices, this method could get complicated as sorting changes the positions of the elements.

  3. HashMap Approach: This approach involves creating a map to store the elements of the array as we traverse it. For each element, we calculate its complement (i.e., target - element). If the complement is in the map, we’ve found a pair that adds up to the target. If it’s not, we add the element to the map and move on to the next one. The time complexity of this approach is O(n), where n is the length of the array, since we’re making a single pass through the array. The space complexity is also O(n) for storing elements in the map. This method preserves the original indices and is generally more efficient than the previous two methods for this problem.

While not the most efficient approach, using two pointers also works, since you can first sort the array and then find the sum in O(nLogN) time. However, you also need to keep track of the original indexes which may cause a slower runtime.

Yes, you’re correct. The Two Pointer approach does work in this scenario but with a few caveats:

  1. The sorting step takes O(n log n) time, where n is the length of the array. This makes the Two Pointer approach slower than the HashMap approach, which takes O(n) time.

  2. As you mentioned, sorting the array changes the original order of the elements, which means the original indices can be lost. If the problem requires the original indices, we would have to store them before sorting, which adds extra complexity to the solution.

    A common way to deal with this issue is to create a list of pairs (or tuples in Python), where the first element of each pair is a number from the array and the second element is the original index of that number. Then, we can sort this list of pairs, which preserves the original indices.

  3. Unlike the HashMap approach, the Two Pointer approach cannot handle the case where the array contains duplicate elements that add up to the target. For example, in the case of nums = [3,3], target = 6, the Two Pointer approach would fail to identify that the two 3’s add up to 6.

In conclusion, while the Two Pointer approach can solve this problem, it is not the most efficient or straightforward method. The HashMap approach is generally preferred due to its faster runtime and its ability to handle duplicates.

All these solutions fail if there is a negative number but testcases are not present for them

The solutions provided above will still work with negative numbers.

The core of the problem is to find two numbers such that their sum equals the target. The numbers can be positive, negative, or zero.

For example, if you have nums = [3, -1, 4], target = 3, the numbers 4 and -1 add up to 3.

Both the hashmap and two-pointer approaches will correctly identify these two numbers. The hashmap method works by checking for each number, if the target minus that number is in the hashmap, and the two-pointer method works by sorting the array and then using two pointers to find two numbers that sum to the target. Both methods do not make any assumptions about the sign of the numbers and will work correctly even if the array contains negative numbers.

The reason why negative numbers don’t affect these solutions is that subtraction (which is used in the hashmap solution) and addition (which is used in checking if two numbers sum to the target) work the same way with negative numbers as with positive numbers. The two-pointer solution sorts the array, and sorting also works with negative numbers. So these solutions remain valid.

When solving the issue using two-pass hash table, a bit extra work will be needed to handle the order of the two index.

For example( when the input array contains duplicates and these duplicates are the solution)

Input [2, 2, 7] target 4

Result: [0,1]

Question: shall we use unordered_map or unordered_multimap(C++)?

Approach 1: If using unordered_map, only the first {2, 0} will be inserted. and theMap[target-nums[i]] will always return the 0. The solution provided will produce result [1, 0]. The extra work needed is to compare the two indexes in the result and return [smaller, bigger].

Approach 2: If using unordered_multimap, you need to use equal_range method to find out all index of duplicate data.

However, the one-pass hash table solution has no such issue at all by design. It just secretely avoid the case by coincidence i guess.

You are correct in your observations. Both of the mentioned issues can occur when solving the problem using a two-pass hash table.

In approach 1, using an unordered_map in C++, only the first instance of a duplicate key will be stored. This means that when the solution is found, the indices might be returned in the wrong order, and you would need to sort them before returning.

In approach 2, using an unordered_multimap can store multiple values for the same key. This means you can store all instances of a number. However, when retrieving these, you would have to use the equal_range method to get all the possible values and then check each one until you find the correct pair.

The one-pass hash table solution indeed avoids these issues by checking for the existence of the complement in the hash table before inserting the current number. This approach ensures that if a pair is found, the current index is always larger than the index stored in the hash table, hence maintaining the correct order.

Please remember that the best approach to use can depend on the specifics of the problem at hand and the requirements, such as whether the order of the returned indices matters.

n=len(nums) for i in range(0,n-1): for j in range(1,n): while(i!=j): if nums[i]+nums[j]==target : return (i,j) ——> it is showing time limit exceeded, can any one suggest better and simple one

The time complexity of your solution is O(n^2) due to the two nested for loops. Each time you are checking each pair of numbers to see if they add up to the target. This could be inefficient when the size of the array is large.

An improved approach is to use a hash table (dictionary in Python) to reduce the time complexity to O(n). The key idea is to check if each element’s complement (target - nums[i]) exists in the table.

Here’s the Python code:

1
2
3
4
5
6
7
def twoSum(nums, target):
    hash_table = {}
    for i, num in enumerate(nums):
        complement = target - num
        if complement in hash_table:
            return [hash_table[complement], i]
        hash_table[num] = i

In this solution, we create a dictionary/hash table. For each number in the array, we calculate the complement of that number (which is target - num). We then check if this complement is in our dictionary. If it is, we have found our two numbers, and we return their indices. If it’s not, we add the number and its index to our dictionary and continue to the next number. This way, we only need to go through the list once, which makes it faster for larger inputs.

My solution works but when I try to submit it, it says Output Limit Exceeded. Does someone know what the problem could be?

// SOLUTION

var twoSum = function(nums, target) { let p1 = 0, p2 = nums.length - 1 sum = 0 res = []

while(p1 < nums.length){ console.log(nums[p1], nums[p2]); sum = nums[p1] + nums[p2] if(sum === target){ res = [p1, p2] break } else { if(p2 === p1 + 1){ p1++ p2 = nums.length - 1 } else { p2– } } }

return res };

Your algorithm is based on a two-pointer technique, but it seems like it’s designed for a sorted array. In this problem, the array isn’t guaranteed to be sorted. Hence, your algorithm might not work in all cases, which is probably why you’re seeing the “Output Limit Exceeded” error.

Also, your solution has a time complexity of O(n^2), since in the worst case scenario (when there is no valid answer), it goes through all pairs of numbers.

A more efficient solution would be to use a hash table (a JavaScript object or Map), which allows you to solve the problem in O(n) time:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var twoSum = function(nums, target) {
    let numIndices = new Map();

    for(let i = 0; i < nums.length; i++){
        let complement = target - nums[i];
        if(numIndices.has(complement)){
            return [numIndices.get(complement), i];
        }
        numIndices.set(nums[i], i);
    }
};

In this solution, we create a map numIndices. For each number in the array, we calculate the complement of that number (which is target - num). We then check if this complement is in our map. If it is, we have found our two numbers, and we return their indices. If it’s not, we add the number and its index to our map and continue to the next number. This way, we only need to go through the list once, which makes it faster for larger inputs.

For a hash table implemented by ordered map, the time compexity of the solution becomes O(n logn)?

No, in a typical hash table implementation, the operations like searching, inserting, and deleting entries are done in constant time, O(1), on average. This is regardless of whether the hash table is implemented with an ordered map or not.

Hash tables achieve this speed because they use a hash function to map keys to specific buckets. This allows direct access to the value associated with a key.

However, in some specific cases like high collision scenarios, the operations can degrade to O(n), where n is the number of entries in the hash table.

Keep in mind that an ordered map, in languages like C++, has operations like insertion and lookup that are O(log n), not O(1). So if you’re using an ordered map to implement a hash table, your operations would take O(log n) time, not O(1).

In the context of this problem, a hash table is used to store the number and its index, and for each number, we check if its complement is in the hash table. This is done in O(1) time for each number, so the total time complexity is O(n), where n is the size of the input array.

what happens if we have more than one possibility of getting the output, like 9 can be written as 1+8 and 2+7 like that. how to retrieve all the starting and ending indexes.if you saw any type of problem like that kindly suggest me the code or link for that question

In the problem, it is specified that there is exactly one valid solution. However, if the problem were to be modified such that multiple pairs of numbers could sum to the target, you would need to adjust your approach to account for this possibility.

You could modify the hash table approach as follows. Instead of returning when a valid pair is found, you could add it to a list of solutions and continue iterating through the rest of the array.

Here is a Python example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def twoSum(nums, target):
    num_map = {}
    solutions = []

    for i, num in enumerate(nums):
        complement = target - num
        if complement in num_map:
            solutions.append([num_map[complement], i])
        num_map[num] = i

    return solutions

In this code, solutions is a list that stores all pairs of indices that sum to the target. If there are multiple pairs that sum to the target, all of them will be added to the solutions list.

Keep in mind that this solution assumes that you can use the same element twice in different pairs. If you can’t use the same element twice, you would need to remove or ignore elements from num_map once they have been used.

However, be aware that finding all possible pairs that sum to the target could potentially return a very large number of solutions in some cases. The exact number of solutions will depend on the specific values in the input array and the target value. This approach could also potentially use a significant amount of memory to store all the solutions.

Why is [3,2,4] target = 6 output cannot be [0,0] but for [2,5,5,11] the output can be [1,1]? Can anyone please explain?

The difference between the two scenarios you provided lies in the problem’s constraints and the nature of the problem itself. The problem statement says that each input would have exactly one solution, and you may not use the same element twice. This means that for each solution, the two numbers used to reach the target must be at distinct indices.

Let’s break down the two scenarios:

  1. In the first case, the array is [3,2,4], and the target is 6. The only pair of numbers that add up to 6 are 2 and 4. Since 2 is at index 1 and 4 is at index 2, the output is [1,2]. It cannot be [0,0] because that would mean we are using the number at index 0 (which is 3) twice, and that would violate the problem’s constraint of not using the same element twice.

  2. In the second case, the array is [2,5,5,11], and the target is 10. Here, 5 + 5 equals 10. But notice that even though the two numbers are the same, they are at different indices (1 and 2), so they are considered distinct. That’s why the output can be [1,2]. The output cannot be [1,1] or [2,2] as that would again violate the constraint of not using the same element twice.

So, to clarify, when the problem statement mentions “you may not use the same element twice”, it is referring to elements at the same index, not elements with the same value. If the same value appears more than once in the list (at different indices), each occurrence is considered a distinct element.

why do a lot of the solutions use vectors if the problem says array, if this is a interview question would i take the input into a vector or would i stick to trying to solve this using a array.

The term “array” is often used in a more general sense in many programming problems to refer to a collection of elements. In a language like Python, we might use a list to solve this problem. In JavaScript, we might use an array. In C++, an array, vector, or even a list could be used.

In C++, a std::vector is often preferred over a built-in array for a few reasons:

  1. Dynamic Size: Unlike arrays, vectors are dynamic, meaning that you can add or remove items on the fly. This is helpful in situations where you may not know ahead of time how many items you will be working with.

  2. Automatic Memory Management: With a vector, you don’t have to worry about allocating and deallocating memory manually. The vector will automatically handle memory for you.

  3. Convenient Methods: Vectors come with many built-in methods which can make your life easier, such as push_back() to add an element, size() to get the number of elements, etc.

In an interview situation, the important thing is that you are able to solve the problem effectively. If you are more comfortable using vectors, it’s perfectly acceptable to use a vector and explain why you chose to do so. If the interviewer prefers you to use an array for some reason, they will let you know.

For the following problem, my solution is mentioned below. When it compiled, no errors were identified. However, during submission, it failed in one test case. I tried running the same solution in Eclipse with the same test case, and it processed and was accepted. Please review the code below and provide feedback.

Test Case: [3,2,3]

class Solution { public int[] twoSum(int[] nums, int target) { int[] result = new int[2]; for (int i=0; i<nums.length; i++) { for (int j=1; j<nums.length;j++) { if (nums.length==2) { if(nums[0]+nums[1]==target) { result[0]=0; result[1]=1; break; } } else if(target-nums[i]==nums[j]) { result[0]=i; result[1]=j; break; } } }return result; } }

There are two problems with your code:

  1. In the inner loop, you’re always starting j from 1. This will lead to a problem when there are more than two numbers in nums. If the pair that sums to the target includes the first number in the array (nums[0]), your code won’t be able to find it because j never equals 0. Instead, you should start j from i+1 so it can compare each number with the numbers that come after it, including the first number.

  2. You’re using a break statement to exit the inner loop when you find a pair that adds up to the target. However, this break statement only exits the inner loop, not the outer loop. As a result, your code continues to run even after it has found the answer, which could cause it to overwrite the correct answer if it finds another pair that adds up to the target. You can fix this by returning the result immediately when you find a pair that adds up to the target.

Here’s a corrected version of your code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution {
    public int[] twoSum(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = i+1; j < nums.length; j++) {
                if (nums[i] + nums[j] == target) {
                    return new int[]{i, j};
                }
            }
        }
        throw new IllegalArgumentException("No two sum solution");
    }
}

This version will return the correct indices as soon as it finds a pair that adds up to the target. If it finishes running without finding a pair that adds up to the target, it will throw an exception, because the problem statement guarantees that there will always be exactly one solution.

So i tried to solve ths problem in python using an outer loop and an inner loop,the first loop will carry an elemnt from the nums to the inner loop and the inner loop will take another element into the if condition which checks if they both add upto target and if does the an and conditon says that both indexes should not be same.This is working fine with more than 2 numbers but i foundout that for some reason wih an array with 2 numbers,the inner loop is not incrementing to the second elemtn instead it just iterates the first elemtn two times and the outer loop also does not increment to the next element.why is this happening

From your description, it sounds like you’re facing issues with handling arrays of length 2. I would need to look at your code to identify the specific issue, but generally, your approach seems to be correct.

Here is how you can solve it using two loops in Python:

1
2
3
4
5
6
def twoSum(nums, target):
    for i in range(len(nums)):
        for j in range(i + 1, len(nums)):  # start from the next element
            if nums[i] + nums[j] == target:
                return [i, j]
    return []

The outer loop i starts from index 0 and goes until the end of the list. The inner loop j always starts from the next index after i and goes until the end of the list. This ensures that we don’t add a number with itself (unless the number is repeated in the list).

If you’re still having trouble, I suggest posting your code so I can better understand the specific issues you’re encountering.

why isnt this method coming as right?? vector twoSum(vector& nums, int target) { unordered_map<int,int> mp; for(int i=0;i<nums.size();i++){ mp[nums[i]]=i; int find=target-nums[i]; if(mp.find(find)!=mp.end()){ return { mp[find],mp[nums[i]]}; }

}
return {};

}

Your method is mostly correct, but it fails when the same number is used twice.

The main problem is that you’re adding the number to the map before checking if the complement exists in the map. If the target is twice a certain number, your function will fail because it will find the number in the map before the second occurrence of the number has been processed.

Here’s a corrected version of your code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
vector<int> twoSum(vector<int>& nums, int target) {
    unordered_map<int, int> mp;
    for (int i = 0; i < nums.size(); i++) {
        int find = target - nums[i];
        if (mp.find(find) != mp.end() && mp[find] != i) {
            return {mp[find], i};
        }
        mp[nums[i]] = i;
    }
    return {};
}

In this version, I first check if the complement of the current number is in the map, and if it is, I return the indices. Only after this check do I add the current number to the map. This ensures that we do not incorrectly identify a number as its own complement. Also, the condition mp[find] != i is necessary to ensure that we don’t use the same element twice.

class Solutions(object): def two_sum(self, nums, target): self.nums = nums self.target = target

def input(self): nums = [1, 2, 3, 4, 5]

m = int(input("Enter the first index value: "))
n = int(input("Enter the second index value: "))

if 0 <= m < len(nums) and 0 <= n < len(nums):
    y = self.nums[n] + self.nums[m]
    print(y)
else:
    print("Invalid index value!")

sol = Solutions() sol.two_sum([1, 2, 3, 4, 5], 0) sol.input()

could anyone tell me whats wrong with code

Your code does not follow the problem statement correctly. The task requires you to find two indices in the given array whose corresponding values sum up to a given target value. But in your code, you are asking the user to input two indices and then you are returning the sum of values at these indices. It’s not solving the problem as expected.

Here is the corrected Python code for the twoSum problem:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class Solution(object):
    def twoSum(self, nums, target):
        # Create a dictionary to store the number and its index
        num_map = {}
        # Enumerate through the numbers list
        for i, num in enumerate(nums):
            # Calculate the complement of the current number with respect to the target
            complement = target - num
            # If the complement is in the map, we have found the pair that adds up to target
            if complement in num_map:
                # Return the current index and the index of the complement
                return [num_map[complement], i]
            # Add the current number and its index to the map
            num_map[num] = i
        # If no such pair is found, return an empty list
        return []

This Solution class contains a method called twoSum that takes a list of integers nums and an integer target and returns indices of the two numbers such that they add up to target.

To use the Solution class, you can do:

1
2
sol = Solution()
print(sol.twoSum([1, 2, 3, 4, 5], 9))

The output would be [3, 4] since nums[3] + nums[4] == 9.

I tried this code with python. When nums=[0,4,3,0] and target is 0 this code return nothing. Can anybody help?

class Solution(object): def twoSum(self, nums, target): """ :type nums: List[int] :type target: int :rtype: List[int] """ for ind in range(len(nums)): if nums[ind]<target: try: adj=nums.index(target-nums[ind],ind+1) except: adj=0 if adj: return [ind,adj]

Your code attempts to solve the problem by iterating through the array, and for each number, it tries to find if the complement (target - nums[ind]) is present in the rest of the array.

However, it has two main issues:

  1. It incorrectly skips the case when nums[ind] equals target. This is problematic for inputs like nums = [0, 4, 3, 0] and target = 0.
  2. It doesn’t handle negative numbers and zero correctly. Your solution only attempts to find pairs when nums[ind] is less than target, which will fail if the target or any number in nums is negative or zero.

Here is a correct solution using a similar approach, but with a hashmap for constant time look-up:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        num_dict = {}  # to store {num: index} pairs
        for ind, num in enumerate(nums):
            complement = target - num
            if complement in num_dict:
                return [num_dict[complement], ind]
            num_dict[num] = ind  # add the current number and its index to the dict
        return []  # return an empty list if no solution is found

This code maintains a dictionary to keep track of the numbers seen so far and their indices. For each number, it checks if the complement is already in the dictionary. If so, it returns the indices of the two numbers. If not, it adds the current number and its index to the dictionary. This approach handles all edge cases correctly and has a time complexity of O(n), where n is the length of nums.

2 pointer approach is showing TLE, even though it has O(n) complexity. Help !!!

The two-pointer approach usually has a time complexity of O(n), assuming the array is already sorted. However, if you need to sort the array first, the overall time complexity becomes O(n log n), which could be too slow if the size of the array (n) is very large.

Moreover, please note that the two-pointer approach might not be the best approach for this particular problem. This is because sorting the array would lose the original index information, which is required to output the correct result.

The hash map approach is more efficient for this problem, as it can keep track of original indices and find the result in one pass (O(n)).

Here’s a Python example:

1
2
3
4
5
6
7
def twoSum(nums, target):
    num_dict = {}  # Initialize an empty hash map
    for i, num in enumerate(nums):
        if target - num in num_dict:
            return [num_dict[target - num], i]  # Return the indices of the two numbers
        num_dict[num] = i  # Add the current number and its index to the hash map
    return []  # Return an empty list if no solution is found

This code keeps track of the numbers we’ve seen so far and their indices in num_dict. For each number, it checks if the complement (target - num) is already in num_dict. If so, it returns the indices of the complement and the current number. If not, it adds the current number and its index to num_dict. This approach allows us to find the solution in a single pass through the array, making it more efficient than the two-pointer approach for this problem.

The term add “up to” should be change to equal to !_!, upto make me think it’s <= target.

In this context, “add up to” indeed means that the sum of two numbers should be equal to the target. In general mathematical parlance, “add up to” means the sum of the numbers is exactly equal to a certain value. It’s not meant to imply that the sum should be less than or equal to the target value.

So for the problem statement, “Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target”, it means you need to find two numbers in the array that when added together, exactly equal the target value.

When I run the below code, it works correctly against Case 1, Case 2, and Case 3. However, when I submit, it errors. The indices it returns when submitting are the same (0, 0) thus causing it not to pass submission. However, I don’t get this error when Running it against the Cases as it has different indices for each Case. Can anyone help explain why this is behaving in this way?

`class Solution { public int[] twoSum(int[] nums, int target) { int[] indices = new int[2]; int currIndex = 0; int startingIndex = 1;

for(int i = startingIndex; i < nums.length; i++){
    if (nums[currIndex] + nums[i] == target){
        indices[0] = currIndex;
        indices[1] = i;
        break;
    }
    ++currIndex;
    startingIndex += 1;
}   
return indices;

} }`

The issue with the code is that the incrementation of currIndex and startingIndex is done inside the for loop after the if condition, but it should be done in the outer scope, and the for loop should iterate over the range from startingIndex to the end of nums for every currIndex.

The problem is that currIndex is only incremented if the if condition is not met. Once a pair that sums up to the target is found, the currIndex stops incrementing and startingIndex is not properly updated. This is why you are only seeing the indices as (0, 0) in your failing test cases. The loop is not fully traversing the nums array for every index.

Here is a corrected version of your code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] indices = new int[2];

        for(int currIndex = 0; currIndex < nums.length; currIndex++){
            for(int i = currIndex + 1; i < nums.length; i++){
                if (nums[currIndex] + nums[i] == target){
                    indices[0] = currIndex;
                    indices[1] = i;
                    return indices; // Once you've found a pair, you can return immediately
                }
            }
        }   

        // If no pair is found in the entire array, return an empty array.
        // This will never be the case in the problem as it's guaranteed that there's always a valid answer.
        return new int[]{};
    }
}

This version of the code uses two nested loops. The outer loop picks the first number, and the inner loop checks if a pair is found with every other number in the array. As soon as a pair is found, the function returns.

Why is this solution wrong?:

let nums = [2,7,11,15]

`const twoSum = function(target){ for (let i= 0; i < nums.length; i++){ for (let j= i + 1; j < nums.length; j++) { if (nums[i] + nums[j] === target) { return [i,j] && console.log([i,j]) } } } }

twoSum(9)`

If I try it outside of Leetcode I still get the correct output on each example (e.g [0,1] with target 9, [1,2] with target 6).

The code is correct in terms of functionality - it does indeed find two numbers in the array that add up to the target, and return their indices. However, there seems to be a small confusion in your return statement: return [i,j] && console.log([i,j]).

Here’s a simplified and correct version:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
let nums = [2,7,11,15]

const twoSum = function(nums, target){
    for (let i= 0; i < nums.length; i++){
        for (let j= i + 1; j < nums.length; j++) {
            if (nums[i] + nums[j] === target) {
                return [i, j];  // just return the pair of indices
            }
        }
    }
}

console.log(twoSum(nums, 9));  // you can log the function call

In your version, the && operator is used, which is a logical AND operator. It doesn’t make sense to use it here because you want to do two separate things - return the result, and log it to the console. In JavaScript, && operator returns the first falsy value. If both values are truthy, the second value is returned. So, your original return statement would just return [i, j], and the console.log part wouldn’t be executed.

In the corrected version, the function twoSum just returns the result, and then you can log that result to the console outside of the function.

i have a qn.. how to take input an array without knowing its definite length in java… its hard to find online… can anyone tell me here pls

In Java, array lengths are fixed upon creation and cannot be changed dynamically. So, to take input for an array without knowing its definite length, we need to use some kind of dynamic data structures such as ArrayList or LinkedList.

Here’s a simple way of taking input using ArrayList with Scanner:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import java.util.*;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        Scanner scanner = new Scanner(System.in);
        System.out.println("Enter integers (type 'exit' to finish):");

        while(scanner.hasNextInt()){
            list.add(scanner.nextInt());
        }

        // If you need an array, you can convert this list to an array
        Integer[] array = list.toArray(new Integer[list.size()]);

        // print the array elements
        System.out.println("Elements of the array: " + Arrays.toString(array));
    }
}

In this example, you enter numbers from the command line one by one. When you want to finish entering numbers, you type exit, and the program will stop accepting numbers, convert the list to an array, and print out the array.

Remember, though, that this will give you an array of Integer objects, not int primitives. If you need an int[], you’ll need an extra step to convert from Integer[] to int[].

class Solution { public: vector twoSum(vector& nums, int target) { int n = nums.size();

vectorp;

int s = 0;
int e = n-1;

while(s<e){ if((nums[s] + nums[e]) == target){ break;

   }
   else{
       s++;
       e--;
   }
p.push_back(s);
p.push_back(e);

}

return p; } };

someone pls modify this code as it showing memory limit exceed

The memory limit is exceeded because your loop runs indefinitely when it doesn’t find a solution. In that case, it keeps on pushing “s” and “e” to the vector “p” until it fills up all available memory.

The root of this problem is that you’ve assumed the input “nums” is sorted, which is not stated in the problem. The two-pointer technique you’re using only works correctly on sorted arrays. When “nums” is not sorted, your loop may miss the correct pair or run indefinitely when there’s no solution.

Here’s a revised version of your code that correctly handles unsorted inputs by using a hash map:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> indices;
        for (int i = 0; i < nums.size(); ++i) {
            int complement = target - nums[i];
            if (indices.count(complement)) {
                return {indices[complement], i};
            }
            indices[nums[i]] = i;
        }
        return {};  // return an empty vector if no solution
    }
};

This code loops through the “nums” array. For each element, it calculates the “complement” (the number you’d need to add to it to get “target”), then checks whether this number is already in the “indices” map. If it is, that means the current element and the previously-seen complement element add up to “target”, so it returns their indices. If it’s not, the code adds the current element and its index to the “indices” map, then moves on to the next element. If it gets through the whole array without finding a pair that adds up to “target”, it returns an empty vector.

i am trying to slove this problem but i get this error ?

Line 25: Char 5: error: redefinition of ‘main’ [solution.c] int main(int argc, char *argv[]) {

i tried it in othar compler and it is work , how can i avoid this error here?

can someone help me ?

This error typically occurs when you have more than one main function in your program or you are trying to compile multiple files where each file has a main function. The main function is the entry point to a C program and can only be defined once.

Make sure you’re not creating multiple instances of the main function.

Here’s a basic structure of how your program should look:

1
2
3
4
5
6
7
8
9
#include <stdio.h>

// define your function(s) here

int main(int argc, char *argv[]) {
    // your code here

    return 0;
}

Ensure you only have one main function in your program. If you are running the code locally, make sure you are compiling only the desired .c file.

how to i return a int* type?

In C, you can return a pointer to an integer (int*) by first creating it (usually dynamically using malloc or calloc), setting its value(s), and then returning it from the function. Here is an example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include <stdlib.h>

int* createAndSetInt(int value) {
    int* myIntPointer = malloc(sizeof(int));  // Allocate memory for an int
    *myIntPointer = value;  // Set the value of the int at the memory address
    return myIntPointer;  // Return the pointer to the int
}

int main() {
    int* myInt = createAndSetInt(5);
    printf("%d\n", *myInt);  // Outputs: 5

    // Remember to free the allocated memory once you're done with it
    free(myInt);
    
    return 0;
}

In this example, createAndSetInt is a function that creates an int dynamically, sets its value to the provided value, and then returns a pointer to it.

This type of allocation is useful when you need the data to stay alive longer than the function call itself, because the memory allocated with malloc or calloc isn’t deallocated when the function ends (it sticks around until free is called).

Please note, it’s very important to remember to free any memory you allocate this way, once you’re done with it. Otherwise, you can end up with a memory leak, where you’ve reserved some memory, but aren’t using it and have lost the ability to free it. This can lead to running out of memory if you do it a lot.

Also, always check the return value from malloc or calloc. If the system can’t allocate the memory (i.e., you’re out of memory), malloc or calloc will return NULL. If you try to access memory through a NULL pointer, your program will likely crash.

I am generally new to coding (python) and I have few confusions (or questions) that I wanted to ask. I learned that when you create a class you need a method that initializes the class using init. The default code given doesn’t have a separate method that has init. Does the leetcode (or interviewer), expect us to create an empty method that initialize the class with init ?

In Python, the __init__ method is a special method that you can define in your class to create an initialization procedure for objects of that class. It’s often used to set up initial values for instance variables. However, __init__ isn’t required for a class to function.

When you see a class in Python (like on LeetCode) that does not define an __init__ method, it simply means that the class does not need to do anything specific when objects of the class are initialized.

For the specific case of coding problems on LeetCode or in interviews, if you see a class definition, they usually provide a method that you need to implement. You would usually not need to define your own __init__ method, unless the problem specifies that you need to do something specific upon object initialization.

Here’s an example with __init__:

1
2
3
4
5
6
class MyClass:
    def __init__(self):
        self.my_variable = 0

    def my_method(self):
        return self.my_variable + 1

Here, __init__ is used to set up an instance variable my_variable.

But the following is also a completely valid class definition:

1
2
3
class MyClass:
    def my_method(self, input):
        return input + 1

In this second class, there’s no __init__ method, and my_method uses its arguments, not instance variables.

Both of these examples are valid classes, and would be used in different situations, depending on what you need the class to do.

I’m confused as to why the description calls nums an “array of integers” while the parameter reads “vector& nums” (with the return type of the function being the same type). Why is this?

The instructions don’t specify what to do/return if there are no two numbers in the inputted array which add up to the target value. In this case, are we to simply return 1?

  1. Vector vs. Array: In C++, the standard library includes a type called vector which is essentially a dynamic array. It can resize itself automatically when an element is inserted or deleted, with their storage being handled automatically by the container. The term “array” is often used in a more general sense to refer to a sequence of elements, not necessarily the specific fixed-size array type in C++. When the problem statement refers to an “array”, it’s talking conceptually about the input: a sequence of numbers. When the function signature uses a vector, it’s specifically choosing to use the C++ vector type to represent that sequence.

  2. Undefined Behavior: You’re correct that the problem doesn’t specify what to do if there are no two numbers that add up to the target value. When the problem doesn’t specify behavior, that usually means it’s a situation you don’t need to handle. For the specific problem of finding two numbers that add up to a target value, the problem statement usually assumes that there is exactly one solution, so you don’t need to worry about the case where there’s no solution.

    However, if you wanted to handle such a case in a real-world scenario, what you’d return would depend on the context. You might return an empty vector to signify that no pair was found, or you might throw an exception. Returning a 1 might be misleading, because the function is expected to return a vector of indices. An empty vector would be a more appropriate indication of the lack of a solution. But again, for the scope of this problem, you can assume there will always be a solution.

I’m solving in python 3. Why is the function inside a class? Does it have any meaning for the end result? Would the solution be different (or even possible if there was no class? I feel like this is unnecessarily confusing

In Python, classes are used for object-oriented programming (OOP), which is a programming paradigm that provides a means of structuring programs so that properties and behaviors are bundled into individual objects. However, in the context of coding problems on platforms like LeetCode, the use of classes mainly provides a standardized way of presenting the problem and evaluating solutions.

In many coding problems on LeetCode, the solution function is encapsulated in a class. The reason behind this is to provide a consistent interface for the problems, and it has no effect on the actual algorithm or data structure you are asked to implement.

In Python, you would typically not need to use a class for simple functions like these. You could easily solve these problems with standalone functions. However, LeetCode uses classes to fit with their testing infrastructure, which runs multiple test cases by creating an instance of your solution class and then calling the method on that instance for each test case.

This might seem a bit confusing initially, especially if you are not familiar with classes in Python or object-oriented programming in general, but rest assured that it is not a crucial concept for solving these types of problems. It’s more of a structural requirement for the platform.

Your solution would not be different whether you put your function in a class or not; it’s just about how you organize your code. The most important thing is the logic within your function.

var twoSum = function(nums, target) { for(i=0;i<nums.length;i++){ for(j=i;j<nums.length;j++){ if(nums[i]+nums[j]===target){ console.log(i,j) } } // console.log(target) // console.log(nums[i]); } }; twoSum([2,7,11,15],9);

is there any problem it is giving same solution but it is not accepting

The problem with your code is that you are using console.log to print out the indices where the sum equals the target. The question requires you to return the indices as an array.

Also, your second loop should start from j=i+1, not j=i. If it starts from i, you might sum up the same element and get incorrect results.

Here’s the corrected code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var twoSum = function(nums, target) {
    for(let i=0;i<nums.length;i++){
        for(let j=i+1;j<nums.length;j++){  // j starts from i+1
            if(nums[i]+nums[j]===target){
                return [i,j];   // return the indices instead of printing them
            }
        }
    }
};

console.log(twoSum([2,7,11,15],9));

In the above code, I used let instead of var to define i and j because let has block scope, which means it only exists within the loop. This is a good practice in modern JavaScript.

I’m trying this one in C. I created the array pointer with malloc(), assigned values, and print it’s content to stdout successfully. I get the correct indices, but after returning an int *, the output just shows a closing bracket ]. Any suggestions?

If you’re experiencing issues with returning a dynamically allocated array in C, the problem might be with how you’re returning the array or how you’re trying to print the returned values.

In C, you can return a pointer to the first element of an array. The function signature would look like this:

1
int* yourFunction(int* nums, int target, int numsSize, int* returnSize)

You’d call malloc() to allocate space for your result array, then return the pointer to that space:

1
2
3
4
5
int* result = malloc(2 * sizeof(int));
result[0] = index1;
result[1] = index2;
*returnSize = 2;  // set the output parameter to the result size
return result;

When you want to print the results, you’ll need to dereference the pointer and use the size of the returned array:

1
2
3
4
5
6
int returnSize;
int* result = yourFunction(nums, target, numsSize, &returnSize);
for (int i = 0; i < returnSize; i++) {
    printf("%d ", result[i]);
}
free(result);  // don't forget to free the memory when you're done!

If the output just shows a closing bracket, it’s possible that you’re not correctly initializing or returning the array, or that there’s an issue with how you’re trying to print the array. If you can share the code you’re working with, it would be easier to diagnose the issue.

i do not understand constrains . 2 <= nums.length <= 104 -109 <= nums[i] <= 109 -109 <= target <= 109

what is it’s implication

The constraints given in the problem statement are there to set the bounds for the input values. They give you information on what kind of input to expect and how you should design your solution to accommodate those inputs. Let’s break down what each constraint means:

  1. 2 <= nums.length <= 104 : This constraint means that the length of the array nums will be at least 2 and at most 104 (10,000). Therefore, your solution should be able to handle arrays of these sizes without running into issues like timeouts or memory limits.

  2. -109 <= nums[i] <= 109 : This constraint means that each individual number in the array nums will be at least -109 (-1,000,000,000) and at most 109 (1,000,000,000). This sets the range for each number in your array.

  3. -109 <= target <= 109 : This constraint means that the target sum will be at least -109 (-1,000,000,000) and at most 109 (1,000,000,000). This is the range for the target value you are trying to achieve with the sum of two numbers in the array.

These constraints can guide your approach to the problem. For instance, because the numbers can be quite large, you would want to avoid solutions that might lead to integer overflow. Similarly, because the array can be fairly long, a solution with a time complexity of O(n^2) might not be efficient enough, and you might need to find a solution with a time complexity of O(n) or similar.

My array shows the right stuff but when I return my array I keep getting “]” as the output no matter what. How to fix? I do my code in c. ` int *array = malloc(sizeof(int) * 2);

for (int i = 0; i < numsSize; i++) { for (int j = i + 1; j < numsSize; j++) { if (nums[i] + nums[j] == target) { array[0] = i; array[1] = j; break; } } } return array;

If your function signature is similar to int* twoSum(int* nums, int numsSize, int target, int* returnSize), you should make sure to set the returnSize to the length of the array you’re returning. In your case, that would be 2, since you’re returning an array of two integers.

The purpose of returnSize is to tell the calling function how many elements are in the array that is being returned. Without this, the calling function has no way to tell how many elements there are in the returned array.

Your code should look something like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    int *array = malloc(sizeof(int) * 2);

    for (int i = 0; i < numsSize; i++) {
        for (int j = i + 1; j < numsSize; j++) {
            if (nums[i] + nums[j] == target) {
                array[0] = i;
                array[1] = j;
                *returnSize = 2; // Set the return size.
                return array;    // You can return here. No need to iterate further.
            }
        }
    }

    *returnSize = 0; // If no pair was found, return size should be 0.
    return NULL; // Return NULL if no pair was found.
}

Please modify according to your function signature and other specifications.

what is the return type of vector function

In the context of C++, vector is a container provided by the Standard Template Library (STL). It’s a dynamic array, allowing elements to be efficiently added or removed without managing memory manually.

When you use a vector, you specify the type of elements it should hold. For example, std::vector<int> is a vector of integers, std::vector<float> is a vector of floats, and so on.

When you see something like this:

1
2
3
4
5
std::vector<int> get_values()
{
    std::vector<int> values = {1, 2, 3, 4, 5};
    return values;
}

The return type of the function get_values is std::vector<int>, meaning it returns a vector of integers.

In the case of the Two Sum problem, the expected function signature is likely something like vector<int> twoSum(vector<int>& nums, int target). Here, vector<int> is the return type of the function twoSum, meaning this function is expected to return a vector of integers. The input is a reference to a vector of integers and an integer target.

ine 24: Char 5: error: expected member name or ‘;’ after declaration specifiers return res; ^

vector res = {l,r};

return res;
}; Why do i see this?

The error you are seeing is most likely due to a syntax error in your C++ code. You’re attempting to return res outside of any function. The return statement must be inside a function.

Here is a correct example:

1
2
3
4
5
6
#include <vector>

std::vector<int> twoSum(std::vector<int>& nums, int target) {
    std::vector<int> res = {0, 1};  // just an example, replace with actual code
    return res;
}

In this case, return res; is inside the twoSum function.

Please ensure that your return res; statement is inside a function and not outside of it. If it’s outside, the compiler won’t know what to do with it, leading to the error you’re seeing. Without the full context of your code, it’s a bit hard to give a more precise answer, but this is the most likely issue based on the information you’ve provided.

Please my code below and post your suggestion to optimize it,

class Solution { public int[] twoSum(int[] nums, int target) { int[] arr=new int[2]; for(int i=0;i<nums.length;i++){ for (int j=i+1;j<nums.length;j++){ if(nums[i]+nums[j]==target){ arr[0]=i; arr[1]=j; } } } return arr; } }

Your current solution has a time complexity of O(n^2) due to the use of two nested for-loops, which can be inefficient when dealing with larger input arrays. Here’s a more optimized solution using a HashMap that achieves a time complexity of O(n):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import java.util.HashMap;
import java.util.Map;

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> numMap = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int complement = target - nums[i];
            if (numMap.containsKey(complement)) {
                return new int[] { numMap.get(complement), i };
            } else {
                numMap.put(nums[i], i);
            }
        }
        throw new IllegalArgumentException("No two sum solution");
    }
}

This code essentially uses a HashMap to store the elements of the array as it iterates through them. For each element, it checks if its complement (target - current element) exists in the HashMap. If it does, that means we have found two numbers that add up to the target, and we return their indices. If it does not, we add the current number and its index to the HashMap and continue with the next iteration.

The HashMap allows for constant time (O(1)) lookups, making this approach significantly faster for larger input arrays.

What if there are two solutions that matches the target?

The problem statement for the Two Sum problem specifies that there will be exactly one solution, and you may not use the same element twice.

So, in the context of this problem, you don’t need to worry about handling multiple possible solutions. Once you find one valid pair of indices, you can return it right away.

If you were asked to handle multiple solutions in a variation of this problem, you might return a list of all pairs of indices that add up to the target. This would be a more complex problem and likely require a different approach. For instance, you might use a method that involves sorting the array and then using two pointers, one starting from the beginning and the other from the end, and moving them towards each other. Or you could still use a hash map but store all possible indices for each value, and then for each index, look for all possible pairings. This, however, can lead to duplicates which need to be handled separately.

But, in the context of the original problem, you only need to find one valid solution.

Hi am absolutely new to javascript. I get the information in the examples given. But how do you know what you’re supposed to write? Am I supposed to fill in more information in the editor? and then say output= something?

In this problem, you are expected to fill out the provided twoSum function, such that it returns an array of two indices where the numbers in the array at those indices add up to the target. Here’s an example of what you could write:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var twoSum = function(nums, target) {
    // We'll use a hash map to store the numbers we've seen so far
    let map = {};

    // Iterate through the array of numbers
    for(let i = 0; i < nums.length; i++) {
        // Check if the current number's complement (target - current number)
        // exists in our map
        let complement = target - nums[i];

        if(map[complement] !== undefined) {
            // If it does, we've found two numbers that add up to our target!
            // Return their indices
            return [map[complement], i];
        }

        // If not, add the current number to our map
        map[nums[i]] = i;
    }

    // If we get through the whole array and haven't returned yet, there's no solution
    // (although in this problem, we know there will always be a solution)
};

When you run the code, the platform will automatically test your function against different test cases by calling your function with different arguments and checking the return value against the expected result. There’s no need to manually call the function or print any output in the code editor.

So in this problem, you just need to write the twoSum function, and the platform will take care of the rest. You’re not expected to write any other code outside of that function.

How can we return two values in cpp??

In C++, you can’t directly return multiple values from a function. However, there are ways to achieve similar results:

  1. Use a std::pair or std::tuple if you have a small, fixed number of items to return.
  2. Use a std::vector or std::array if you have multiple items of the same type to return.
  3. Use a std::map, std::unordered_map or std::set if you have key-value pairs to return.
  4. Use a structure or class if the return values can be logically grouped together.

For example, if you wanted to return two int values from a function, you could do it like this using std::pair:

1
2
3
4
5
6
std::pair<int, int> myFunction() {
    int a = 5;
    int b = 10;

    return std::make_pair(a, b);
}

And you can access the returned values like this:

1
2
3
std::pair<int, int> result = myFunction();
std::cout << "First value: " << result.first << std::endl;
std::cout << "Second value: " << result.second << std::endl;

In the specific context of the Two Sum problem, you would return a std::vector<int> with the two indices. Here’s an example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
std::vector<int> twoSum(std::vector<int>& nums, int target) {
    std::unordered_map<int, int> map;
    for (int i = 0; i < nums.size(); i++) {
        int complement = target - nums[i];
        if (map.count(complement)) {
            return {map[complement], i};
        }
        map[nums[i]] = i;
    }
    return {};  // Return an empty vector if no solution is found
}

In this example, the return {map[complement], i}; line creates a std::vector<int> with two elements and returns it.

class Solution { public: vector twoSum(vector& nums, int target) { for(int i=0;i<nums.size();i++) { for(int j=1;j<nums.size();j++) { if(nums[i]+nums[j]==target) { cout«i«","«j; } } }

} };

Line 15: Char 5: error: non-void function does not return a value [-Werror,-Wreturn-type] } ^ 1 error generated.’ This error is generating.Some one please help

The error message indicates that the function twoSum is declared to return a value of type vector<int>, but it does not return anything at the end. The code currently only prints the indices that add up to the target, instead of returning them.

Here’s how you can modify your code to fix this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        for(int i=0; i < nums.size(); i++) {
            for(int j = i+1; j < nums.size(); j++) {
                if(nums[i] + nums[j] == target) {
                    return {i, j};  // Return the indices as soon as you find them.
                }
            }
        }
        return {};  // Return an empty vector if no solution is found.
    }
};

This function now returns a vector<int> that contains the two indices as soon as they’re found, and if no two numbers sum up to the target, it returns an empty vector.

Input: nums = [2,7,11,15], target = 9 Output: [0,1] Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].

public class Solution { public int[] TwoSum(int[] nums, int target) { for(int i=0,j=i+1;i<sizeof(nums);i++,j++) { sum=nums[i]+nums[j]; if(sum==target) { return i,j; } } } }

is this okay becoz i wont get output? kindly reply

Your current code contains several issues:

  1. In C# (which your code appears to be written in), sizeof(nums) won’t give you the length of the array. You should use nums.Length.

  2. The j variable is not properly defined in the for loop, and it should be reset to i+1 at each iteration.

  3. C# doesn’t allow returning multiple values directly using return i, j;. You should return an array or a list instead.

  4. The sum variable is not defined.

Here’s a corrected version of your code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public class Solution {
    public int[] TwoSum(int[] nums, int target) {
        for(int i = 0; i < nums.Length; i++) {
            for(int j = i + 1; j < nums.Length; j++) {
                int sum = nums[i] + nums[j];
                if(sum == target) {
                    return new int[] {i, j};
                }
            }
        }
        return new int[] {-1, -1};  // return -1, -1 if no solution is found
    }
}

This code will iterate through nums and for each number, it will check if any other number in the array adds up to the target. If it finds such numbers, it returns their indices in an array. If it doesn’t find any, it returns [-1, -1] to signify that no solution was found.

class Solution { public int[] twoSum(int[] nums, int target) { int n= nums.length; for(int i=0,j=i+1;i<n;){ if(nums[i]+nums[j]==target) return new int[]{i,j}; j++; if(j==n){ i++; j=i; } } return null; } } i am having 53/57 test cases passed but this code is working properly in local deviced

Your solution is not working for certain edge cases because of the way you’re incrementing j. In your approach, when you increment i, you also set j to i, but it should be j = i + 1.

Here’s the corrected version of your code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int n= nums.length;
        for(int i=0; i<n; i++){
            for(int j=i+1; j<n; j++){
                if(nums[i]+nums[j] == target){
                    return new int[]{i,j};
                }
            }
        }
        return null;
    }
}

This way, for each i, you check every pair of numbers in the array that hasn’t been checked yet. If you find a pair of numbers that adds up to the target, you return their indices. If no such pair is found, you return null.

Please note that the time complexity of this solution is O(n^2) due to the use of nested loops, where n is the length of the input array. There are more efficient solutions (like using a hash map) that can solve this problem with a time complexity of O(n).

class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: for i in nums: for j in nums[1:]: if i + j == target: lol = [nums.index(i), nums.index(j)] break return lol

Can you tell me where is the issue because I can’t pass the third case.

The issue lies in how you are using the index method. If there are duplicate values in the nums list that make up the target, it will always return the first occurrence of that value, which might not be the correct index.

For example, consider the input nums = [3,3], target = 6. Your solution will return [0,0], but the correct output is [0,1].

Here is a corrected version of your code:

1
2
3
4
5
6
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        for i in range(len(nums)):
            for j in range(i+1, len(nums)):
                if nums[i] + nums[j] == target:
                    return [i, j]

In this corrected code, i and j are not the elements in nums, but the indices of these elements. It ensures we are not checking the same pair twice or adding a number to itself (unless the number is duplicated in the array). This solution has a time complexity of O(n^2) due to the use of two nested loops. There are more efficient solutions, like using a hash map, that can solve this problem with a time complexity of O(n).

for (int y = 0;y< nums.length;y++){ for(int x = 1; x< nums.length;x++){ if (x==y){continue;} else { int n = nums[x] + nums[y]; if (n == target) { if (y<x){System.out.println("["+y+","+x+"]");} else {System.out.println("["+x+","+y+"]");} } else {continue;}

        }

    }
}

It says there is an error in the penultimate line. I don’t know what it’s saying. help me

The code you’ve written is missing a return statement. In Java, if a function is declared to return a type (in this case int[]), then it must return that type.

However, you’re not returning anything from your function, but printing the values instead. What you need to do is create an int[] to store your result and return that.

Here is an adjusted version of your code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
public int[] twoSum(int[] nums, int target) {
    for (int y = 0; y < nums.length; y++) {
        for (int x = 1; x < nums.length; x++) {
            if (x == y) {
                continue;
            } else {
                int n = nums[x] + nums[y];
                if (n == target) {
                    if (y < x) {
                        return new int[] {y, x};
                    } else {
                        return new int[] {x, y};
                    }
                }
            }
        }
    }
    // Return an empty array or throw an exception if no solution is found
    return new int[] {};
}

Please note that this implementation has a time complexity of O(n^2) due to the use of two nested loops. There are more efficient ways to solve this problem, such as using a HashMap, which would bring down the time complexity to O(n).

can this be the answer

class Solution(object): def twoSum(self, nums, target): j = -1 for i in nums: j += 1 while j < len(nums): if nums[j] + i == target: return [j, nums.index(i)]

This solution seems almost correct, but there’s a small issue with the logic which would cause it to fail in certain cases. Specifically, when there are duplicate numbers in the input array that could be part of the solution.

Here is the problem: nums.index(i) always returns the index of the first occurrence of i in nums, which can be a problem if nums[j] and nums.index(i) are the same number. For example, consider the case nums = [3,3] and target = 6. Your function will return [0,0] because nums.index(i) returns the first occurrence of 3 but the correct answer is [0,1].

To fix this, consider iterating over the indices of nums instead of the numbers in nums themselves. Here’s a fixed version of your code:

1
2
3
4
5
6
class Solution(object):
    def twoSum(self, nums, target):
        for i in range(len(nums)):
            for j in range(i + 1, len(nums)):
                if nums[i] + nums[j] == target:
                    return [i, j]

In this version of the code, we’re explicitly handling indices, and we avoid the issue with nums.index() entirely.

This solution works but its time complexity is O(n^2) due to the use of nested loops. There are more efficient solutions that work in O(n) time by using a hashmap to remember what values we’ve seen and at what indices.

omething else that’s worth mentioning is that there exists a O(n log n) solution. this obviously is inferior to the average case O(n) performance of a one-pass hash table, but it’s worth mentioning. this is from the CLRS algorithms textbook, exercise 2.3-7.

basically, the procedure is to first perform a merge sort on the array, followed by a binary search of the complement of each element. the merge sort takes O(n lg n) time, and performing a binary search (log n time) on n elements takes O(n lg n) time. thus, the entire algorithm takes O(n lg n) time.

Yes, you are right. This approach of sorting the array first and then using a two-pointer technique or a binary search to find the two numbers that sum to the target also solves the problem. The time complexity is indeed O(n log n) due to the sorting step.

Here’s how the two-pointer technique would work: After sorting the array, initialize one pointer at the beginning of the array and another at the end. Then, in each iteration, calculate the sum of the numbers pointed to by the two pointers. If the sum is less than the target, move the start pointer forward (to increase the sum). If the sum is greater than the target, move the end pointer backward (to decrease the sum). If the sum is exactly the target, you’ve found your pair.

Here’s how you could implement this in Python:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        sorted_nums = sorted([(num, i) for i, num in enumerate(nums)])
        l = 0
        r = len(nums) - 1
        while l < r:
            if sorted_nums[l][0] + sorted_nums[r][0] == target:
                return [sorted_nums[l][1], sorted_nums[r][1]]
            elif sorted_nums[l][0] + sorted_nums[r][0] < target:
                l += 1
            else:
                r -= 1

Please note that this method may not be acceptable for the problem as posed on LeetCode, because the problem specifies that the original order of the input list must be preserved in the output. But in many real-world situations, this could be a valid solution.

Question about the hash approach:

in STL at least, we would use std::map as the hash map.

To find if a key exists in a map, we would need to use map::find( key ). The complexity of map::find() is O(log( map::size() )). We are doing this N times, so our total complexity seems to be O( N*log(N) ) instead of linear as you seem to suggest.

If true, this is the same as sorting the array first, and then walking it from both ends.

What am I missing?

You’re correct that the C++ std::map operations have a time complexity of O(log n). However, std::map is a tree-based container and its operations are log n because they involve tree traversals.

But when we refer to “hash” operations in the context of this problem, we’re generally referring to hash table or hash map operations, not map operations. C++ provides std::unordered_map which is a true hash table implementation. The complexity for search, insert, and delete operations in an ideal unordered_map are O(1) (constant time) on average. This is because hash tables use a hash function to directly map keys to buckets in an underlying array, so it doesn’t need to traverse a data structure like a tree or a linked list to find an item.

So, when using std::unordered_map for this problem in C++, the overall time complexity can be O(n), making the hash table approach more efficient than the sorting + two-pointer approach (O(n log n)) for larger inputs.

Here’s how you might write it in C++:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> num_map;
        for (int i = 0; i < nums.size(); i++) {
            int complement = target - nums[i];
            if (num_map.count(complement)) {
                return { num_map[complement], i };
            }
            num_map[nums[i]] = i;
        }
        return {};
    }
};

This way, the average time complexity is O(n).

Start from 23.