patternMinor
Find if two elements in an array sum up to a given number
Viewed 0 times
findnumberelementsarraytwosumgiven
Problem
I'm currently solving some problems over at kattis, in particular the Add 'Em Up task.
A quick summarizing:
You are given an array with $1 \leq n \leq 100000 $ elements and an integer $2 \leq s \leq 200 000000$. You want if there exists two elements $x_i,x_j, i \neq j, $ in the array such that $x_i + x_j = s$. However, there's a twist that you can flip certain numbers to obtain a new number. For example, if $ x_i = 51 $ then a flip would yield $ \bar{x}_i = 15.$ Still, you can just use an element once, so $ x_i + \bar{x}_i = s $ is not an accepted answer.
Looking at the worst case scenario, our new array would contain $2n$ elements, $ \{x_1, ..., x_n, \bar{x}_1, ..., \bar{x}_n \}. $
I've written an algorithm that works, but it's not efficient enough. I believe it's $ \in O(n^2) $.
If $ N = \{x_1, ..., x_n, \bar{x}_1, ..., \bar{x}_n \} $, and if $x_i $ doesn't have a flip, then $ \bar{x}_i = $ 'NF'. (NoFlip, str).
How can I make the code more efficient?
I've tried:
A quick summarizing:
You are given an array with $1 \leq n \leq 100000 $ elements and an integer $2 \leq s \leq 200 000000$. You want if there exists two elements $x_i,x_j, i \neq j, $ in the array such that $x_i + x_j = s$. However, there's a twist that you can flip certain numbers to obtain a new number. For example, if $ x_i = 51 $ then a flip would yield $ \bar{x}_i = 15.$ Still, you can just use an element once, so $ x_i + \bar{x}_i = s $ is not an accepted answer.
Looking at the worst case scenario, our new array would contain $2n$ elements, $ \{x_1, ..., x_n, \bar{x}_1, ..., \bar{x}_n \}. $
I've written an algorithm that works, but it's not efficient enough. I believe it's $ \in O(n^2) $.
If $ N = \{x_1, ..., x_n, \bar{x}_1, ..., \bar{x}_n \} $, and if $x_i $ doesn't have a flip, then $ \bar{x}_i = $ 'NF'. (NoFlip, str).
for i in range(2*n) do
for j in range(2*n) do
if (j-i) % n != 0 and N[i], N[j] != 'NF':
if N[i] + N[j] == S:
return True
return FalseHow can I make the code more efficient?
I've tried:
- Removed all elements $ \geq S $ first
Solution
There is an $O(n)$ solution, using a nice trick:
Keep track of the different values you have already seen in an auxiliary hashmap, called $seen$.
Now, loop over the elemnts of the array (the original array, you don't have to add the negations), and for each $x_i$ do the following:
You will see that if for any $i$ we get that $s-x_i\in seen$ before we added $x_i$ at the $i$'th iteration, then there must be some $j< i$ such that $x_i+x_j=s$ or $x_i+\overline{x_j}=s$. And for a similar reason, if $s-\overline{x_i}\in seen$ before we added it in the $i$'th iteration, then there must be some $j with $\overline{x_i}+x_j=s$ or $\overline{x_i}+\overline{x_j}=s$.
Thechnically speaking, the solution works in $O(n^2)$ in the worst case, but since we deal with a hash map, we can say that on average (or at least, its very likely) that it will run in $O(n)$.
Keep track of the different values you have already seen in an auxiliary hashmap, called $seen$.
Now, loop over the elemnts of the array (the original array, you don't have to add the negations), and for each $x_i$ do the following:
- If either $s-x_i\in seen$ or $s-\overline{x_i}\in seen$, then return $True$.
- Else, add both $x_i,\overline{x_i}$ to $seen$, and continue to the next element in the list.
You will see that if for any $i$ we get that $s-x_i\in seen$ before we added $x_i$ at the $i$'th iteration, then there must be some $j< i$ such that $x_i+x_j=s$ or $x_i+\overline{x_j}=s$. And for a similar reason, if $s-\overline{x_i}\in seen$ before we added it in the $i$'th iteration, then there must be some $j with $\overline{x_i}+x_j=s$ or $\overline{x_i}+\overline{x_j}=s$.
Thechnically speaking, the solution works in $O(n^2)$ in the worst case, but since we deal with a hash map, we can say that on average (or at least, its very likely) that it will run in $O(n)$.
Context
StackExchange Computer Science Q#143128, answer score: 3
Revisions (0)
No revisions yet.