"Но в худшем случае это O (N M). Есть ли лучший эффективный алгоритм?" Вероятно, не из-за размерности данных, составляющих O (N M). Многие операции с матрицами, подобные этой, имеют порядок M N, поскольку в худшем случае есть M N элементов, которые необходимо будет проверить в случае совпадения матриц.
Глядя на средний случай, более интересно, если разностный блок обязательно представляет собой один прямоугольник во всей матрице, то я подозреваю, что вам может сойтись сканирование со средним числом всех элементов.
Вот быстрый, хотя у меня было:
отслеживать текущий элемент, назовите это XY
Начните с верхнего левого угла, поэтому XY теперь является верхним углом
Убедитесь, что элементы XY в обоих равны, если не равны, переходите к 3, иначе переходите к 4
Если элементов нет, то у вас есть элемент матрицы разностей. Запишите этот элемент, затем найдите в этой строке и столбце другие элементы (возможно, что-то вроде двоичного поиска будет самым быстрым). После поиска строки / столбца у вас есть координаты ребер. Если элементы не равны, переходите к 4.
Следующий шаг переместите XY по диагонали на один элемент вниз и один элемент вправо, затем снова перейдите к 2
после того, как диагональ пройдена, вам нужно будет проверить ее по следующей диагонали (я подозреваю, что лучше выбрать новую диагональ, которая находится дальше всего от текущей диагонали, хотя у меня нет никаких доказательств того, что это лучший выбор) пока все элементы не будут охвачены. В худшем случае это все еще O (N * M), но в среднем это может быть быстрее.
По сути, вы пытаетесь использовать один другой элемент как можно быстрее, поэтому цель состоит в том, чтобы выбрать первый элемент таким образом, чтобы минимизировать ожидаемое значение числа поисков для поиска первого другого элемента.