TLE when solving "Removing duplicates from unsorted linked list" using maps in c++ - algorithm

I am trying to solve the removing duplicates from unsorted linked list problem on GFG using maps. I have figured out the accepted solution using insert and find commands:
Node * removeDuplicates( Node *head)
{
// your code goes here
map <int, int> duplicates;
Node* curr=head;
Node* prev=NULL;
while(curr){
if(duplicates.find(curr->data)==duplicates.end()){
duplicates.insert({curr->data,1});
prev=curr;
}
else{
prev->next=curr->next;
delete(curr);
}
curr=prev->next;
}
return head;
}
But another approach I tried earlier is giving TLE for submission, even though it works fine for example test case. I have tried to implement the same idea as above but in a slightly different way. Can anyone help me out with this?
Node * removeDuplicates( Node *head)
{
map <int, int> duplicates;
Node* temp=head;
while(temp){
duplicates[temp->data]=1;
temp=temp->next;
}
Node* curr=head;
Node* prev=NULL;
while(curr){
if(duplicates[curr->data]==1){
duplicates[curr->data]=0;
prev=curr;
}
else{
prev->next=curr->next;
delete(curr);
}
curr=prev->next;
}
return head;
}

There are multiple problems with the 2nd solution.
your running through a linked list twice, don't do this if possible.
unordered_map might be much faster as already mentioned in the commented
your looking more in the duplicates in the 2nd solution, 3 vs. 2.
Either of the above could further cause cache congestion slowing things down further.

Take the bool data type far value instead of int so you don't have to initialize the value of a map.
Instead of taking an ordered map use the unordered map which is relatively faster.
Here is the optimized code.
Node *removeDuplicates(Node *head)
{
Node *curr = head;
Node *prev = NULL;
if (curr == NULL)
return NULL;
unordered_map visited;
while (curr != NULL)
{
if (visited[curr->data])
{
Node *temp = curr;
curr = curr->next;
delete (temp);
prev->next = curr;
}
else
{
visited[curr->data] = true;
prev = curr;
curr = curr->next;
}
}
return head;
}

Related

Problem with Stack based Euler-Tree-traversal

I want a function that traverses a binary tree with the Euler traversal (this is how it works). Of course this is easily achievable with recursion - I know how that works. But now I want to implement an iterative version of this algorithm using a stack instead of recursion. My idea was to store the direction we are traversing on the stack as well. My code is not working and I can somehow not wrap my mind around this problem. Can you give me any hints on how to tackle this issue? Here is my code so far:
#define LEFT (struct Node*) 0xBADF00D
#define RIGHT (struct Node*) 0xDEADBEEF
struct Node {
int data;
struct Node* parent;
struct Node* left;
struct Node* right;
};
void eulerTree(struct Node* root)
{
stack<struct Node*> s;
s.push(root);
s.push(RIGHT);
s.push(root);
s.push(LEFT);
while(!s.empty()) {
struct Node* direction = s.top(); s.pop();
struct Node* node = s.top(); s.pop();
visit(node);
if(direction == LEFT) {
if(node->left) {
s.push(node->left);
s.push(RIGHT);
s.push(node->left);
s.push(LEFT);
}
}
if(direction == RIGHT) {
if(node->right) {
s.push(node->right);
s.push(RIGHT);
s.push(node->right);
s.push(LEFT);
}
}
}
}
Think of a simple binary tree to start with :
1
2 3
Euler traversal for this is : 1 2 1 3 1
You see the pattern here:
root, root->left, root, root->right, root
So your stack order should be:
root
root->left
root
root->right
root
But what if your root is a leaf? then don't push anything just print the value.
Also once you push the nodes on left, right make sure you set them as 0 for the root so that you don't keep pushing them forever.
With that said, the code in cpp would be:
Edit:
The previous code I posted has a bug. The correct code is below:
void eulerTree(struct Node* root)
{
stack<struct Node*> s;
s.push(root);
while(!s.empty()) {
struct Node* node = s.pop();
visit(node);
if(node->right) {
s.push(node);
s.push(node->right);
}
if(node->left) {
s.push(node);
s.push(node->left);
}
node->left = 0;
node->right = 0;
}
}
Without destroying the tree:
But yes, even though the code is simple this destroys the tree which is not desired. To tackle this problem I am going to use two properties for leaves of the tree in a euler tree traversal.
If the leaf is left child of the parent and the right child of that parent is null
( or )
if the leaf is right child
-after this leaf is printed then print the parent nodes all the way up the root.
If the leaf is left child and the right child is not null
-after this leaf is printed then print only its immediate parent.
To illustrate look at the below tree.
1
2 3
4 5 6 7
If the leaf is 5 then after it is printed, then print all the parents upto 1.
If the leaf is 4 then after it is printed, then print just its immediate parent 2.
To simplify implementation I am going to use a parent stack in addition to the current stack.
void eulerTree(struct Node* root) {
stack<struct Node*> s;
s.push(root);
struct Node* original = root;
stack<struct Node*> p;
while(!s.empty()) {
struct Node* node = s.top();
s.pop();
visit(node);
if ( !node->right && !node->left && !p.empty() ) {
struct Node* pNode = p.top();
if ( pNode->left == node && !pNode->right || pNode->right == node ) {
while ( !p.empty() ) {
visit(p.top());
p.pop();
}
p.push(original);
} else {
visit(pNode);
}
}
if(node->left || node->right) {
p.push(node);
}
if(node->right) {
s.push(node->right);
}
if(node->left) {
s.push(node->left);
}
}
}
A recursive implementation might look like this:
void euler(Node *n) {
visit(n);
if (n->left) {
euler(n->left);
visit(n);
}
if (n->right) {
euler(n->right);
visit(n);
}
}
Now whenever this makes a recursive call, the call stack is used to remember where we are in the code and what we're doing. Then we start again at the top and when we're done, that information is popped of the stack and we continue where we left off.
If you're going to do it iteratively with your own stack, you have to do the same job yourself. You have to remember enough to continue where you left off.
We have to remember which node we were working on of course, but also there are two recursive calls so, so there are 2 possible places we might have to return to. When we return from a recursive call, then either:
We have just done the n->left call and should continue on to check n->right; OR
We have just done the n->right call and should continue with the final visit of n
We could store some extra information on the stack to distinguish these two cases, but that is not necessary for this particular algorithm. From the descriptions above, you can see that we can distinguish these cases based on the node we're returning from -- it's either n->left or n->right.
So, just storing the waiting node in the stack, we can write an iterative version like this:
int state=0; // 0 => initial visit, 1 => just did left, 2 => just did right
Node *n = root;
while (n) {
visit(n);
if (n->left && state<1) {
stack.push(n);
n=n->left;
state=0;
continue;
}
if (n->right && state<2) {
stack.push(n);
n=n->right;
state=0;
continue;
}
if (stack.empty())
break; // done
Node *child=n;
n = stack.pop();
state = (child == n->left ? 1 : 2);
}

Odd Even Linked List Run Time Error for one particular input. Runs fine for everything else

I am trying to solve a problem from LeetCode.
Problem
Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes.
You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity.
Example:
Given 1->2->3->4->5->NULL,
return 1->3->5->2->4->NULL.
My Solution:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* oddEvenList(ListNode* head) {
ListNode *even, *firsteven, *odd, *curr;
if(head == NULL)
return NULL;
odd = head;
even = head;
curr = head;
if(head->next) {
even = even->next;
firsteven = head->next;
}
else return head;
if(head->next->next)
curr = head->next->next;
else return head;
while(curr) {
even->next = curr->next;
curr->next = NULL;
odd->next = curr;
curr->next = firsteven;
odd = odd->next;
even = even->next;
even->next ? curr = even->next : curr = NULL;
}
return head;
}
};
My solution works perfectly well for all inputs except for inputs of size 3.
For an input 1->2->3 I am getting a run time error. I have done a dry run several times. I am not sure why I am getting a run time error.
Can you please tell me what am I doing wrong?
The problem is with this line:
even->next = curr->next;
When current is set to the last element (3), you're trying curr->next, which will result in an error.

Singly linked list Tail

