I solved the next exercises having two solutions: https://www.hackerrank.com/challenges/reverse-a-doubly-linked-list
First (non-recursive):
/*
Insert Node at the end of a linked list
head pointer input could be NULL as well for empty list
Node is defined as
class Node {
int data;
Node next;
Node prev;
}
*/
Node Reverse(Node head) {
if (head == null) return null;
Node current = head;
while (current.next != null) {
Node temp = current.next;
current.next = current.prev;
current.prev = temp;
current = temp;
}
current.next = current.prev;
current.prev = null;
return current;
}
Second algorithm (recursive):
/*
Insert Node at the end of a linked list
head pointer input could be NULL as well for empty list
Node is defined as
class Node {
int data;
Node next;
Node prev;
}
*/
Node Reverse(Node head) {
if (head.next == null) {
head.next = head.prev;
head.prev = null;
return head;
}
Node newHead = Reverse(head.next);
Node temp = head.next;
head.next = head.prev;
head.prev = temp;
return newHead;
}
According to the book, the solution must be O(n). I guess using recursive solution is more elegant but maybe I'm wrong. Can you help to determine the space and time complexity of these two algoritms, or in your, which is better in performance?
The question is a bit unclear, both solutions seem to be O(n) in both time and space. Although you could probably remove the special cases and make Torvalds happy. Something like:
Node Reverse(Node head) {
if (head == null) return null;
Node current = head;
while (current != null) {
Node temp = current.next;
current.next = current.prev;
current.prev = temp;
current = temp;
}
return current;
}
Node Reverse(Node head) {
Node temp = head.next;
head.next = head.prev;
head.prev = temp;
return temp==null?head:Reverse(temp);
}
I have not tested these, use them as inspiration only. (Also the recursive will nullpointer if head is null in the beginning).