0

Can someone please tell me if the following solution is possible "IN ONE PASS"?

Given a list of numbers and a number k, return whether any two numbers from the list add up to k.

For example, given [10, 15, 3, 7] and k of 17, return True since 10 + 7 is 17.

Bonus: Can you do this in one pass?

def verify(list):
    for i in range(len(list)):
        j = k - list[i]
        if j in list:
            return True
    return False
dspencer
  • 4,297
  • 4
  • 22
  • 43
Oussama
  • 3
  • 2
  • 2
    No, this isn't in one pass, as `in` iterates over the list – Nick is tired May 17 '20 at 01:15
  • 1
    Does this answer your question? [Given a list of numbers and a number k, return whether any two numbers from the list add up to k](https://stackoverflow.com/questions/51300360/given-a-list-of-numbers-and-a-number-k-return-whether-any-two-numbers-from-the) – Hozayfa El Rifai May 17 '20 at 01:16
  • @HozayfaElRifai It's a rich thread but the answers are mainly in Java. Thanks – Oussama May 17 '20 at 02:33

3 Answers3

0

I came up with two solutions.

The first one, which am pretty sure is the one what you are being asked for, does all the possible sums -worst case scenario- with only one pass:

def verify_2(l,k):
    i = 0
    j = 0
    n = len(l)
    while i < n - 1:
        j = i + 1
        while j < n:
            if l[i] + l[j] == k:
                return True
            j = j + 1
        i = i + 1
    return False


print(verify_2(l = [10,15,3,7], k = 17)) #RETURNS TRUE
print(verify_2(l = [10,15,3,7], k = 6)) #RETURNS FALSE

The other one is less efficient (because it has to sort the vector firt, which already has n*log(n) complexity at the very least), and you have to manually do another pass. This is NOT what you are being asked for, but since it is easier to understand I leave it to you as well:

def verify(l,k):
    l.sort()
    for i in range(len(l) - 1):
        if l[i] + l[i+1] == k:
            return True
    return False

print(verify(l = [10,15,3,7], k = 17)) #RETURNS TRUE
print(verify(l = [10,15,3,7], k = 6)) #RETURNS FALSE

P.S.1 First solution is WAY faster than the second one.

P.S.2 Regarding your solution I have to tell you several things. Avoid using the word "list" for variables or parameters, since it is a word of the Python language that is reserved for converting another datatype to the datatype "list" (i.e. if you have s = "hello" and you do s = list(s) then you get that s has['h','e','l','l','o'] inside). Also bare in mind that all the code BELOW the function header (below def...) NEEDS to be indented, either with four spaces, two spaces or one tab (or you get an interpretation error). You also should note that in your solution k is used, but it is not a defined variable; you should pass it as a parameter or define it inside the function, or you cannot work with it (former is advised, not latter). Even accounting for that, your function did not do what was asked in the text: It actually subtracts the i-th element from k at each step of the for loop, and checks at each iteration whether the result of the subtraction belongs to the list.

blackcub3s
  • 189
  • 1
  • 4
  • I really like you're answer.. it's so smart and elegant.. also thank you for the tips.. Can you have a look at my second proposition? – Oussama May 17 '20 at 02:02
  • Actually, isn't this a solution if the two terms are adjacent.. like if k = 13 I'm not sure it will return true. @americansanti – Oussama May 17 '20 at 02:44
  • Hey! It was a proper solution, because the method 'l.sort()' just sorted the list in ascending order. So you only have to worry about adjacent numbers :). Btw, I added a better solution: if you sort it first is not efficient. Check out the new solution. If you have any doubts contact me. – blackcub3s May 17 '20 at 13:12
0

I'm sorry guys, I find it difficult to find an answer to the thread you're suggesting, and the solutions are mostly in Java.. Can you have a look at this other proposition: Fisrt we create a copy of our list..

def verify(l, K):
   for i in range(len(l)):
       j = k - l[i]
       if j in l:
           return True
       l = l.pop([i])
   return False

Thank you!

Oussama
  • 3
  • 2
  • I haven't put it into the editor, but I see several mistakes. Note that `l.pop([i])` does not work. You should do `l.pop(i)`. Then, also note that pop method returns an element of the list. You are destroying the list by assigning `l = l.pop(i)` Finally, also note that the `range(len(l))` gets called only at the start of the for loop. When you are inside you use the pop method, and this method, at each call, makes the list one slot shorter. So then you obviously get `IndexError: pop index out of range`. If you want to maintain your solution maybe try with a while loop instead. – blackcub3s May 17 '20 at 13:35
0

Use itertools combinations to get all possible pairs of numbers in your list.

from itertools import combinations
li =[10, 15, 3, 7]
k =17

answer = k in (map(sum,combinations(li,2)))

print(answer)
LevB
  • 925
  • 6
  • 10