Skip to content
Related Articles

Related Articles

Improve Article

Find triplet sum closest to X in a sorted Doubly Linked List (DLL)

  • Last Updated : 14 Jul, 2021

Given a sorted doubly linked list of N nodes and an integer X, the task is to find the sum of three nodes in the list which is closest to X

Examples:

Input: DLL: -8 ↔ 2 ↔ 3 ↔ 4 ↔ 5, X = 1
Output: 1
Explanation: The required three integers {-8, 4, 5} whose sum is 1 and is closest to 1. 

Input: DLL: 1 ↔ 2 ↔ 3 ↔ 4, X = 3 
Output: 6
Explanation: The required three integers are {1, 2, 3} whose sum is 6 and is closest to X = 3. 

Naive Approach: The simplest approach to solve the given problem is to generate all possible triplets using three nested loops and then choose the triplet which has the sum closest to X and print the sum of the triplet.

Time Complexity: O(N3)
Auxiliary Space: O(1)

Efficient Approach: To optimize the above approach, the idea is to use 3 pointer technique. Follow the steps below to solve this problem:

  • Initialize 4 variables, first and second pointing to the head node of the doubly linked list, i.e., first = head, second = head, and tail and third both initialized to the last node of the doubly linked list.
  • Initialize a variable diff, initialized as INT_MAX, which stores the closest sum to X.
  • Iterate while the first node is not NULL and perform the following steps:
    • Initialize second to the next of first, i.e., second = first→next and third = tail(the last node of doubly linked list).
    • Iterate while second and third are not NULL and third is not equal to the second.
      • Initialize a variable say, sum as (first→data + second→data + third→data).
      • If the absolute value of X – sum is less than the absolute value of X diff, then update the value of diff as sum.
      • If sum is less than X, then increment second pointer, i.e., second = second→next.
      • Otherwise, decrement third, i.e., third = third→prev.
    • Move the first pointer to the next pointer, i.e., first = first→next.
  • After completing the above steps, print the value of diff as the result.

Below is the implementation of the above approach:



C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Doubly linked list node
struct Node {
    int data;
    struct Node *next, *prev;
};
  
// Function to insert a new node at
// the beginning of doubly linked
// list
void insert(struct Node** head, int data)
{
    // Allocate node
    struct Node* temp = new Node();
  
    // Fill the data value in it
    temp->data = data;
    temp->next = temp->prev = NULL;
  
    // If head is NULL change
    // head to temp
    if ((*head) == NULL) {
        (*head) = temp;
    }
  
    // Insert the node before head
    else {
        temp->next = *head;
        (*head)->prev = temp;
        (*head) = temp;
    }
}
  
// Function to find sum of triplet
// closest to X
void closestTripletSum(struct Node* head, int X)
{
    // Points to the first node
    // of the triplet
    struct Node* first = head;
  
    // Points to the second node
    // of the triplet
    struct Node* second = head->next;
  
    // Stores the last node of
    // doubly linked list
    struct Node* tail = head;
  
    // Traverse till end of the list
    while (tail->next != NULL) {
        tail = tail->next;
    }
  
    // Stores the sum closest to X
    int diff = INT_MAX;
  
    // Points to the third node
    // of the triplet
    struct Node* third = tail;
  
    // Iterate till the end of the list
    while (first != NULL) {
        second = first->next;
        third = tail;
  
        while (second != NULL && third != NULL
               && third != second) {
            int sum = (first->data + second->data
                       + third->data);
  
            // Check if the current sum
            // is closest to X
            if (abs(X - sum) < abs(X - diff)) {
  
                // Update the value of diff
                diff = sum;
            }
  
            // Check if sum is less than X
            if (sum < X) {
  
                // Increment the second
                // pointer
                second = second->next;
            }
            else {
  
                // Decrement the third
                // pointer
                third = third->prev;
            }
        }
  
        // Move the first pointer
        // ahead
        first = first->next;
    }
  
    // Print the closest sum
    cout << diff;
}
  
// Driver Code
int main()
{
    // Given Input
    struct Node* head = NULL;
    insert(&head, 4);
    insert(&head, 3);
    insert(&head, 2);
    insert(&head, 1);
    int X = 3;
  
    // Function Call
    closestTripletSum(head, X);
  
    return 0;
}
Output
6

Time Complexity: O(N2)
Auxiliary Space: O(1)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :