Swap KTH Node From Beginning With KTH Node From End in A Linked List
Swap KTH Node From Beginning With KTH Node From End in A Linked List
Swap KTH Node From Beginning With KTH Node From End in A Linked List
The problem seems simple at first look, but it has many interesting cases.
Let X be the kth node from beginning and Y be the kth node from end. Following are
the interesting cases that must be handled.
1) Y is next to X
2) X is next to Y
3) X and Y are same
4) X and Y don’t exist (k is more than number of nodes in linked list)
// A C++ program to swap Kth node from beginning with kth node from end
#include <iostream>
#include <stdlib.h>
using namespace std;
/* Function for swapping kth nodes from both ends of linked list */
void swapKth(struct Node **head_ref, int k)
{
// Count nodes in linked list
int n = countNodes(*head_ref);
// Check if k is valid
if (n < k) return;
// If x (kth node from start) and y(kth node from end) are same
if (2*k - 1 == n) return;
// Find the kth node from beginning of linked list. We also find
// previous of kth node because we need to update next pointer of
// the previous.
Node *x = *head_ref;
Node *x_prev = NULL;
for (int i = 1; i < k; i++)
{
x_prev = x;
x = x->next;
}
// Similarly, find the kth node from end and its previous. kth node
// from end is (n-k+1)th node from beginning
Node *y = *head_ref;
Node *y_prev = NULL;
for (int i = 1; i < n-k+1; i++)
{
y_prev = y;
y = y->next;
}
return 0;
}
Output:
Original Linked List: 1 2 3 4 5 6 7 8
// Driver program
int main(void)
{
Node *head = NULL;
insert(&head, 5);
insert(&head, 20);
insert(&head, 4);
insert(&head, 3);
insert(&head, 30);
insert(&head, 10);
head = mergeSort(head);
cout << "Linked List after sorting\n";
print(head);
return 0;
}
Output:
Linked List after sorting
Forward Traversal using next pointer
3 4 5 10 20 30
Backward Traversal using prev pointer
30 20 10 5 4 3
Thanks to Goku for providing above implementation in a comment here.
Time Complexity: Time complexity of the above implementation is same as time
complexity of MergeSort for arrays. It takes Θ(nLogn) time.
A simple approach for this problem is to one by one pick each node and find
second element whose sum is equal to x in the remaining list by traversing in forward
direction.Time complexity for this problem will be O(n^2) , n is total number of nodes
in doubly linked list.
An efficient solution for this problem is same as this article. Here is the algorithm :
Initialize two pointer variables to find the candidate elements in the sorted
doubly linked list.Initialize first with start of doubly linked list i.e; first=head and
initialize second with last node of doubly linked list i.e; second=last_node.
We initialize first and second pointers as first and last nodes. Here we don’t
have random access, so to find second pointer, we traverse the list to initialize
second.
If current sum of first and second is less than x, then we move first in forward
direction. If current sum of first and second element is greater than x, then we
move second in backward direction.
Loop termination conditions are also different from arrays. The loop terminates
when either of two pointers become NULL, or they cross each other (second-
>next = first), or they become same (first == second)
pairSum(head, x);
return 0;
}
Output:
(1,6)
(2,5)
else
Initialize current = head_ref
while (current->next != NULL and
current->next->data data)
current = current->next
newNode->next = current->next
if current->next != NULL
newNode->next->prev = newNode
current->next = newNode
newNode->prev = current
// if list is empty
if (*head_ref == NULL)
*head_ref = newNode;
else {
current = *head_ref;
current->next = newNode;
newNode->prev = current;
}
}
Output:
Created Doubly Linked List
3 5 8 9 10 12
Time Complexity: O(n)
// increment count
count++;
if ((*head) == NULL)
(*head) = temp;
else {
temp->next = *head;
(*head)->prev = temp;
(*head) = temp;
}
}
// pair found
if ((first->data + second->data) == value) {
// increment count
count++;
if ((*head) == NULL)
(*head) = temp;
else {
temp->next = *head;
(*head)->prev = temp;
(*head) = temp;
}
}
int x = 17;
Algorithm:
removeDuplicates(head_ref, x)
if head_ref == NULL
return
Initialize current = head_ref
while current->next != NULL
if current->data == current->next->data
deleteNode(head_ref, current->next)
else
current = current->next
The algorithm for deleteNode(head_ref, current) (which deletes the node using the
pointer to the node) is discussed in this post.
return 0;
}
Output:
Original Doubly linked list:
4 4 4 4 6 8 8 10 12 12
Doubly linked list after removing duplicates:
4 6 8 10 12
Time Complexity: O(n)
Algorithm:
delAllOccurOfGivenKey(head_ref, x)
if head_ref == NULL
return
Initialize current = head_ref
Declare next
while current != NULL
if current->data == x
next = current->next
deleteNode(head_ref, current)
current = next
else
current = current->next
The algorithm for deleteNode(head_ref, current) (which deletes the node using the
pointer to the node) is discussed in this post.
/* update current */
current = next;
}
int x = 2;
return 0;
}
Output:
Original Doubly linked list:
2 2 10 8 4 2 5 2
Doubly linked list after deletion of 2:
10 8 4 5
Time Complexity: O(n)
Approach: Create a recursive function say reverse(head, k). This function receives the
head or the first node of each group of k nodes. It reverses those group of k nodes by
applying the approach discussed in Reverse a doubly linked list | Set-2. After reversing the
group of k nodes the function checks whether next group of nodes exists in the list or not. If
group exists then it makes a recursive call to itself with the first node of the next group and
makes the necessary adjustments with the next and previous links of that group. Finally it
returns the new head node of the reversed group.
// C++ implementation to reverse a doubly linked list
// in groups of given size
#include <bits/stdc++.h>
int k = 2;
return 0;
}
Output:
Original list: 10 8 4 2
Modified list: 8 10 2 4
Time Complexity: O(n).
Given a Binary Tree (BT), convert it to a Doubly Linked List(DLL) In-Place. The left
and right pointers in nodes are to be used as previous and next pointers respectively
in converted DLL. The order of nodes in DLL must be same as Inorder of the given
Binary Tree. The first node of Inorder traversal (left most node in BT) must be head
node of the DLL.
printList(head);
return 0;
}
Output :
Extracted Double Linked list is:
0 1 2 3 4 5 6 7 8 9
Approach: The idea is to traverse the nodes of the doubly linked list one by one and
get the pointer of the nodes having even data then replace by the value of the array
and increment the index of the array and move to the next node in the linked list.
Below is the implementation of above approach:
// C++ implementation to create
// odd doubly linked list
#include <bits/stdc++.h>
using namespace std;
N=2
Rotated List:
Examples:
Input : a b c d e N = 2
Output : c d e a b
Input : a b c d e f g h N = 4
Output : e f g h a b c d
To rotate the Doubly linked list, we need to change next of Nth node to NULL, next of
last node to previous head node, and prev of head node to last node and finally
change head to (N+1)th node and prev of new head node to NULL (Prev of Head
node in doubly linked list is NULL)
So we need to get hold of three nodes: Nth node, (N+1)th node and last node.
Traverse the list from beginning and stop at Nth node. Store pointer to Nth node. We
can get (N+1)th node using NthNode->next. Keep traversing till end and store
pointer to last node also. Finally, change pointers as stated above and at Last Print
Rotated List using
PrintList Function.
C++
Java
C#
filter_none
edit
play_arrow
brightness_4
// C++ program to rotate a Doubly linked
// list counter clock wise by N times
#include <bits/stdc++.h>
using namespace std;
// Driver's Code
int main(void)
{
/* Start with the empty list */
struct Node* head = NULL;
int N = 2;
return 0;
}
Output:
Given linked list
a b c d e
Rotated Linked list
c d e a b
Delete all the nodes from a doubly linked list that are
smaller than a given value
Given a doubly linked list containing N nodes and a number K, the task is to delete
all the nodes from the list that are smaller than the given value K.
Examples:
Input: 15 <=> 16 <=> 10 <=> 9 <=> 6 <=> 7 <=> 17
K = 10
Output: 15 <=> 16 <=> 10 <=> 17
Approach: Traverse the nodes of the doubly linked list one by one and get the
pointer of the nodes having data value smaller than K. Refer to the article
on Deleting a node from Doubly Linked List to delete a node.
Below is the implementation of the above approach:
// C++ implementation to delete all
// the nodes from the doubly
// linked list that are smaller than
// the specified value K
#include <bits/stdc++.h>
return;
}
int K = 10;
deletesmallerNodes(&head, K);
Output:
Original List: 15 16 10 9 6 7 17
Modified List: 15 16 10 17
Time Complexity: O(N), where N is the total number of Nodes.
Input:
M = 3, N = 2
Linked List: 1->2->3->4->5->6->7->8->9->10
Output:
Linked List: 1->2->3->6->7->8
Input:
M = 1, N = 1
Linked List: 1->2->3->4->5->6->7->8->9->10
Output:
Linked List: 1->3->5->7->9
The main part of the problem is to maintain proper links between nodes, make sure
that all corner cases are handled. Following is C implementation of function
skipMdeleteN() that skips M nodes and delete N nodes till end of list. It is assumed
that M cannot be 0.
class Node
public:
int data;
Node *next;
};
/* allocate node */
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
{
cout<<temp->data<<" ";
temp = temp->next;
cout<<endl;
int count;
while (curr)
// Skip M nodes
curr = curr->next;
if (curr == NULL)
return;
t = curr->next;
Node *temp = t;
t = t->next;
free(temp);
}
// Link the previous list with remaining nodes
curr->next = t;
curr = t;
// Driver code
int main()
1->2->3->4->5->6->7->8->9->10 */
push(&head, 10);
push(&head, 9);
push(&head, 8);
push(&head, 7);
push(&head, 6);
push(&head, 5);
push(&head, 4);
push(&head, 3);
push(&head, 2);
push(&head, 1);
cout << "M = " << M<< " N = " << N << "\nGiven Linked list is :\n";
printList(head);
skipMdeleteN(head, M, N);
return 0;
Output:
M = 2, N = 3
Given Linked list is :
1 2 3 4 5 6 7 8 9 10
1. Create a doubly linked list where each node contains only one character of a
string.
2. Initialize two pointers left at starting of list and right at the end of the list.
3. Check the data at left node is equal to right node, if it is equal then increment
left and decrement right till middle of the list, if at any stage it is not equal then
return false.
// Structure of node
struct Node
{
char data;
struct Node *next;
struct Node *prev;
};
left = left->next;
right = right->prev;
}
return true;
}
// Driver program
int main()
{
struct Node* head = NULL;
push(&head, 'l');
push(&head, 'e');
push(&head, 'v');
push(&head, 'e');
push(&head, 'l');
if (isPalindrome(head))
printf("It is Palindrome");
else
printf("Not Palindrome");
return 0;
}
Output:
It is Palindrome
Time complexity: O(n)
Auxiliary Space : O(1)
Examples:
Input: Initial List = 15 <=> 16 <=> 6 <=> 7 <=> 17
Output: Final List = 15 <=> 7 <=> 17
Input: Initial List = 5 <=> 3 <=> 6 <=> 8 <=> 4 <=> 1 <=> 2 <=> 9
Output: Final List = 5 <=> 3 <=> 1 <=> 9
return;
}
// Driver program
int main()
{
// start with the empty list
Node* head = NULL;
deleteEvenNodes(&head);
Output:
Doubly Linked List
785910
Modified Tree:
1
/ \
2 3
/ \
4 6
We need to traverse all leaves and connect them by changing their left and right
pointers. We also need to remove them from Binary Tree by changing left or right pointers in
parent nodes. There can be many ways to solve this. In the following implementation, we
add leaves at the beginning of current linked list and update head of the list using pointer to
head pointer. Since we insert at the beginning, we need to process leaves in reverse order.
For reverse order, we first traverse the right subtree then the left subtree. We use return
values to update left or right pointers in parent nodes.
return root;
}
// Driver code
int main()
{
Node *head = NULL;
Node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
root->right->right = newNode(6);
root->left->left->left = newNode(7);
root->left->left->right = newNode(8);
root->right->right->left = newNode(9);
root->right->right->right = newNode(10);
Output:
Inorder Trvaersal of given Tree is:
7 4 8 2 5 1 3 9 6 10
Extracted Double Linked list is:
7 8 5 9 10
Inorder traversal of modified tree is:
4 2 1 3 6
Time Complexity: O(n), the solution does a single traversal of given Binary Tree.
Sort a k sorted doubly linked list
Given a doubly linked list containing n nodes, where each node is at most k away
from its target position in the list. The problem is to sort the given doubly linked list.
For example, let us consider k is 2, a node at position 7 in the sorted doubly linked
list, can be at positions 5, 6, 7, 8, 9 in the given doubly linked list.
Examples:
Naive Approach: Sort the given doubly linked list using insertion sort technique.
Time Complexity: O(nk)
Auxiliary Space: O(1)
Efficient Approach: We can sort the list using the MIN HEAP data structure. The
approach has been explained in Sort a nearly sorted (or K sorted) array. We only
have to be careful while traversing the input doubly linked list and adjusting the
required next and previous links in the final sorted list.
filter_none
edit
play_arrow
brightness_5
// C++ implementation to sort a k sorted doubly
// linked list
#include <bits/stdc++.h>
struct Node {
int data;
};
// priority queue
struct compare {
};
// if list is empty
if (head == NULL)
return head;
pq.push(head);
head = head->next;
while (!pq.empty()) {
// place root or top of 'pq' at the end of the
// pointed to by 'newHead'
if (newHead == NULL) {
newHead = pq.top();
newHead->prev = NULL;
last = newHead;
else {
last->next = pq.top();
pq.top()->prev = last;
last = pq.top();
pq.pop();
if (head != NULL) {
pq.push(head);
head = head->next;
return newHead;
// allocate node
new_node->data = new_data;
new_node->prev = NULL;
new_node->next = (*head_ref);
if ((*head_ref) != NULL)
(*head_ref)->prev = new_node;
(*head_ref) = new_node;
// if list is empty
if (head == NULL)
head = head->next;
int main()
// 3<->6<->2<->12<->56<->8
push(&head, 8);
push(&head, 56);
push(&head, 12);
push(&head, 2);
push(&head, 6);
push(&head, 3);
int k = 2;
printList(head);
printList(head);
return 0;
Output:
Original Doubly linked list:
3 6 2 12 56 8
Doubly linked list after sorting:
2 3 6 8 12 56
Time Complexity: O(nLogk)
Auxiliary Space: O(k)
#include <bits/stdc++.h>
struct Node {
int data;
};
// base case
return;
if (*head_ref == del)
*head_ref = del->next;
if (del->next != NULL)
del->next->prev = del->prev;
if (del->prev != NULL)
del->prev->next = del->next;
free(del);
// a single node
if ((*head_ref) == NULL ||
(*head_ref)->next == NULL)
return;
ptr2 = ptr1->next;
if (ptr1->data == ptr2->data) {
deleteNode(head_ref, ptr2);
// update 'ptr2'
ptr2 = next;
ptr2 = ptr2->next;
// allocate node
new_node->data = new_data;
new_node->prev = NULL;
new_node->next = (*head_ref);
if ((*head_ref) != NULL)
(*head_ref)->prev = new_node;
(*head_ref) = new_node;
// if list is empty
if (head == NULL)
head = head->next;
int main()
// 8<->4<->4<->6<->4<->8<->4<->10<->12<->12
push(&head, 12);
push(&head, 12);
push(&head, 10);
push(&head, 4);
push(&head, 8);
push(&head, 4);
push(&head, 6);
push(&head, 4);
push(&head, 4);
push(&head, 8);
printList(head);
/* remove duplicate nodes */
removeDuplicates(&head);
"removing duplicates:n";
printList(head);
return 0;
Output:
Original Doubly linked list:
8 4 4 6 4 8 4 10 12 12
Doubly linked list after removing duplicates:
8 4 6 10 12
Time Complexity: O(n2)
Auxiliary Space: O(1)
Method 2 (Sorting): Following are the steps:
1. Sort the elements of the doubly linked list using Merge Sort. Refer this post.
2. Remove duplicates in linear time using the algorithm to remove duplicates from a
sorted doubly linked list.
Time Complexity: O(nLogn)
Auxiliary Space: O(1)
Note that this method doesn’t preserve the original order of elements.
Method 3 Efficient Approach(Hashing):
We traverse the doubly linked list from head to end. For every newly encountered
element, we check whether it is in the hash table: if yes, we remove it; otherwise we
put it in the hash table. Hash table is implemented using unordered_set in C++.
#include <bits/stdc++.h>
struct Node {
int data;
};
// base case
return;
if (*head_ref == del)
*head_ref = del->next;
if (del->next != NULL)
del->next->prev = del->prev;
if (del->prev != NULL)
del->prev->next = del->next;
free(del);
if ((*head_ref) == NULL)
return;
unordered_set<int> us;
if (us.find(current->data) != us.end()) {
// 'current' node
next = current->next;
deleteNode(head_ref, current);
// update 'current'
current = next;
else {
us.insert(current->data);
// move to the next node
current = current->next;
// allocate node
new_node->data = new_data;
new_node->prev = NULL;
new_node->next = (*head_ref);
if ((*head_ref) != NULL)
(*head_ref)->prev = new_node;
(*head_ref) = new_node;
}
// Function to print nodes in a given doubly
// linked list
// if list is empty
if (head == NULL)
head = head->next;
int main()
// 8<->4<->4<->6<->4<->8<->4<->10<->12<->12
push(&head, 12);
push(&head, 12);
push(&head, 10);
push(&head, 4);
push(&head, 8);
push(&head, 4);
push(&head, 6);
push(&head, 4);
push(&head, 4);
push(&head, 8);
printList(head);
/* remove duplicate nodes */
removeDuplicates(&head);
"removing duplicates:n";
printList(head);
return 0;
Output:
Original Doubly linked list:
8 4 4 6 4 8 4 10 12 12
Doubly linked list after removing duplicates:
8 4 6 10 12
Time Complexity: O(n)
Auxiliary Space: O(n)