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

Получить в неудачниках, мы делаем связанный список Logic

Хорошо, поднимите руку, если вы когда-либо были лично жертвами этими смешными запутанными … Теги от реверсингалинкпида, Python, начинающих, псевдокод.

Хорошо, поднимите руку, если вы когда-либо были лично жертвами этими смешными спутними небольшими структурами данных.

Хорошо, может быть, это немного драматично Но это уверенно чувствовал как Я преследовал первые несколько (или 30) раз, когда я должен был придумать решение в течение невозможного количества времени. Добавим к тому, что давление наблюдается и оценивается за неспособность следовать своей логике. Если вы похожи на меня, вы, возможно, немного плакали … пару раз.

Тем не менее, по словам моего любимого философа, Рона Сунсона, «Держите свои слезы в глазах, где они принадлежат».

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

В этом я охвачу, что такое связанный список, почему это так сбивает с толку, и как к умело, но умно устраивает узлы и их указатели, чтобы решить один из самых распространенных проблем связанных списков, которые я видел до сих пор: отменить связанный список.

Давайте начнем с взгляда на следующее определение класса связанного списка:

# Definition for singly-linked list.

class ListNode:    
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

Итак, это «ListNode» или список узлов?

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

Название «связанный список» сама сбивает с толку, потому что это не На самом деле, список вообще. По крайней мере, не похоже на список в Python или массивом в JavaScript, который оба включают в себя индексы и поэтому заказываются.

Связанный список – это способ хранения значений и связать их вместе, как цепочка. Он может быть определен как класс с головкой и свойством хвоста, который соответствует исходным и конечным узлам, но это не всегда так.

Технически, только один узел – это связанный список, даже если он указан на Никто ценность.

Например, используя класс сверху, давайте создадим связанный список:

linked_list = ListNode(1)

print(linked_list) 
# this is what it would look like printed to the terminal: 
#  

# to access the data
linked_list.val   # 1
linked_list.next  # None

Вытянуты, наша ссылка_Лист выглядит так: # 1 -> Нет

Серьезно, что это? Список муравьев? Это должно быть хотя бы … в три раза больше этого?!

Хаха, нет, это все, что нужно. Вы можете сохранить создание узлов, а затем подключить их:

node2 = ListNode(2)
linked_list.next = node2
# or simply: 
node2.next = ListNode(3)

Теперь, если мы вытягиваем его, наша наша ссылка_List выглядит так: # 1 -> 2 -> 3 -> Никто

Но linked_list все еще просто один узел с val (1) и а Далее (Node2) Отказ

Многие путаницы происходят от того, что нет списка, поэтому получить значение всех узлов не так просто, как написание хорошего OL ‘ для петли Отказ В большинстве случаев все, что вы получаете, это просто ссылка на исходный узел. Пока у вас есть стартовый узел, вы все еще можете перемещаться по всему узлам по пересекающий Отказ

Пересекающий связанный список

Для петлей? Где мы идем, нам не нужно для петлей! Учитывая начальный узел, чтобы добраться до следующего узла, узел после следующего, и все остальные узлы, которые вам нужно сделать, это Traverse.

# start with the given node
curr = node     

    # while loop that keeps going as long as current never becomes NONE
    while curr is not None:

        # do something with this node's value or pointer
        # this will be where we do the logic to reverse
        print(curr.value)       

        curr = curr.next # set the curr pointer to next node

Этот драгоценный камень в то время как цикл – это то, что вы часто будете использовать во многих проблемах, поэтому тренируйтесь и знаете, что это как спина вашей руки!

Реверсив связанный список

Если вы Google алгоритм для этого вы можете увидеть что-то вроде этого:

Initialize three pointers prev as NULL, curr as head and next as NULL.
Iterate through the linked list. In loop, do following. 
// Before changing next of current, 
// store next node 
next = curr->next
// Now change next of current 
// This is where actual reversing happens 
curr->next = prev 
// Move prev and curr one step forward 
prev = curr 
curr = next

Не делайте ошибку, которую я думал, что вы можете решить это несколько раз и помнить позже. Вы можете оказаться в интервью, говоря: «Во-первых, я сделал некоторые указатели. Затем я просто устанавливаю этот указатель на этот указатель следующего и предыдущего тока следующего, или это было предыдущему следующему. Стреляй я не могу вспомнить … ».

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

