Рубрики
Без рубрики

Решение: пересечение двух связанных списков

Это является частью серии объяснений решений LeetCode (индекс). Если вам понравилось это решение или fou … с меткой алгоритмы, JavaScript, Java, Python.

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”