if you want create a singly linked list like this:
struct Node {
int data;
Node *next;
};
struct List{
Node *head;
// Node *tail; --> necessary?
Node *last;
};
And this list has the methods "append", "remove", "printList" and "findElement".
Is it necessary to have a tail? Because with "last" you can address the last node.
So when it is necessary to have all three Nodes "head", "tail" and "last"? When you want to insert the node sorted into the list for example?
No, it's not necessary. The tail is equal to head->next and thus it would be redundant and add bookkeeping overhead to keep this field updated.
Also note that the field last is kind of unusual. In most use cases, you add elements to the head of a singly linked list and use a different data structure when you really need to add to the end.
Actually, you can implement enqueue (append at tail), push (prepend at head), dequeue (remove from head), and of course find and print with with a one-pointer header. The trick is to make the list circular and have the header point to the tail. Then tail->next is the head.
#include <stdio.h>
#include <stdlib.h>
typedef struct node_s {
struct node_s *next;
int data;
} Node;
typedef struct list_s {
Node *tail;
} List;
Node *new_node(int data) {
Node *node = malloc(sizeof *node);
node->data = data;
node->next = node;
return node;
}
void init_list(List *list) {
list->tail = NULL;
}
int is_empty(List *list) {
return list->tail == NULL;
}
void enqueue(List *list, Node *node) {
if (list->tail) {
Node *head = list->tail->next;
node->next = head;
list->tail->next = node;
list->tail = node;
} else list->tail = node->next = node;
}
void push(List *list, Node *node) {
if (list->tail) {
Node *head = list->tail->next;
node->next = head;
list->tail->next = node;
} else list->tail = node->next = node;
}
Node *dequeue(List *list) {
Node *head = list->tail->next;
if (head == list->tail)
list->tail = NULL;
else
list->tail->next = head->next;
return head;
}
void print_list(List *list) {
printf("The list:\n");
if (list->tail) {
Node *head = list->tail->next;
Node *p = head;
do {
printf("%d\n", p->data);
p = p->next;
} while (p != head);
}
}
int main(int argc, char *argv[]) {
List list[1];
init_list(list);
// Build the list in order and print it.
for (int i = 0; i < 4; i++) enqueue(list, new_node(i));
print_list(list);
// Remove elements from head until empty.
printf("Dequeueing:\n");
while (!is_empty(list)) {
Node *node = dequeue(list);
printf("%d\n", node->data);
free(node);
}
// Build the list in reverse order and print it.
for (int i = 0; i < 4; i++) push(list, new_node(i));
print_list(list);
return 0;
}
I think it depends on what operations you want to use.
Assuming you want to insert and delete nodes at the tail of a list, it is certainly a wise choice to keep a last node in your list.
Otherwise, if you want to do operations at the beginning of the list, a last node is unnecessary.
It's not necessary but a tail can be useful if you're working with the linked list in a queue-like FIFO fashion rather than a stack-like LIFO fashion or want to be able to transfer entire lists of elements from one head to another's tail without disrupting the relative order of the elements.
Note that I'm referring to 'tail' as a reference to the last node in the list which I believe is safe to assume that the question is about.
A lot of very micro-optimized SLL implementations often are tail-less and work like a stack while backed by an efficient fixed allocator for locality of reference (cache-friendliness) and faster node allocations/deallocations. There the primary benefit of the SLL over a variable-sized array-based sequence is the ability to start moving things around by just changing the value of the next pointer/reference and the lack of invalidation on inserting/removing elements if you're working in native, lower-level languages that involve pointers. The lack of a tail can boost performance quite a bit by reducing the amount of branching instructions required in operations to push and pop from the stack.
For the needs you listed, whether the tail is going to help or just add unnecessary complexity and overhead is if your append and remove operations can work strictly from the front in a LIFO stack fashion or if you want to be able to append to the back but remove from the front in a FIFO fashion without any iteration involved, e.g. If you don't have a tail in the latter case, one of these operations are going to go from constant-time complexity to linear-time complexity, and you might improve your use cases by exchanging that linear-time algorithmic complexity for the relatively smaller micro-level overhead of maintaining a tail.

Implementing the Dutch National Flag Program with Linked Lists