Тогда, даже если вы не можете вспомнить, как точно отменить, вы можете просто понять его, переместив указатели вокруг. Практикуйте «Выяснение этого», не глядя на псевдокод столько раз, сколько сможете. Для меня “выясняет его” означает визуализацию его.

Как визуализировать решение и включить его в код

1.) Выясните свою отправную точку I.E, если у вас есть 1> 2 -> Нет, начальные значения будут предыдущий, и

2.) Вытяните его, все. В том числе:

  • Узлы со своими следующими указателями (я нарисовал их как круги с черными стрелками)

  • Все нет ценностей

  • Prev, Cur, Curry и следующие указатели (я Color-Coded Chays)

  • Prev, Cur, Curry и следующие значения в начале каждого цикла

  • Хотя условие в начале каждого цикла

3.) Выясните, какие стрелки должны указывать на то, чтобы показать список, чтобы перевернуть. Вы должны перемещать только стрелки, а не узлы. Прежде чем двигаться вокруг стрел, убедитесь, что вы можете написать этот шаг в качестве кода. Например, в этом случае мы знаем, что все цветные указатели, где они должны быть, кроме Следующий один. Если мы хотим красной стрелкой указывать на 2, логика для этого будет. Так как мы не имеем дело со списками, мы не можем просто сказать Далее + 1 или Далее [1] или что-нибудь подобное. Мы можем только «перемещаться» или добраться до узлов, используя у нас указатели.

4.) Перед переходом на новую контур обновите значения (те, внизу на рисунке 2) для Prev, Cur, и следующих значений, где бы указывать соответствующую стрелку.

5.) В начале нового цикла пройдите через код, который вы написали для первого цикла, убедившись, что логика все еще применяется и достигает желаемого эффекта.

Проверьте мое видео о том, как я это делаю.

Действительно следуйте за каждым шагом, а затем попробуйте вытянуть его без какой-либо помощи. Это помогает иметь доску или карандаш, потому что вам нужно будет стереть и перерисовывать стрелки. Это практикуется, терпение и итерации. Прежде чем я записал это видео, я ударил свои шаги и начал не менее 3 или 4 раза. Иногда ваша логика работает в первом петле, но затем, когда вы продолжаете идти, вы понимаете, что псевдокод не будет работать дальше вниз по линии. Это нормально, просто возьми свое время и займет 5 минут, если вы чувствуете, что вы никуда получаете.

Вы заметите в конце там, начальный узел нашего обратного списка теперь доступен по Ранее Переменная указателя. Это значение, которое мы хотим вернуться.

Давайте пойдем вперед и код!

Код:

class Solution:
    def reverseList(self, head):
        prev = None 
        curr = head
        nxt = None
        while curr is not None:
            nxt = curr.next

            # // This is where actual reversing happens 
            curr.next = prev

            prev = curr
            curr = nxt

        return prev

Существует один край, который может сломать наш код, и это если мы передаем значение None, либо, другими словами, пустой список, как параметр. Давайте исправить это с условным.

class Solution:
    def reverseList(self, head):
        if head is None:
            return head

        prev = None 
        curr = head
        nxt = None

        while curr is not None:
            nxt = curr.next

            # This is where actual reversing happens 
            curr.next = prev

            # then we update values to traverse
            prev = curr
            curr = nxt

        return prev

Вынос

  • Значитые ссылки Проблемы – это обычные проблемы собеседования, они могут сначала очень запутать, поэтому практика работает со связанными списками столько, сколько сможешь.

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

  • При изменении списка имеется имерным образом, вам нужно 3 указателя: Prev, Curry и Next.

  • Если вы не смотрели средних девушек, вы пропускаете на знаком фильме, и вы должны посмотреть его! Только после освоения связанного списка разворот, то есть.

Я надеюсь, что вы нашли эту статью полезную и наслаждались моими рекомендациями поп-культуры! Я почти все умные способы вписаться в кино цитаты Но я оставлю вас с вековой старой классикой, которая имеет абсолютно ничего общего с связанными списками или средними девочками. Это даже не пойдет сюда, поэтому он не может сидеть с нами! Хорошо, действительно, это был (второй -) последний.

Жизнь движется довольно быстро. Если вы не остановитесь и не смотрите в то время, вы могли бы пропустить это. День Ферриса Буллера Выключенный

Оригинал: “https://dev.to/rarrrleslie/get-in-loser-we-re-doing-linked-list-logic-dki”