0

I have a coding exercise with a row of trampolines, each with a minimum and maximum "bounciness". I have the index of a starting trampoline and an end trampoline, and with this, I need to find the minimum amount of jumps required to reach the end trampoline from the start trampoline.

I have tried creating an adjacency-list, in which I list all possible jumps from a trampoline. This is fine until I reach a large number of trampolines. The Problem is it takes O(n^2) time. This is how I create the Adjacency List:

def createAL (a, b, l):
al = [list() for _ in range(l)]
for i in range(l):
    
    for j in range(a[i], b[i]+1):
        if (i+j) <= l-1:
            al[i].append(i+j)
        if (i-j) >= 0:
            al[i].append(i-j)


for i in range(len(al)):
    al[i] = list(set(al[i]))

return al

"a" is the min. bounciness, "b" the max bounciness and "l" is the length of the two lists.

As you can see, the problem is I have 2 nested loops. Does anyone have an idea for a more efficient way of doing this? (preferably wo/ the loops)

jesseb0rn
  • 823
  • 3
  • 14
  • Can you please explain the question in a more clear and precise fashion? You have an array of trampolines. Each has a minimum and maximum value of . How does this affect the question? also, what constrain do the indices create? – shapiro yaacov Oct 21 '20 at 19:13

1 Answers1

0

Assuming "bounciness" is strictly positive, you can omit this part:

for i in range(len(al)):
    al[i] = list(set(al[i]))

...as there is no way you could have duplicates in those lists.

(If however bounciness could be 0 or negative, then first replace any values below 1 by 1 in a)

The building of a can be made a bit faster by:

  • making the ranges on the actual target indexes (so you don't need i+j in every loop),
  • cliping those ranges using min() and max(), avoiding if statements in the loop
  • avoiding individual append calls, using list comprehension

Result:

al = [
    [*range(max(0, i-b[i]), i-a[i]+1), *range(i+a[i], min(l, i+b[i]+1))]
        for i in range(l)
]

Finally, as this adjacency list presumably serves a BFS algorithm, you could also consider that building the adjacency list may not be necessary, as finding the adjacent nodes during BFS is a piece of cake using a and b on-the-spot. I wonder if you really gain time by creating the adjacency list.

In your BFS code, you probably have something like this (where i is the "current" node):

for neighbor in al[i]:

This could be replaced with:

for neighbor in (*range(max(0, i-b[i]), i-a[i]+1), *range(i+a[i], min(l, i+b[i]+1))):

We should also realise that if the target trampoline is found in a number of steps that is much smaller than the number of trampolines, then there is a probability that not all trampolines are visited during the BFS search. And in that case it would have been a waste of time to have created the complete adjacency list...

trincot
  • 317,000
  • 35
  • 244
  • 286