I wanted to sort a linked list containing 0s, 1s or 2s. Now, this is clearly a variant of the Dutch National Flag Problem.
http://en.wikipedia.org/wiki/Dutch_national_flag_problem
The algorithm for the same as given in the link is:
"Have the top group grow down from the top of the array, the bottom group grow up from the bottom, and keep the middle group just above the bottom. The algorithm stores the locations just below the top group, just above the bottom, and just above the middle in three indexes. At each step, examine the element just above the middle. If it belongs to the top group, swap it with the element just below the top. If it belongs in the bottom, swap it with the element just above the bottom. If it is in the middle, leave it. Update the appropriate index. Complexity is Θ(n) moves and examinations."
And a C++ implementation given for the same is:
void threeWayPartition(int data[], int size, int low, int high) {
int p = -1;
int q = size;
for (int i = 0; i < q;) {
if (data[i] == low) {
swap(data[i], data[++p]);
++i;
} else if (data[i] >= high) {
swap(data[i], data[--q]);
} else {
++i;
}
}
}
My only question is how do we traverse back in a linked list like we are doing here in an array?
A standard singly-linked list doesn't allow you to move backwards given a linked list cell. However, you could use a doubly-linked list, where each cell stores a next and a previous pointer. That would let you navigate the list forwards and backwards.
However, for the particular problem you're trying to solve, I don't think this is necessary. One major difference between algorithms on arrays and on linked lists is that when working with linked lists, you can rearrange the cells in the list to reorder the elements in the list. Consequently, the algorithm you've detailed above - which works by changing the contents of the array - might not actually be the most elegant algorithm on linked lists.
If you are indeed working with linked lists, one possible way to solve this problem would be the following:
Create lists holding all values that are 0, 1, or 2.
Remove all cells from the linked list and distribute them into the list of elements that are equal to 0, 1, or 2.
Concatenate these three lists together.
This does no memory allocation and purely works by rearranging the linked list cells. It still runs in time Θ(n), which is another plus. Additionally, you can do this without ever having to walk backwards (i.e. this works on a singly-linked list).
I'll leave the complete implementation to you, but as an example, here's simple C++ code to distribute the linked list cells into the zero, one, and two lists:
struct Cell {
int value;
Cell* next;
}
/* Pointers to the heads of the three lists. */
Cell* lists[3] = { NULL, NULL, NULL };
/* Distribute the cells across the lists. */
while (list != NULL) {
/* Cache a pointer to the next cell in the list, since we will be
* rewiring this linked list.
*/
Cell* next = list->next;
/* Prepend this cell to the list it belongs to. */
list->next = lists[list->value];
lists[list->value] = list;
/* Advance to the next cell in the list. */
list = next;
}
Hope this helps!
As others have said, there is no way to "back up" in a linked list without reverse links. Though it's not exactly an answer to your question, the sort can be easily accomplished with three queues implementing a bucket sort with three buckets.
The advantage of queues (vice pushing on stacks) is that the sort is stable. That is, if there are data in the list nodes (other than the 0,1,2-valued keys), these will remain in the same order for each key.
This is only one of many cases where the canonical algorithm for arrays is not the best for lists.
There is a very slick, simple way to implement the queues: circularly linked lists where the first node, say p, is the tail of the queue and consequently p->next is is the head. With this, the code is concise.
#include <stdio.h>
#include <stdlib.h>
typedef struct node_s {
struct node_s *next;
int val;
int data;
} NODE;
// Add node to tail of queue q and return the new queue.
NODE *enqueue(NODE *q, NODE *node)
{
if (q) {
node->next = q->next;
q->next = node;
}
else node->next = node;
return node;
}
// Concatenate qa and qb and return the result.
NODE *cat(NODE *qa, NODE *qb)
{
NODE *head = qa->next;
qa->next = qb->next;
qb->next = head;
return qb;
}
// Sort a list where all values are 0, 1, or 2.
NODE *sort012(NODE *list)
{
NODE *next = NULL, *q[3] = { NULL, NULL, NULL};
for (NODE *p = list; p; p = next) {
next = p->next;
q[p->val] = enqueue(q[p->val], p);
}
NODE *result = cat(q[0], cat(q[1], q[2]));
// Now transform the circular queue to a simple linked list.
NODE *head = result->next;
result->next = NULL;
return head;
}
int main(void)
{
NODE *list = NULL;
int N = 100;
// Build a list of nodes for testing
for (int i = 0; i < N; ++i) {
NODE *p = malloc(sizeof(NODE));
p->val = rand() % 3;
p->data = N - i; // List ends up with data 1,2,3,..,N
p->next = list;
list = p;
}
list = sort012(list);
for (NODE *p = list; p; p = p->next)
printf("key val=%d, data=%d\n", p->val, p->data);
return 0;
}
This is now a complete simple test and it runs just fine.
This is untested. (I will try to test it if I get time.) But it ought to be at least very close to a solution.
Using a doubly linked list. If you have already implemented a linked list object and the related link list node object, and are able to traverse it in the forward direction it isn't a whole bunch more work to traverse in the reverse direction.
Assuming you have a Node object somewhat like:
public class Node
{
public Node Next;
public Object Value;
}
Then all you really need to do is change you Node class and you Insert method(s) up a little bit to keep track of of the Node that came previously:
public class Node
{
public Node Next;
public Node Previous;
public Object Value;
}
public void Insert(Node currentNode, Node insertedNode)
{
Node siblingNode = currentNode.Next;
insertedNode.Previous = currentNode;
insertedNode.Next = siblingNode;
if(siblingNode!= null)
siblingNode.previous = insertedNode;
currentNode.next = insertedNode;
}
PS Sorry, I didn't notice the edit that included the C++ stuff so it's more C#
Works for all cases by CHANGING NODES rather than NODE DATA.. Hoping its never too late!
METHOD(To throw some light on handling corner cases):
1. Keep three dummy nodes each for 0,1,2;
2. Iterate throught the list and add nodes to respective list.
3. Make the next of zero,one,two pointers as NULL.
4. Backup this last nodes of each list.
5. Now handle 8 different possible cases to join these list and Determine the HEAD.
zero one two
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
An implementation of this in C++.
Node* sortList(Node *head)
{
struct Node dummyzero,dummyone,dummytwo;
dummyzero.next = dummyone.next = dummytwo.next = NULL;
struct Node *zero =&dummyzero,*one = &dummyone,*two=&dummytwo;
Node *curr = head,*next=NULL;
while(curr)
{
next = curr->next;
if(curr->data==0)
{
zero->next = curr;
zero = zero->next;
}
else if(curr->data==1)
{
one->next = curr;
one = one->next;
}
else
{
two->next = curr;
two = two->next;
}
curr = next;
}
zero->next = one->next = two->next =NULL; //Since this dummynode, No segmentation fault here.
Node *zerolast = zero,*onelast = one,*twolast = two;
zero = dummyzero.next;
one = dummyone.next;
two = dummytwo.next;
if(zero==NULL)
{
if(one==NULL)
head = two;
else
{
head = one;
onelast->next = two;
}
}
else
{
head = zero;
if(one==NULL)
zerolast->next = two;
else
{
zerolast->next = one;
onelast->next = two;
}
}
return head;
}
The idea is to use dutch flag sorting algorithm, with a slight modification:
sort 0's and 1's as per dutch flag method,
But for 2's instead of adding them at the end of list, keep them in a separate linked list.
And finally append the 2's list to the sorted list of 0's and 1's.
Node * sort012_linked_list(Node * head) {
if (!head || !head->next)
return head;
Node * head_of_2s = NULL;
Node * prev = NULL;
Node * curr = head;
while (curr) {
if (curr->data == 0) {
if (prev == NULL || prev->data == 0) {
prev = curr;
curr = curr->next;
}
else {
prev->next = curr->next;
curr->next = head;
head = curr;
curr = prev->next;
}
}
else if (curr->data == 1) {
prev = curr;
curr = curr->next;
}
else { // curr->data == 2
if (prev == NULL) {
head = curr->next;
curr->next = head_of_2s;
head_of_2s = curr;
curr = head;
}
else {
prev->next = curr->next;
curr->next = head_of_2s;
head_of_2s = curr;
curr = prev->next;
}
}
}
if (prev)
prev->next = head_of_2s;
return head;
}

