を繰り返し、毎回L1
すべてを繰り返すL2
と、二次時間がかかります。これを改善する唯一の方法は、すべてのL2
. (最後に重複を削除する同様の問題がありL
ます。)
set
for 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
sorted
orを使いたくない場合でもlist.sort
、独自のソートを非常に簡単に作成できます。