DEV Community

Cover image for 🚀 Unleashing Efficiency with Hashmaps: Solving the Two Sum Problem 🚀
Marc Peejay V. Viernes
Marc Peejay V. Viernes

Posted on

🚀 Unleashing Efficiency with Hashmaps: Solving the Two Sum Problem 🚀

Welcome back to my data structures and algorithms grind! Today, I'm diving deep into the classic Two Sum problem, a fundamental challenge that sets the stage for mastering more complex algorithms. Let's embark on this journey of efficiency and problem-solving mastery!

🎯 Problem Description:

The Two Sum problem tasks us with finding two numbers in an array nums that add up to a given target. Our goal is to return the indices of these two numbers.

Example:

Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: nums[0] + nums[1] == 9, so we return [0, 1].
Enter fullscreen mode Exit fullscreen mode

⚙️ Constraints:

  • Length of nums: 2 to 10^4
  • Elements of nums: -10^9 to 10^9
  • Target value: Within the same range
  • Exactly one valid solution exists

💡 Solution Approach:

I'm employing a hashmap to efficiently solve this problem. Here's my strategy:

def twoSum(nums: List[int], target: int) -> List[int]:
    prevMap = {}  # val -> index

    for i, n in enumerate(nums):
        diff = target - n
        if diff in prevMap:
            return [prevMap[diff], i]

        prevMap[n] = i
Enter fullscreen mode Exit fullscreen mode

💬 Code Discussion:

  • Method Definition: I define a method named twoSum which takes in nums, a list of integers; target, the target sum; and returns the indices of the two numbers that add up to the target.

  • Hashmap Initialization: Initializing an empty dictionary named prevMap. In Python, dictionaries (hashmaps) offer constant time complexity for insertion, deletion, and lookup on average.

  • Iterating through nums: Looping through nums using the enumerate function to access both index i and value n.

  • Calculating the Difference: For each n in the array, I calculate the difference diff between the target and n.

  • Checking Complement Existence: I check if diff exists in prevMap. If it does, it means I've found the complement of n that adds up to the target. So, I return the indices of n and its complement from prevMap.

  • Storing in Hashmap: If the complement doesn't exist, I store n along with its index i in prevMap.

⏰ Time Complexity Analysis and Relevance of Hashmap:

Utilizing a hashmap is crucial for achieving an efficient solution. Here's why:

  • Constant Time Lookup: Dictionaries in Python offer constant time complexity (O(1)) for insertion, deletion, and lookup on average. This enables us to check if a complement exists for a given number in constant time.

By leveraging the constant time complexity of dictionary lookups, we achieve a linear time complexity of O(n) for solving the Two Sum problem, making our solution highly efficient, especially for large input sizes.

🔍 Discussion on Space Complexity and Trade-offs:

The space complexity of our solution is O(n), where n represents the number of elements in the input array nums. In the worst-case scenario, we may need to store most of the n elements in the hashmap prevMap. This accounts for situations where we encounter all elements in nums except one while iterating through the array to find the unique pair that sums up to the target. Therefore, even though we technically store n - 1 elements (due to the guaranteed unique pair), according to the principles of complexity analysis, we simplify this to O(n) by considering the dominant factor.

The trade-off between time and space complexity is common in algorithm design. In this case, we prioritize time efficiency by using additional space to store the hashmap. However, for applications with strict memory constraints or when optimizing for space is critical, alternative approaches may be explored.

Understanding these trade-offs and choosing the most suitable solution based on the problem requirements is crucial in algorithm design.

💼 Possible Applications of Hashmaps:

Hashmaps find diverse applications across various domains:

  • Database Indexing: Efficient indexing and retrieval of data in databases.
  • Caching: Storing frequently accessed data for quick retrieval.
  • Symbol Tables: Facilitating quick lookup of identifiers in programming languages.
  • Network Routing: Storing routing information for efficient packet forwarding.

Understanding hashmaps and their applications equips us with powerful tools for efficiently solving real-world problems.

That's all for today's dev blog. Keep sharpening your skills in data structures and algorithms, and stay tuned for more insights in our next adventure!

For more details and practice, check out the Two Sum problem on LeetCode.

Top comments (0)