swapping adjacent nodes of a LinkedList

I have to swap two adjacent node(not their data) in a linked list.
e.g.
1) Input a->b->c->d->e->f, Output : b->a->d->c->f->e
2) Input a->b->c->d->e, Output : b->a->d->c->e
I have writen the following code is there any more efficient way (maybe with two temporary pointers) or simple logic?
node* swap(node* head) {
node *first = head;
node *second,*third,*result;
if(head == NULL || head->next == NULL) {
return head;
}
result = second = first->next;
third = second->next;
while(second != NULL) {
second->next=first;
first->next=(third->next==NULL ? third : third->next);
first=third;
second=(third->next==NULL ? third : third->next);
third=(second==NULL ? second : second->next);
}
return result;
}
Looks good. I added one correctness check (third==NULL) and removed one redundant expression. You are going through the whole list only once, which you have to do. So I think we can be pretty certain that this is the fastest way to do it.
node* swap(node* head) {
node *first = head;
node *second,*third,*result;
if(head == NULL || head->next == NULL) {
return head;
}
result = second = first->next;
third = second->next;
while(second != NULL) {
second->next=first;
second = first->next=((third==NULL || third->next==NULL) ? third : third->next);
first=third;
third=(second==NULL ? second : second->next);
}
return result;
}
You can do this fairly simply with a recursion:
// Swaps node b and c.
void swapTwo(node* a, node* b, node* c) {
if (a != NULL)
a->next = c;
b->next = c->next;
c->next = b;
}
void swapEveryTwo(node* prev, node* node) {
if (node != null && node->next != null) {
swapTwo(prev, node, node->next);
swapEveryTwo(node->next, node->next->next);
}
}
Every call of swapEveryTwo swaps pairs of nodes, and then sets up the recursion for the next pair. Also, because this function is tail recursive, the compiler will undoubtedly optimize it to a while loop, ensuring no extra stack frames are allocated, and thus will be optimal. If you need further explanation, feel free to ask.
Edited to add swap function as in original post:
node* swap(node *head) {
if (head != NULL && head->next != NULL) {
node *newHead = head->next;
swapEveryTwo(NULL, head);
return newHead;
} else {
return head;
}
}
Your algorithm is about the best possible. Often we can get a bit of speed through simplicity. Instead of drawing pictures and reasoning about pointers, think of popping elements off the head of the input list and using a queue add-to-tail operation to build up the result. In pseudocode, we have
set_empty(rtn);
while (head) {
fst = pop(head);
if (head) {
snd = pop(head);
add_at_tail(rtn, snd);
}
add_at_tail(rtn, fst);
}
The if is needed only to protect against the case where the input list has odd length. If we're sure the list is even in length, we can skip it.
Now pop is very easy to implement. The add-to-tail operation is easiest if we use a dummy head node. So in C, we have:
node *swap(node *head)
{
node dummy[1]; // set_empty(rtn);
node *rtn = dummy;
while (head) {
node *fst = head; // fst = pop(head);
head = head->next;
if (head) {
node *snd = head; // snd = pop(head);
head = head->next;
rtn->next = snd; // add_to_tail(rtn, snd);
rtn = rtn->next;
}
rtn->next = fst; // add_to_tail(rtn, fst);
rtn = rtn->next;
}
rtn->next = NULL; // terminate tail
return dummy->next;
}
Now I have not tested this code, but I'm pretty sure it will run fine modulo maybe a typo or two. There are fewer tests than yours (just one per element). Tests are comparatively expensive because they can interfere with pipelining, so mine ought to run just a tad faster. Almost certainly this difference is irrelevant.
However, I think my code rather simpler to understand. Of course that's just one biased opinion, but readability does count during maintenance.
NB Now I have done a quick test and it worked on the first try! On the other hand when I tried your code I got a segv at
first->next=(third->next==NULL ? third : third->next);
Below is the test frame. Do you see anything wrong?
typedef struct node_s {
struct node_s *next;
int val;
} node;
// swap goes here
int main(void)
{
node dummy[1];
node *p = dummy;
for (int i = 0; i < 16; i++) {
p->next = malloc(sizeof(node));
p = p->next;
p->next = NULL;
p->val = 'a' + i;
}
p = swap(dummy->next);
while (p) {
printf("%c ", p->val);
p = p->next;
}
printf("\n");
return 0;
}
In JavaScript
LinkedList.prototype.swapPairs = function() {
var recurse = function(current) {
if (!current) return this;
if (current.next) {
var save = current.next.value;
current.next.value = current.value;
current.value = save;
current = current.next;
}
return recurse(current.next);
}.bind(this);
return recurse(this.head);
}
Alex DiCarlo's recursion method is simpler but needs to be corrected slightly.
void swapEveryTwo(node* prev, node* node) {
if (node != null && node->next != null) {
swapTwo(prev, node, node->next);
swapEveryTwo(node, node->next);
}
}
Please correct me if I am wrong.
Thanks!

Resources