This is an optimised version that empirically can be faster a little, yet it has the same time complexity in theory.
I have tried to tweak QuickSort Algorithm to serve this purpose, but it did not work fully.
Nevertheless, you can do better than O(N^2) in a little, and that's my best proposal for now (others are very welcome to comment or propose a better working approach).
Still availing of QuickSort, which costs O(N log(N)), the comparison can be faster and cost O((N(N+1))/2). In total that will be: O(N log(N)) + O((N(N+1)/2).
Empirical Analysis
x = np.arange(1, 1000000)
y1 = np.add(np.multiply(x, np.log10(x)), np.divide(np.multiply(x, np.add(x, 1)), 2))
y2 = np.square(x)
plt.plot(x, y1, label='N log(N) + (N(N+1) / 2)')
plt.plot(x, y2, label='N^2')
plt.xlabel("Number of Elements")
plt.ylabel("Complexity")
plt.legend(loc='best')
plt.show()
![enter image description here]()
For a few hundreds of elements, there is no big difference, but as the number of elements increases, the difference in performance increases.
def naive(arr):
keys = arr
max_key, element = -1, np.NAN
for k in keys:
count = 0
for divisor in keys:
if divisor != 0 and k % divisor == 0:
count += 1
if count > max_key:
max_key = count
element = k
return element
def better_little(arr):
keys = np.sort(arr)[::-1]
l = len(keys)
max_key, element = -1, np.NAN
for i in range(l):
count = 0
for j in range(i+1, l):
if keys[j] != 0 and keys[i] % keys[j] == 0:
count += 1
if count > max_key:
max_key = count
element = keys[i]
return element
# TEST
np.random.seed(2021)
all_times = 0.0
rounds = 100
for _ in range(rounds):
arr = np.random.randint(0, 1000, size=1000)
start_ = time.time()
naive(arr)
all_times += time.time() - start_
print("Naive :: Average Time {}".format(all_times/rounds))
np.random.seed(2021)
all_times = 0.0
for _ in range(rounds):
arr = np.random.randint(0, 1000, size=1000)
start_ = time.time()
better_little(arr)
all_times += time.time() - start_
print("Better A little :: Average Time {}".format(all_times / rounds))
Results
Naive :: Average Time 0.40
Better A little :: Average Time 0.30