Проблема: →
Учитывая заголовки двух односвязных списков headA
и headB
, вернуть узел, в котором два списка пересекаются. Если два связанных списка вообще не пересекаются, вернуть null
.
Например, следующие два связанных списка начинают пересекаться в узле c1
:
Тестовые примеры генерируются таким образом, что нигде во всей связанной структуре нет циклов.
Обратите внимание, что связанные списки должны сохранять свою первоначальную структуру после возврата из функции.
Пользовательский судья:
Входные данные для судьи задаются следующим образом (ваша программа не получает эти входные данные):
intersectVal
- Значение узла, в котором происходит пересечение. Это0
, если нет пересеченного узла.listA
- Первый связанный список.listB
- Второй связанный список.skipA
— Количество узлов, которые нужно пропустить вперед вlistA
(начиная с головы), чтобы добраться до пересекаемого узла.skipB
— количество узлов, которые необходимо пропустить вlistB
(начиная с головы), чтобы добраться до пересекаемого узла.
Затем судья создаст связанную структуру на основе этих входных данных и передаст две головки, headA
и headB
, в вашу программу. Если вы правильно вернете пересеченный узел, ваше решение будет принято.
Пример 1:
Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3 Output: Intersected at '8' Explanation: The intersected node's value is 8 (note that this must not be 0 if the two lists intersect). From the head of A, it reads as [4,1,8,4,5]. From the head of B, it reads as [5,6,1,8,4,5]. There are 2 nodes before the intersected node in A; There are 3 nodes before the intersected node in B. - Note that the intersected node's value is not 1 because the nodes with value 1 in A and B (2nd node in A and 3rd node in B) are different node references. In other words, they point to two different locations in memory, while the nodes with value 8 in A and B (3rd node in A and 4th node in B) point to the same location in memory.
Пример 2:
Input: intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 Output: Intersected at '2' Explanation: The intersected node's value is 2 (note that this must not be 0 if the two lists intersect). From the head of A, it reads as [1,9,1,2,4]. From the head of B, it reads as [3,2,4]. There are 3 nodes before the intersected node in A; There are 1 node before the intersected node in B.
Пример 3:
Input: intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 Output: No intersection Explanation: From the head of A, it reads as [2,6,4]. From the head of B, it reads as [1,5]. Since the two lists do not intersect, intersectVal must be 0, while skipA and skipB can be arbitrary values. Explanation: The two lists do not intersect, so return null.
Ограничения:
- Количество узлов
listA
находится вm
. - Количество узлов
listB
находится вn
. 1 <= m, n <= 3 * 104
1 <= Node.val <= 105
0 <= skipA < m
0 <= skipB < n
intersectVal
равно0
, еслиlistA
иlistB
не пересекаются.intersectVal == listA[skipA] == listB[skipB]
, еслиlistA
иlistB
пересекаются.
Дополнение. Не могли бы вы написать решение, которое выполняется за O(m + n)
времени и использует только O(1)
памяти?
Решение: →
Давайте посмотрим на решение с изображением ниже, мы можем понять, как это решение мы можем получить,
Давайте разберемся с кодом,
В коде они дали два связанных списка head1 и head2, нам нужно сначала проверить, является ли кто-либо из них или оба пустыми, если да, то мы просто вернем NULL .
Теперь, следующий шаг, инициализируйте два указателя node1 и node2 в head1 и head2.
Теперь нам нужно обойти оба связанных списка, чтобы получить пересечение, мы возьмем цикл while и остановим его, когда оба nodeA и nodeB станут такой же.
Считайте узел 1 узлом А и узел 2 узлом Б.
Первая итерация,
Вторая итерация,
Третья итерация,
Здесь следующий из nodeB равен нулю, поэтому мы указываем nodeB как headA,
Примечание: → Здесь мы можем указать nodeB с помощью headB, но в этом случае итерация будет больше, поэтому для получения быстрого результата мы указываем nodeB с headA и nodeAс headB.
Четвертая итерация,
Пятая итерация,
Шестая итерация,
Здесь условие станет false.
В конце мы можем вернуть любой узел, так как оба узла содержат одинаковое значение,
Наконец, nodeA — наш ответ.
Теперь давайте посмотрим полный исходный код,
Код (Java): →
Код (Питон): →
Сложность времени
Здесь мы просматриваем двусвязный список, поэтому общая временная сложность будет O(m+n).
Космическая сложность
Здесь мы использовали только две переменные, поэтому общая пространственная сложность также будет O(1).
Спасибо, что прочитали эту статью ❤
Если эта статья поможет вам, пожалуйста, похлопайте 👏 этой статье.
Пожалуйста, следите за мной на medium, я буду публиковать полезную информацию, как указано выше.
Инстаграм → https://www.instagram.com/alexmurphyas8/
Твиттер → https://twitter.com/AlexMurphyas8
Если я что-то не так? Позвольте мне в комментариях. Я хотел бы улучшить.