Home > Net >  How can I avoid Runtime Error with find Two Sum?
How can I avoid Runtime Error with find Two Sum?

Time:04-23

I have this issue

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

Input: nums = [2,7,11,15], target = 9

Output: [0,1]

and I write this code to solve this issue

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        prev_map = {}
        for index, value in enumerate(nums):
            prev_value = value - target
            if prev_value or abs(prev_value) in prev_map:
                return [prev_map[prev_value], index]
            prev_map[value] =  index

but I get a Runtime Error can anyone explain why this happened ?

CodePudding user response:

This line is the problem:

if prev_value or abs(prev_value) in prev_map:

The or keyword splits the condition into two completely separate halves. As written, this says "Is prev_value nonzero, or is the absolute value of prev_value in prev_map?"

Instead, you want to write it this way:

if prev_value in prev_map or abs(prev_value) in prev_map:

CodePudding user response:

You are checking if prev_value is True or abs(prev_value) in prev_map is True.

if (prev_value is True) or (abs(prev_value) in prev_map)

If prev_value is True, but prev_value is not in prev_map

if prev_value or abs(prev_value) in prev_map:
    return [prev_map[prev_value], index] # prev_map[prev_value] => You are trying to get the value of missing key, you will certainly get a Runtime Error

CodePudding user response:

Your runtime error may be from any of these things:

  • Type hints need to be lower case: List should be list
  • You need to create a class instance
x = Solution()
  • Then call it's method
x.twoSum(nums=[2, 7, 11, 15], target=9)
  • Or Exception has occurred: KeyError

This KeyError is from accessing something from prev_map that is not there:

Use:

class Solution:
    # Your type hints need to be lower case: List => list
    def twoSum(self, nums: list[int], target: int) -> list[int]:
        prev_map = {}
        for index, value in enumerate(nums):
            prev_value = value - target
            
            if prev_value in prev_map:
                return [prev_map[prev_value], index]
            elif abs(prev_value) in prev_map:
                return [prev_map[abs(prev_value)], index]
            
            prev_map[value] = index

Your code was failing because you were checking if prev_value. That's just seeing if the variable was truthy. Rather than if prev_value in prev_map. If this statement was True, you would still access prev_map[prev_value] anyway. But what if prev_value was not in prev_map, but abs(prev_value) was (as you checked it in the conditional)?

You need to access the dictionary with the right value, if that value is in there:

if prev_value in prev_map:
    return [prev_map[prev_value], index]

elif abs(prev_value) in prev_map:
    return [prev_map[abs(prev_value)], index]

CodePudding user response:

By your question explanation your code can be simpler and smaller. So this way it works fine and also it's cleaner for your use. I noticed that other answers explained the error in your code so I tried to suggest a better code to fix your problem easier.

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        for i, num in enumerate(nums):
            try:
                return [i, nums.index(target-num)]
            except ValueError:
                continue
        
        return -1

I used try except in this code as in Python, "Easier to ask for forgiveness than permission" (EAFP) is a rule in "Zen of Python". But you can replace it with if to check if it exists or not. I suggest that you use the try except version as it is also faster.

At last if there is no two values meeting target goal this method will return -1. If you don't want to do that you can omit that line.

If you have any questions ask me.

  • Related