Find the Previous Closest Smaller Node in a Singly Linked List
Last Updated :
31 Dec, 2023
Given a singly linked list, the task is to find the previous closest smaller node for every node in a linked list.
Examples:
Input: 5 -> 6 -> 8 -> 2 -> 3 -> 4
Output: -1 -> 5 -> 6 -> -1 -> 2 -> 3
Explanation:
- For the first node 5, there is no previous closest smaller node so it is replaced with -1.
- For the second node 6, the previous closest smaller node is 5, so it is replaced with 5.
- For the third node 8, the previous closest smaller node is 6, so it is replaced with 6.
- For the fourth node 2, there is no previous closest smaller node so it is replaced with -1.
- For the fifth node 3, the previous closest smaller node is 2, so it is replaced with 2.
- For the sixth node 4, the previous closest smaller node is 3, so it is replaced with 3.
Input: 9 -> 2 -> 7 -> 4 -> 6
Output: -1 -> -1 -> 2 -> 2 -> 4
Explanation:
- For the first node 9, there is no previous closest smaller node so it is replaced with -1.
- For the second node 2, there is no previous closest smaller node so it is replaced with -1.
- For the third node 7, the previous closest smaller node is 2, so it is replaced with 2.
- For the fourth node 4, the previous closest smaller node is 2, so it is replaced with 2.
- For the fifth node 6, the previous closest smaller node is 4, so it is replaced with 4.
Approach: To solve the problem follow the below idea:
The intuition behind this approach is to use a stack to keep track of the previous smaller elements as we traverse the linked list. For each node in the linked list, we pop elements from the stack that are greater than or equal to the current node’s value until we find an element smaller than the current node’s value. The top element of the stack at this point is the previous smaller element for the current node. We then push the current node’s value onto the stack and create a new node in a separate linked list with the value of the previous smaller element. We continue this process for all nodes in the original linked list, and the resulting linked list contains the previous smaller element for each node.
Steps of this approach:
- Create an empty stack to store the nodes of the list.
- Traverse the list, starting from the head node.
- For each node, pop all nodes from the stack that have values greater than or equal to the current node’s value, until either the stack is empty or the top node’s value is less than the current node’s value.
- If the stack is not empty, then the previous smaller node for the current node is the top node of the stack. Otherwise, there is no previous smaller node, and we can set it to -1.
- Push the current node onto the stack.
- Repeat steps 3-5 until the end of the list is reached.
- Create a new linked list using the values of the previous smaller nodes we found, and return it as the result.
Implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node* next;
};
Node* createNode( int data)
{
Node* node = new Node;
node->data = data;
node->next = NULL;
return node;
}
Node* findPrevSmaller(Node* head)
{
stack< int > s;
Node* curr = head;
int prevSmaller;
Node* result = NULL;
while (curr != NULL) {
prevSmaller = -1;
while (!s.empty() && s.top() >= curr->data) {
s.pop();
}
if (!s.empty()) {
prevSmaller = s.top();
}
s.push(curr->data);
Node* newNode = createNode(prevSmaller);
if (result == NULL) {
result = newNode;
}
else {
Node* temp = result;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
curr = curr->next;
}
return result;
}
void printList(Node* head)
{
while (head != NULL) {
if (head->next != NULL) {
cout << head->data << " -> ";
}
else {
cout << head->data << "\n";
}
head = head->next;
}
}
int main()
{
Node* head = createNode(5);
head->next = createNode(6);
head->next->next = createNode(8);
head->next->next->next = createNode(2);
head->next->next->next->next = createNode(3);
head->next->next->next->next->next = createNode(4);
Node* result = findPrevSmaller(head);
cout << "List with Previous Closest Smaller Nodes: ";
printList(result);
return 0;
}
|
Java
import java.util.Stack;
class Node {
int data;
Node next;
Node( int data) {
this .data = data;
this .next = null ;
}
}
public class PrevClosestSmaller {
static Node findPrevSmaller(Node head) {
Stack<Integer> s = new Stack<>();
Node curr = head;
int prevSmaller;
Node result = null ;
while (curr != null ) {
prevSmaller = - 1 ;
while (!s.isEmpty() && s.peek() >= curr.data) {
s.pop();
}
if (!s.isEmpty()) {
prevSmaller = s.peek();
}
s.push(curr.data);
Node newNode = new Node(prevSmaller);
if (result == null ) {
result = newNode;
} else {
Node temp = result;
while (temp.next != null ) {
temp = temp.next;
}
temp.next = newNode;
}
curr = curr.next;
}
return result;
}
static void printList(Node head) {
while (head != null ) {
if (head.next != null ) {
System.out.print(head.data + " -> " );
} else {
System.out.println(head.data);
}
head = head.next;
}
}
public static void main(String[] args) {
Node head = new Node( 5 );
head.next = new Node( 6 );
head.next.next = new Node( 8 );
head.next.next.next = new Node( 2 );
head.next.next.next.next = new Node( 3 );
head.next.next.next.next.next = new Node( 4 );
Node result = findPrevSmaller(head);
System.out.print( "List with Previous Closest Smaller Nodes: " );
printList(result);
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self . next = None
def find_prev_smaller(head):
stack = []
curr = head
prev_smaller = None
result = None
while curr:
prev_smaller = None
while stack and stack[ - 1 ] > = curr.data:
stack.pop()
if stack:
prev_smaller = stack[ - 1 ]
stack.append(curr.data)
new_node = Node(prev_smaller)
if not result:
result = new_node
else :
temp = result
while temp. next :
temp = temp. next
temp. next = new_node
curr = curr. next
return result
def print_list(head):
while head:
if head. next :
print (head.data if head.data is not None else - 1 , end = " -> " )
else :
print (head.data if head.data is not None else - 1 )
head = head. next
if __name__ = = "__main__" :
head = Node( 5 )
head. next = Node( 6 )
head. next . next = Node( 8 )
head. next . next . next = Node( 2 )
head. next . next . next . next = Node( 3 )
head. next . next . next . next . next = Node( 4 )
result = find_prev_smaller(head)
print ( "List with Previous Closest Smaller Nodes:" , end = " " )
print_list(result)
|
C#
using System;
using System.Collections.Generic;
public class Node
{
public int data;
public Node next;
}
class Program
{
static Node CreateNode( int data)
{
Node node = new Node();
node.data = data;
node.next = null ;
return node;
}
static Node FindPrevSmaller(Node head)
{
Stack< int > stack = new Stack< int >();
Node curr = head;
int prevSmaller;
Node result = null ;
while (curr != null )
{
prevSmaller = -1;
while (stack.Count > 0 && stack.Peek() >= curr.data)
{
stack.Pop();
}
if (stack.Count > 0)
{
prevSmaller = stack.Peek();
}
stack.Push(curr.data);
Node newNode = CreateNode(prevSmaller);
if (result == null )
{
result = newNode;
}
else
{
Node temp = result;
while (temp.next != null )
{
temp = temp.next;
}
temp.next = newNode;
}
curr = curr.next;
}
return result;
}
static void PrintList(Node head)
{
while (head != null )
{
if (head.next != null )
{
Console.Write(head.data + " -> " );
}
else
{
Console.WriteLine(head.data);
}
head = head.next;
}
}
static void Main()
{
Node head = CreateNode(5);
head.next = CreateNode(6);
head.next.next = CreateNode(8);
head.next.next.next = CreateNode(2);
head.next.next.next.next = CreateNode(3);
head.next.next.next.next.next = CreateNode(4);
Node result = FindPrevSmaller(head);
Console.Write( "List with Previous Closest Smaller Nodes: " );
PrintList(result);
}
}
|
Javascript
class Node {
constructor(data) {
this .data = data;
this .next = null ;
}
}
function findPrevSmaller(head) {
const stack = [];
let curr = head;
let prevSmaller;
let result = null ;
while (curr !== null ) {
prevSmaller = -1;
while (stack.length > 0 && stack[stack.length - 1] >= curr.data) {
stack.pop();
}
if (stack.length > 0) {
prevSmaller = stack[stack.length - 1];
}
stack.push(curr.data);
const newNode = new Node(prevSmaller);
if (result === null ) {
result = newNode;
} else {
let temp = result;
while (temp.next !== null ) {
temp = temp.next;
}
temp.next = newNode;
}
curr = curr.next;
}
return result;
}
function printList(head) {
let current = head;
let listString = "List with Previous Closest Smaller Nodes: " ;
while (current !== null ) {
if (current.next !== null ) {
listString += current.data + " -> " ;
} else {
listString += current.data;
}
current = current.next;
}
console.log(listString);
}
const head = new Node(5);
head.next = new Node(6);
head.next.next = new Node(8);
head.next.next.next = new Node(2);
head.next.next.next.next = new Node(3);
head.next.next.next.next.next = new Node(4);
const result = findPrevSmaller(head);
printList(result);
|
Output
List with Previous Closest Smaller Nodes: -1 -> 5 -> 6 -> -1 -> 2 -> 3
Time Complexity: O(n), where n is the number of nodes in the linked list.
Auxiliary Space: O(n), where n is the number of nodes in the linked list. This is because we use a stack to store the previous smaller elements and a linked list to store the result.
Share your thoughts in the comments
Please Login to comment...