Given the head of a doubly linked list and an integer X, insert a node with value X before the tail of the linked list and return the head of the modified list.
Input: head -> 1 <-> 2 <-> 4, X = 3
Output: head -> 1 <-> 2 <-> 3 <-> 4
Explanation: 3 was added before the last node.
Input: head -> 4, X = 6
Output: head -> 6 <-> 4
Explanation: 6 was added before 4, note that the head was changed as a result.
Input: head -> 4 <-> 5, X = 6
#include <bits/stdc++.h>
using namespace std;
// Definition of doubly linked list
struct ListNode
{
int val;
ListNode *next;
ListNode *prev;
ListNode()
{
val = 0;
next = NULL;
prev = NULL;
}
ListNode(int data1)
{
val = data1;
next = NULL;
prev = NULL;
}
ListNode(int data1, ListNode *next1, ListNode *prev1)
{
val = data1;
next = next1;
prev = prev1;
}
};
// Solution class
class Solution {
public:
// Function to insert a node before tail of a doubly linked list
ListNode* insertBeforeTail(ListNode* head, int X) {
// Edge case
if (head->next == nullptr) {
// Create new node with data as X
ListNode* newHead = new ListNode(X, head, nullptr);
head->prev = newHead;
return newHead;
}
// Create pointer tail
ListNode* tail = head;
while (tail->next != nullptr) {
tail = tail->next;
}
// Keep track of node before tail using prev
ListNode* prev = tail->prev;
// Create new node with value X
ListNode* newNode = new ListNode(X, tail, prev);
// Join the new node
prev->next = newNode;
tail->prev = newNode;
// Return updated linked list
return head;
}
};
// Helper Function to convert an array to a doubly linked list
ListNode* arrayToLinkedList(vector<int> &nums) {
// If array is empty, return nullptr
if (nums.empty()) return nullptr;
// Create head node with first element of the array
ListNode* head = new ListNode(nums[0]);
// Initialize 'prev' to the head node
ListNode* prev = head;
for (int i=1; i < nums.size(); i++) {
// Create a new node
ListNode* temp = new ListNode(nums[i], nullptr, prev);
// Update 'next' pointer
prev->next = temp;
// Move 'prev' to newly created node
prev = temp;
}
// Return head
return head;
}
// Helper Function to print the linked list
void printLL(ListNode* head) {
while (head != NULL) {
cout << head->val << " ";
head = head->next;
}
cout << endl;
}
int main() {
vector<int> nums = {1, 2, 3, 5};
// Creating the doubly linked list from given array
ListNode* head = arrayToLinkedList(nums);
// Print the Original list
cout << "Original List: ";
printLL(head);
// Create an instance of Solution class
Solution sol;
/* Function call to insert a node
before tail of a doubly linked list */
head = sol.insertBeforeTail(head, 4);
// Print the Modified list
cout << "Modified list: ";
printLL(head);
return 0;
}
// Definition of doubly linked list
class ListNode {
int val;
ListNode next;
ListNode prev;
ListNode() {
val = 0;
next = null;
prev = null;
}
ListNode(int data1) {
val = data1;
next = null;
prev = null;
}
ListNode(int data1, ListNode next1, ListNode prev1) {
val = data1;
next = next1;
prev = prev1;
}
}
// Solution class
class Solution {
// Function to insert a node before tail of a doubly linked list
public ListNode insertBeforeTail(ListNode head, int X) {
// Edge case
if (head.next == null) {
// Create new node with data as X
ListNode newHead = new ListNode(X, head, null);
head.prev = newHead;
return newHead;
}
// Create pointer tail
ListNode tail = head;
while (tail.next != null) {
tail = tail.next;
}
// Keep track of node before tail using prev
ListNode prev = tail.prev;
// Create new node with value X
ListNode newNode = new ListNode(X, tail, prev);
// Join the new node
prev.next = newNode;
tail.prev = newNode;
// Return updated linked list
return head;
}
}
// Main method
class Main {
// Helper Function to convert an array to a doubly linked list
private static ListNode arrayToLinkedList(int[] nums) {
// If array is empty, return null
if (nums.length == 0) return null;
// Create head node with first element of the array
ListNode head = new ListNode(nums[0]);
// Initialize 'prev' to the head node
ListNode prev = head;
for (int i = 1; i < nums.length; i++) {
// Create a new node
ListNode temp = new ListNode(nums[i], null, prev);
// Update 'next' pointer
prev.next = temp;
// Move 'prev' to newly created node
prev = temp;
}
// Return head
return head;
}
// Helper Function to print the linked list
private static void printLL(ListNode head) {
while (head != null) {
System.out.print(head.val + " ");
head = head.next;
}
System.out.println();
}
// main method
public static void main(String[] args) {
int[] nums = {1, 2, 3, 5};
// Creating the doubly linked list from given array
ListNode head = arrayToLinkedList(nums);
// Print the Original list
System.out.print("Original List: ");
printLL(head);
// Create an instance of Solution class
Solution sol = new Solution();
/* Function call to insert a node
before tail of a doubly linked list */
head = sol.insertBeforeTail(head, 4);
// Print the Modified list
System.out.print("Modified list: ");
printLL(head);
}
}
# Definition of doubly linked list
class ListNode:
def __init__(self, data1=0, next1=None, prev1=None):
self.val = data1
self.next = next1
self.prev = prev1
# Solution class
class Solution:
''' Function to insert a node before tail of a doubly linked list '''
def insertBeforeTail(self, head, X):
# Edge case
if head.next is None:
# Create new node with data as X
newHead = ListNode(X, head, None)
head.prev = newHead
return newHead
# Create pointer tail
tail = head
while tail.next is not None:
tail = tail.next
# Keep track of node before tail using prev
prev = tail.prev
# Create new node with value X
newNode = ListNode(X, tail, prev)
# Join the new node
prev.next = newNode
tail.prev = newNode
# Return updated linked list
return head
# Helper Function to convert an array to a doubly linked list
def arrayToLinkedList(nums):
# If array is empty, return None
if not nums:
return None
# Create head node with first element of the array
head = ListNode(nums[0])
# Initialize 'prev' to the head node
prev = head
for i in range(1, len(nums)):
# Create a new node
temp = ListNode(nums[i], None, prev)
# Update 'next' pointer
prev.next = temp
# Move 'prev' to newly created node
prev = temp
# Return head
return head
# Helper Function to print the linked list
def printLL(head):
while head is not None:
print(head.val, end=" ")
head = head.next
print()
if __name__ == "__main__":
nums = [1, 2, 3, 5]
# Creating the doubly linked list from given array
head = arrayToLinkedList(nums)
# Print the Original list
print("Original List: ", end="")
printLL(head)
# Create an instance of Solution class
sol = Solution()
''' Function call to insert a node
before tail of a doubly linked list '''
head = sol.insertBeforeTail(head, 4)
# Print the Modified list
print("Modified list: ", end="")
printLL(head)
// Definition of doubly linked list
class ListNode {
constructor(data1 = 0, next1 = null, prev1 = null) {
this.val = data1;
this.next = next1;
this.prev = prev1;
}
}
// Solution class
class Solution {
// Function to insert a node before tail of a doubly linked list
insertBeforeTail(head, X) {
// Edge case
if (head.next === null) {
// Create new node with data as X
let newHead = new ListNode(X, head, null);
head.prev = newHead;
return newHead;
}
// Create pointer tail
let tail = head;
while (tail.next !== null) {
tail = tail.next;
}
// Keep track of node before tail using prev
let prev = tail.prev;
// Create new node with value X
let newNode = new ListNode(X, tail, prev);
// Join the new node
prev.next = newNode;
tail.prev = newNode;
// Return updated linked list
return head;
}
}
// Helper Function to convert an array to a doubly linked list
function arrayToLinkedList(nums) {
// If array is empty, return null
if (nums.length === 0) return null;
// Create head node with first element of the array
let head = new ListNode(nums[0]);
// Initialize 'prev' to the head node
let prev = head;
for (let i = 1; i < nums.length; i++) {
// Create a new node
let temp = new ListNode(nums[i], null, prev);
// Update 'next' pointer
prev.next = temp;
// Move 'prev' to newly created node
prev = temp;
}
// Return head
return head;
}
// Helper Function to print the linked list
function printLL(head) {
while (head !== null) {
process.stdout.write(head.val + " ");
head = head.next;
}
console.log();
}
const main = () => {
const nums = [1, 2, 3, 5];
// Creating the doubly linked list from given array
let head = arrayToLinkedList(nums);
// Print the Original list
console.log("Original List: ");
printLL(head);
// Create an instance of Solution class
let sol = new Solution();
/* Function call to insert a node
before tail of a doubly linked list */
head = sol.insertBeforeTail(head, 4);
// Print the Modified list
console.log("Modified list: ");
printLL(head);
}
main();
Q: Can this problem be solved using a singly linked list?
A: No, a singly linked list does not support backward traversal efficiently, making it harder to insert before the tail without full traversal.
Q: Why do we need to insert before the tail, not after it?
A: The problem explicitly asks to insert before the last node, so tail’s previous node is used.
Q: How would you modify the solution if you were allowed to insert after the tail instead?
A: Simply append the new node after the last node and update tail.
Q: How does this compare to inserting at arbitrary positions?
A: Arbitrary insertions require finding the correct position, leading to O(n) traversal.