Answer the question
In order to leave comments, you need to log in
The largest non-increasing subsequence. How to optimize an algorithm in Python?
Taking a course on algorithms at stepic.org
Stuck on the problem of finding the largest non-increasing subsequence in n log n time (see picture)
My solution passes all tests except the last one, 20th, giving the error Failed test #20 of 20. Time limit exceeded - it is clear that I do not pass by time, but I have been trying to understand why for a week now. And, as luck would have it, no one in the comments faced exactly such a problem, so I ask for help here.
I apologize in advance if the question is stupid, I'm still just learning and, unfortunately, I don't have any familiar programmers who I can turn to with questions (
A description of the algorithm for finding the largest increasing subsequence in time n log n using binary search is here:https://en.wikipedia.org/wiki/Longest_increasing_s...
I optimized this algorithm so that it builds not a strictly increasing subsequence, but a non-decreasing one and used it for an "inverted" input array, it works correctly on all tests .. maybe speed is lost somewhere else: for example, when displaying a result or creating lists.
Here is my code:
n = int(input())
x = list(map(int, input().split()))
x.reverse()
p = [0]*n
m = [0]*(n+1)
l = 0
for i in range(n):
left = 1
right = l
while left <= right:
mid = (left+right) // 2
if x[m[mid]] < x[i]:
left = mid+1
elif x[m[mid]] == x[i]:
left += 1
else:
right = mid-1
new_l = left
p[i] = m[new_l-1]
if new_l > l:
m[new_l] = i
l = new_l
elif x[i] < x[m[new_l]]:
m[new_l] = i
print(l)
k = m[l]
for i in range(l-1,-1,-1):
print (n-k, end = ' ')
k = p[k]
Answer the question
In order to leave comments, you need to log in
To begin with, I recommend resending the solution, timeouts can happen simply due to a surge in load on the testing server.
If that doesn't help, then you really should optimize print, because Python has very expensive function calls, on my computer, these are the measurements I got:
l = list(range(10**5))
for i in l: # 107 ms
print(i, end=' ')
s = ' '.join(map(str, l))
print(s) # 55 ms
for i in range(n):
left = 1
right = l
...
elif x[m[mid]] == x[i]:
left += 1
...
for i in range(n):
left = 1
right = l
while left <= right:
mid = (left+right) // 2
if x[m[mid]] <= x[i]:
left = mid+1
else:
right = mid-1
...
Madam, if this is really your code, then believe me, you have no problems and everything is in order. Many "programmers" will not even be able to understand what is written here. According to the subject, I’m too lazy to poke around in the task so deeply, but if the solution doesn’t work, then it’s not a fact that this is your problem, maybe the guys in the environment have too little timeout for executing tests. Speed is most often lost on nested loops, you have one for with a nested while, while is a dangerous thing that can lead to infinite loops. Check your code so that it can't jump to infinite execution under certain conditions.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question