Давайте разберем, что в сущности делает предложенный вами алгоритм.
Для каждого индекса i (st 0 ≤ i ≤ n) вы сравниваете i со всеми уникальными индексами j (i ≠ j), чтобы определить: i * j == k
.
Инвариант для этого алгоритма будет означать, что на каждой итерации сравниваемая пара {i, j} не сравнивалась ранее.
Эта реализация (при условии, что она компилируется и запускается без исключений времени выполнения, упомянутых в комментариях), выполняет в общей сложности сравнения nC2 (где nC2 - биномиальный коэффициент для n и 2 для выбора всехвозможные уникальные пары), и каждое такое сравнение будет вычисляться в постоянное время (O (1)).Обратите внимание, можно доказать , что nCk не больше, чем n ^ k.
Таким образом, O (nC2) обеспечивает более точную верхнюю границу для этого алгоритма - хотя с помощью обычной большой записи O этовсе равно будет O (n ^ 2), так как nC2 = n * (n-1) / 2 = (n ^ 2-n) / 2, который по-прежнему порядка n ^ 2.
ВВаш вопрос из комментариев:
Правильно ли использовать «i» в сложности, так как я использовал O (n- (i + 1))?
i - текущий индекс, тогда как на сложность вашего алгоритма влияет только размер вашей выборки, n.
IOW, общая сложность рассчитывается для всех итераций в алгоритмев то время как я ссылаюсь на конкретную итерацию.Поэтому некорректно использовать «i» в ваших расчетах сложности.
Кроме моего полуалгоритма, есть ли более эффективный алгоритм?
Ваш«Полуалгоритм» кажется мне наиболее эффективным способом решения этой проблемы.Любой алгоритм, основанный на сравнении, потребует запроса всех пар в массиве, что соответствует сложности, описанной выше.Хотя я не рассчитал нижнюю границу и мне было бы интересно услышать, если кто-нибудь знает о более эффективной реализации.
edit: Другой ответ здесь показывает хорошее решение этой проблемы, которое(вообще говоря) более эффективный, чем этот.