Без сохранения какой-либо внешней информации, нет, вы не можете сделать лучше, чем Θ (N 2 ).Обоснование простое - если вы не смотрите на все N 2 местоположений в матрице, то вы не можете гарантировать, что вы нашли все нули и могли в конечном итоге дать неправильный ответ,Например, если я знаю, что вы просматриваете меньше N 2 местоположений, то я могу запустить ваш алгоритм на матрице и посмотреть, сколько нулей вы сообщаете.Затем я мог бы посмотреть на места, к которым у вас не было доступа, заменить их все нулями и снова запустить ваш алгоритм.Поскольку ваш алгоритм не смотрит на эти местоположения, он не может знать, что в них есть нули, и поэтому по крайней мере один из двух прогонов алгоритма вернет неправильный ответ.
В более общем смыслеПри разработке алгоритмов для обработки данных хорошим способом проверить, сможете ли вы добиться большего успеха, чем некоторые среды выполнения, является использование такого рода «состязательного анализа».Задайте себе вопрос: если я бегу быстрее, чем некоторое время O (f (n)), может ли злоумышленник манипулировать данными таким образом, чтобы изменить ответ, но я не смог бы обнаружить?Это тот анализ, который, наряду с более умной математикой, доказывает, что алгоритмы сортировки, основанные на сравнении, не могут работать лучше, чем Ω (n log n) в среднем случае.
Если матрица имеет какую-то другуюсвойства к нему (например, если он отсортирован), то вы могли бы сделать лучше, чем работать в O (N 2 ).В качестве примера предположим, что вы знаете, что все строки матрицы отсортированы.Затем вы можете легко выполнить двоичный поиск по каждой строке, чтобы определить, сколько нулей в ней содержится, что занимает O (N log N) времени и быстрее.
В зависимости от параметров вашей настройки, вы можетечтобы алгоритм работал быстрее, если вы предполагаете, что вам разрешено сканировать параллельно.Например, если на вашей машине установлено K процессоров, которые могут быть выделены для задачи сканирования матрицы, то вы можете разбить матрицу на K групп примерно одинакового размера, чтобы каждый процессор подсчитал количество нулей в группе, а затемПодвести итоги этих расчетов.В результате вы получаете время выполнения Θ (N 2 / K), поскольку время выполнения разделено на несколько ядер.