LeetCode Solutions (161 серия деталей)
Это является частью серии объяснений решения LeetCode ( index ). Если вам понравилось это решение или нашли его полезным, Пожалуйста, нравится Этот пост и/или upvote Мое решение по сообщению на форумах LeetCode Анкет
Проблема LeetCode #160 (легко): пересечение двух связанных списков
Описание:
( прыгнуть в : Идея решения Код : JavaScript | Python | Java | C++
Напишите программу, чтобы найти узел, на котором начинается пересечение двух однозначных списков.
Например, следующие два связанных списка:
Начните пересекаться в узле C1.
Примеры:
Вход: | |
Выход: | Ссылка на узел с |
Объяснение: | Значение пересеченного узла составляет 8 (обратите внимание, что это не должно быть 0, если эти два списка пересекаются). От главы А, он читается как [4,1,8,4,5]. Из главы B он читается как [5,6,1,8,4,5]. Есть 2 узла перед пересеченным узлом в A; Есть 3 узла перед пересеченным узлом в B. |
Визуальный: |
Вход: | |
Выход: | Ссылка на узел с |
Объяснение: | Значение пересеченного узла составляет 2 (обратите внимание, что это не должно быть 0, если эти два списка пересекаются). От главы А, он читается как [1,9,1,2,4]. Из головы B он читается как [3,2,4]. Есть 3 узла перед пересеченным узлом в A; Есть 1 узел перед пересеченным узлом в B. |
Визуальный: |
Вход: | |
Выход: | нулевой |
Объяснение: | От головы А, он читается как [2,6,4]. Из головы B он читается как [1,5]. Поскольку два списка не пересекаются, интерсекталь должен быть 0, в то время как Skipa и Skipb могут быть произвольными значениями. Два списка не пересекаются, поэтому верните NULL. |
Визуальный: |
Ограничения:
- Если два связанных списка вообще не имеют пересечения, верните
нулевой
. - Связанные списки должны сохранить свою исходную структуру после возврата функции.
- Вы можете предположить, что нигде нет циклов во всей связанной структуре.
- Каждое значение в каждом связанном списке находится в диапазоне
[1, 10^9]
. - Ваш код должен желательно работать в
O (n)
Время и использование толькоO (1)
Память.
Идея:
( прыгнуть к : Описание проблемы Код : JavaScript | Python | Java | C++
Наивный подход здесь заключается в том, чтобы хранить каждую ссылку на узел в структуре данных, пока мы не увидим одну и ту же дважды, но это потребует O (n) дополнительное пространство Анкет
Чтобы решить эту проблему только с O (1) дополнительное пространство Нам нужно найти другой способ выравнивания двух связанных списков. Что еще более важно, нам нужно найти способ выстроить заканчивается из двух списков. И самый простой способ сделать это – объединить их в противоположных приказах, A+b и B+a . Таким образом, концы двух оригинальных списков будут соответствовать второй половине каждого объединенного списка.
Затем нам просто нужно проверить, указывают ли в какой -то момент два объединенных списка на один и тот же узел. На самом деле, даже если два объединенных списка не пересекаются, значение A и b Будет то же самое ( null ), когда мы дойдем до конца объединенных списков, поэтому мы можем использовать это в качестве условия нашего выхода.
Нам просто нужно убедиться, что нажимать голова на A и наоборот, если один (но не оба) список заканчивается.
Реализация:
Там код для всех четырех языков почти идентичен.
Код JavaScript:
( прыгнуть к : Проблема Описание Идея решения
var getIntersectionNode = function(headA, headB) { let a = headA, b = headB while (a !== b) { a = !a ? headB : a.next b = !b ? headA : b.next } return a };
Код Python:
( прыгнуть к : Проблема Описание Идея решения
class Solution: def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: a, b = headA, headB while (a != b): a = headB if not a else a.next b = headA if not b else b.next return a
Код Java:
( прыгнуть к : Проблема Описание Идея решения
public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { ListNode a = headA, b = headB; while (a != b) { a = a == null ? headB : a.next; b = b == null ? headA : b.next; } return a; } }
C ++ Код:
( прыгнуть к : Проблема Описание Идея решения
class Solution { public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { ListNode *a = headA, *b = headB; while (a != b) { a = !a ? headB : a->next; b = !b ? headA : b->next; } return a; } };
LeetCode Solutions (161 серия деталей)
Оригинал: “https://dev.to/seanpgallivan/solution-intersection-of-two-linked-lists-478e”