LeetCode: Soluție și explicație pentru inversarea unei liste înlănțuite

  • 2 minute de citit
  • 1 exemplu de cod

Disponibil și în English

Pe această pagină

Salut,

În acest articol explic soluția mea pentru următoarea problemă LeetCode: Reverse Linked List.

Dacă ești interesat să rezolvi această problemă, încearcă să petreci cel puțin o oră sau mai mult pe ea înainte de a-mi vedea soluția.

Ca să te ajut să rezolvi problema, am creat următorul tabel:

Current Prev
1 NULL
2 1
3 2
NULL 3

Gândește-te cum poți folosi acest tabel ca să scrii un algoritm iterativ sau recursiv care inversează lista înlănțuită.


Soluția

Mai jos găsești soluțiile mele iterativă și recursivă, cu explicații. Soluțiile sunt scrise în C#.

Soluția recursivă

Dacă te uiți la tabelul pe care l-am făcut, poți observa că, pentru a inversa lista, tot ce trebuie să faci este să faci nodul curent să indice spre nodul anterior în fiecare apel recursiv, apoi să treci la nodul următor.

Condiția de oprire apare când nodul curent este null. Atunci trebuie să returnezi nodul anterior, care indică spre nodul anterior, care indică spre cel dinaintea lui și așa mai departe. Ai obținut o listă înlănțuită inversată.

Complexitatea este O(n) pentru timp, pentru că trebuie să parcurgem întreaga listă, și O(n) pentru spațiu, pentru că la fiecare apel programul alocă un nou cadru de stivă.

Soluția iterativă

Soluția iterativă este asemănătoare cu cea recursivă, doar că nu alocă spațiu suplimentar; pur și simplu parcurge lista, modificând-o direct.

Actualizează nodul curent la cel anterior și, la final, returnează ultimul nod.

Complexitatea este O(n) pentru timp și O(1) pentru spațiu.


using System;namespace LeetCode.November{    public class ReverseLinkedListProb    {        public class ListNode        {            public int val;            public ListNode next;            public ListNode(int val = 0, ListNode next = null)            {                this.val = val;                this.next = next;            }        }                // Spațiu O(1) ; Timp O(n)        public ListNode ReverseListIterative(ListNode head)        {            ListNode prev = null;            while (head != null)            {                // salvează next                var next = head.next;                // next -> prev                head.next = prev;                // prev -> head                prev = head;                // head -> next                head = next;            }            return prev;        }        // Spațiu O(n) ; Timp O(n)        public ListNode ReverseListRecursion(ListNode head, ListNode prev)        {            if (head == null)            {                return prev;            }            var next = head.next;            head.next = prev;            return ReverseListRecursion(next, head);        }        public ListNode ReverseList(ListNode head)        {            var last = ReverseListIterative(head);            return last;        }        public static void Test()        {            var problem = new ReverseLinkedListProb();            var r = problem.ReverseList(new ListNode(1, new ListNode(2, new ListNode(3))));            while (r != null)            {                Console.Write($"{r.val} ");                r = r.next;            }        }    }}

Mulțumesc că ai citit!