I think you can improve this by separating part of the algebra from the search and using more intelligent data structures.
Go through the list and subtract from the additional diff for each element in the list.
resultlist[index] = complementary_diff - originallist[index]
You can use either a map or a simple loop. β Accepts O (n) time.
See if the number in the resulting list exists in the source list.
Here, with a naive list, you really get O (n ^ 2), because in the end you can find the whole source list for each item.
However, there are more reasonable ways to organize your data than this. If you have an original list sorted , your search time boils down to O (nlogn + nlogn) = O (nlogn), nlogn for sorting, and nlogn for binary search for each item.
If you want to be smarter, you can make your list in a dictionary (or hash table) , and then this step becomes O (n + n) = O (n), n to create a dictionary and 1 * n to search for each element in dictionary. (* EDIT: * Since you cannot consider the uniqueness of each value in the original list. You may need to calculate how many times each value appears in the original list.)
So now you get O (n) total execution time.
Using your example:
1, [1, 3, -4, 0, -3, 5],
Create a list of results:
>>> resultlist [0, -2, 5, 1, 4, -4].
Now we are looking for:
Smooth the source list in the dictionary. I decided to use the index of the source list as a value, as this seems like the side data that interests you.
>>> original_table {(1,0), (3,1), (-4,2), (0,3), (-3,4), (5,5)}
For each item in the list of results, search the hash table and create a tuple:
(resultlist_index, original_table[resultlist[resultlist_index]])
This should look like an example of the solution you had.
Now you just find the length of the resulting list of tuples.
Now here is the code:
example_diff = 1 example_values = [1, 3, -4, 0, -3, 5] example2_diff = 1 example2_values = [1, 0, 1] def complementary_pairs_number(complementary_diff, values): """ Given an integer complement and a list of values count how many pairs of complementary pairs there are in the list. """ print "Input:", complementary_diff, values # Step 1. Result list resultlist = [complementary_diff - value for value in values] print "Result List:", resultlist # Step 2. Flatten into dictionary original_table = {} for original_index in xrange(len(values)): if values[original_index] in original_table: original_table[values[original_index]].append(original_index) else: original_table[values[original_index]] = [original_index] print "Flattened dictionary:", original_table # Step 2.5 Search through dictionary and count up the resulting pairs. pair_count = 0 for resultlist_index in xrange(len(resultlist)): if resultlist[resultlist_index] in original_table: pair_count += len(original_table[resultlist[resultlist_index]]) print "Complementary Pair Count:", pair_count # (Optional) Step 2.5 Search through dictionary and create complementary pairs. Adds O(n^2) complexity. pairs = [] for resultlist_index in xrange(len(resultlist)): if resultlist[resultlist_index] in original_table: pairs += [(resultlist_index, original_index) for original_index in original_table[resultlist[resultlist_index]]] print "Complementary Pair Indices:", pairs # Step 3 return pair_count if __name__ == "__main__": complementary_pairs_number(example_diff, example_values) complementary_pairs_number(example2_diff, example2_values)
Conclusion:
$ python complementary.py Input: 1 [1, 3, -4, 0, -3, 5] Result List: [0, -2, 5, 1, 4, -4] Flattened dictionary: {0: 3, 1: 0, 3: 1, 5: 5, -4: 2, -3: 4} Complementary Pair Indices: [(0, 3), (2, 5), (3, 0), (5, 2)] Input: 1 [1, 0, 1] Result List: [0, 1, 0] Flattened dictionary: {0: [1], 1: [0, 2]} Complementary Pair Count: 4 Complementary Pair Indices: [(0, 1), (1, 0), (1, 2), (2, 1)]
Thanks!