Pierwszy performance - Za dużo razy liczysz len(A). Wystarczy raz i ją przechować, to przyspieszy dla ogromnie dużych list.
Drugi performance - gdy wykona się pierwszy if, a zagnieżdżony wewnątrz niego if się nie zgadza, algorytm dalej sprawdza kolejne if'y które się wykluczają. Do tego gdy masz warunki sprzeczne ze sobą, (nie mogą zajść dwa jednocześnie, wykorzystujesz elif. To jednocześnie pozwala ci redukować ilość sprawdzeń np. do takiego:
if i==0:
if A[i]!=A[i+1]:
return A[i]
elif i==len(A)-1: #Tu już program wie że nie jest równy zero, inaczej by go zignorował
if A[i]!=A[i-1]:
return A[i]
else: #Tu już program wie że nie jest maksymalnym i nie jest zerowym, więc jest środkowym indeksem.
if A[i]!=A[i-1] and A[i]!=A[i+1]:
return A[i]
Trzeci performance - Gdy jest to możliwe, i znasz możliwe inputy, unikaj stosowania '==' w algorytmicznych problemach. Bo jest najzwyczajniej wolniejsze od < lub >.
Czwarty performance - Nie sprawdzaj warunku w pętli za każdym razem, gdy występuje tylko raz.
Co nie zmienia faktu że szybciej powinno przejść coś tego typu:
def solutionM(L):
s_L = set(L)
L.sort()
for i in :
if L.count(i)<2:
return i
Dla małych testów było od 10% do 700% szybsze wyciągając medianę. (zawahania intelowskie ;p, ale i tak nie okazał się nigdy wolniejszy).
Jeśli nie będzie jednak szybszy dla dużych, spróbuj usprawnionej wersji swojego programu:
def solution(A):
#Range omija ostatni element by uniknąć index error, więc od razu go odejmijmy
LA = len(A)-1
#Jeśli będzie tylko jeden element, len(A) da nam 1. Czyli 1-1 równe 0.
#A negacja od False czyli 0, to True, od każdej innej liczby negacja to 1 czyli True. Ponadto już mamy ostatni indeks na ostatni return :).
if not LA:
return A[0]
A.sort() #Dzięki temu wiemy że elementy będą ustawione rosnąco, unikajmy porównań "Jest różne" gdy wiemy że kolejny musi być mniejszy
if A[0]<A[1]: #Sprawdźmy to raz, zamiast w każdym przebiegu pętli.
return A[0]
for i in range(1, LA):
if A[i-1]<A[i] and A[i]<A[i+1]: #Skoro są rosnąco, unikalny element będzie ten który jest większy od poprzedniego i mniejszy od następnego.
return A[i]
return A[LA] #Idąc logiką ten ostatni będzie jedynym jeśli wcześniej return nie wystąpił.
Ten poprawiony przeze mnie już jest podobny w swej szybkości do pierwszego rozwiązania które podałem.
Niestety nie doszukałem się tego konkretnego błędu który by powodował nie zdanie testu, jeśli gdzieś był, patrząc na argumenty logiczne, powinien już być wyeliminowany w powyższych :).