を繰り返し、毎回L1すべてを繰り返すL2と、二次時間がかかります。これを改善する唯一の方法は、すべてのL2. (最後に重複を削除する同様の問題がありLます。)
setfor L2(および for )を使用する場合L、もちろん各in L2ステップは一定時間であるため、アルゴリズム全体は線形です。また、を使用する代わりに、独自のハッシュ テーブル実装をいつでも構築できますset。しかし、それは大変な作業です。
二分探索木、または並べ替えられたリストとbinary_find関数だけでも、O(N log N) で実行できます。そして、それbinary_findは自分で書く方がはるかに簡単です。そう:
S2 = sorted(L2)
L = [element for element in L1 if binary_find(element, S2)]
S = remove_adjacent(sorted(L))
または、さらに簡単に、L1 も並べ替えると、必要ありませんremove_adjacent。
S1, S2 = sorted(L1), sorted(L2)
L = []
for element in S1:
if binary_find(element, S2) and (not L or L[-1] != element):
L.append(element)
いずれにせよ、これは O(N log N) です。ここで、N は長いリストの長さです。比較すると、元は O(N^2) で、他の答えは O(N^3) です。もちろん、もう少し複雑ですが、理解するのは非常に簡単です。
追加のビルトインを使用したくない場合でも、標準ライブラリからのものを使用したくないと想定しているため、 binary_find(および、該当する場合は)を記述する必要があります。remove_adjacentしかし、それは本当に簡単です。例えば:
def binary_find(element, seq):
low, high = 0, len(seq),
while low != high:
mid = (low + high) // 2
if seq[mid] == element:
return True
elif seq[mid] < element:
low = mid+1
else:
high = mid
return False
def remove_adjacent(seq):
ret = []
last = object()
for element in seq:
if element != last:
ret.append(element)
last = element
return ret
sortedorを使いたくない場合でもlist.sort、独自のソートを非常に簡単に作成できます。