CodeLAB
на главную карта сайта обратная связь

Популярные задачи:

#Создание простейшей таблицы. (37133 hits)
#Как посчитать одинаковые пары за 1 проход (самая быстрая версия!). (2149 hits)
#Овал, вписанный в прямоугольник. (37863 hits)
#Рисование линии. (38804 hits)
#Плоттеры для рисования графиков. (29687 hits)
#Доступ ко всем полям и методам. (58030 hits)
#Древовидные структуры. (57430 hits)
#Код. (179772 hits)
#Преобразование сумм из цифрового представления в строковое. (175697 hits)
#Загрузчик классов. (43453 hits)
#Хранение иерархических деревьев. (53329 hits)
#Подключение. (27405 hits)
#Таймер. (40785 hits)
#"C# и платформа .NET" Эндрю Троелсен (Andrew Troelsen, "C# and the .NET platform"), листинги, код, примеры из книги, исходники. (38881 hits)
#Вычисление медианы заданной выборки. (49214 hits)
#Добавление истории операций(undo&redo) в компонент. (39986 hits)
#Сортировка вставкой. (112204 hits)
#Вычисление среднего, среднего отклонения, среднеквадратического отклонения и дисперсии заданной выборки. (46439 hits)
#Создание нестандартного (custom-ного) окна браузера. (35925 hits)
#Рисование 3D объекта. (35144 hits)


Главная >> Каталог задач >> Последовательности >> Найти общие элементы в списках

Найти общие элементы в списках

Aвтор:
Дата:
Просмотров: 656
реализации +добавить

На входе значит у нас 2 связных списка, первый размером пусть будет N и втором - M соответственно. Нужно найти общие в них элементы, т.е. которые содержатся и в первом и втором.
Довольно простая задача, для которой на ум сразу приходит решение перебором, для поиска же оптимального - придется немного подумать.

Следует подчеркнуть что поскольку мы имеем дело со Связными списками (а не массивами), то можем только последовательно друг за другом читать оттуда элементы, а не по индексу как обычно с массивами. Т.е. у нас для входных данных доступна по сути только одна операция типа next (взять следующий элемент) , которая возвращает следующий элемент этого списка или например null (пустое значение) если мы достигли конца списка. И всё, как говорится, крутись как хочешь )

Перебором

Ну как бы все просто: делаем внешний цикл по всем элементам первого списка, на каждом шаге берем очередной элемент и для него запускаем внутренний цикл но уже по второму списку , где уже сравниваем элементы второго цикла с текущим элементов первого и если равны - значит совпадает.

Что с производительностью такого решения? Ну очевидно что т.к. у нас 2 вложенных цикла, первый размером N и второй -  M то это получается квадратичная скорость, т.е. O(N*M) в худшем случае что конечно медленно.

Псевдокод перебором

Получаем примерно такой:

 псевдокод: найти общие элементы в списках перебором  ссылка
  1. list1 = <input1>
  2. list2 = <input2>
  3. result = new list
  4.  
  5. for each element from list1 do:
  6. current = element
  7. for each element2 from list2 do:
  8. if current == element2 then:
  9. result.add(current)
  10. // далее просто останавливаем цикл по list2
  11. break;
  12.  
  13. return result

Обратите внимание что после нахождения одинакового элемента мы останавливаем внутренний цикл (строка 11) и переходим сразу следующему элементу внешнего цикла (list1), т.к. если доказали что этот элемент уже содержится в обоих списках то нет смысла дальше до конца смотреть сколько раз от встречается во втором списке.

Быстрее?

Что ж, с медленным вариантом разобрались, довольно просто, а можем ли как-то быстрее?
Ну без изменения начальных условий или структуры исходных данных - очевидно что нет. 

А давайте поразмыслим немного как именно мы ищем в нашем медленном варианте перебором: мы проходимся по всем элементам первого списка и на каждом шаге ищем этот элемент во втором списке. При этом ищем его самым тривиальным и простым способом - последовательным поиском который занимает линейное время ( ~O(N) - где N это размер всего списка) и проходит по каждому элементу второго списка. 
А какие еще варианты? Вмысле какие еще методы поиска у нас есть?

Да, именно, ну конечно - бинарный поиск , скорость которого уже логарифмичная т.к. O(ln N), а это считай на порядок быстрее чем линейный. 
Круто давайте его и применим для поиска элемента во втором списке.

Реализации:

нет на данный момент   +добавить