Given a linked list containing N nodes and a positive integer K where K should be less than or equal to N. The task is to print the last K nodes of the list in reverse order.
Examples:
Input : list: 1->2->3->4->5, K = 2
Output : 5 4
Input : list: 3->10->6->9->12->2->8, K = 4
Output : 8 2 12 9
The solution discussed in previous post uses recursive approach. The following article discusses three iterative approaches to solve the above problem.
Approach 1: The idea is to use stack data structure. Push all the linked list nodes data value to stack and pop first K elements and print them.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node* next;
};
Node* getNode( int data)
{
Node* newNode = new Node;
newNode->data = data;
newNode->next = NULL;
return newNode;
}
void printLastKRev(Node* head, int k)
{
if (!head)
return ;
stack< int > st;
while (head) {
st.push(head->data);
head = head->next;
}
int cnt = 0;
while (cnt < k) {
cout << st.top() << " " ;
st.pop();
cnt++;
}
}
int main()
{
Node* head = getNode(1);
head->next = getNode(2);
head->next->next = getNode(3);
head->next->next->next = getNode(4);
head->next->next->next->next = getNode(5);
int k = 4;
printLastKRev(head, k);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static class Node
{
int data;
Node next;
};
static Node getNode( int data)
{
Node newNode = new Node();
newNode.data = data;
newNode.next = null ;
return newNode;
}
static void printLastKRev(Node head, int k)
{
if (head == null )
return ;
Stack<Integer> st = new Stack<Integer>();
while (head != null )
{
st.push(head.data);
head = head.next;
}
int cnt = 0 ;
while (cnt < k)
{
System.out.print(st.peek() + " " );
st.pop();
cnt++;
}
}
public static void main(String[] args)
{
Node head = getNode( 1 );
head.next = getNode( 2 );
head.next.next = getNode( 3 );
head.next.next.next = getNode( 4 );
head.next.next.next.next = getNode( 5 );
int k = 4 ;
printLastKRev(head, k);
}
}
|
Python3
import sys
import math
class Node:
def __init__( self ,data):
self .data = data
self . next = None
def getNode(data):
return Node(data)
def printLastKRev(head,k):
if not head:
return
stack = []
while (head):
stack.append(head.data)
head = head. next
cnt = 0
while (cnt < k):
print ( "{} " . format (stack[ - 1 ]),end = "")
stack.pop()
cnt + = 1
if __name__ = = '__main__' :
head = getNode( 1 )
head. next = getNode( 2 )
head. next . next = getNode( 3 )
head. next . next . next = getNode( 4 )
head. next . next . next . next = getNode( 5 )
k = 4
printLastKRev(head,k)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
public class Node
{
public int data;
public Node next;
};
static Node getNode( int data)
{
Node newNode = new Node();
newNode.data = data;
newNode.next = null ;
return newNode;
}
static void printLastKRev(Node head, int k)
{
if (head == null )
return ;
Stack< int > st = new Stack< int >();
while (head != null )
{
st.Push(head.data);
head = head.next;
}
int cnt = 0;
while (cnt < k)
{
Console.Write(st.Peek() + " " );
st.Pop();
cnt++;
}
}
public static void Main(String[] args)
{
Node head = getNode(1);
head.next = getNode(2);
head.next.next = getNode(3);
head.next.next.next = getNode(4);
head.next.next.next.next = getNode(5);
int k = 4;
printLastKRev(head, k);
}
}
|
Javascript
<script>
class Node {
constructor(val) {
this .data = val;
this .next = null ;
}
}
function getNode(data) {
var newNode = new Node();
newNode.data = data;
newNode.next = null ;
return newNode;
}
function printLastKRev(head , k) {
if (head == null )
return ;
var st = [];
while (head != null ) {
st.push(head.data);
head = head.next;
}
var cnt = 0;
while (cnt < k) {
document.write(st.pop() + " " );
cnt++;
}
}
var head = getNode(1);
head.next = getNode(2);
head.next.next = getNode(3);
head.next.next.next = getNode(4);
head.next.next.next.next = getNode(5);
var k = 4;
printLastKRev(head, k);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
The auxiliary space of the above approach can be reduced to O(k). The idea is to use two pointers. Place first pointer to beginning of the list and move second pointer to k-th node form beginning. Then find k-th node from end using approach discussed in this article: Find kth node from end of linked list. After finding kth node from end push all the remaining nodes in the stack. Pop all elements one by one from stack and print them.
Below is the implementation of the above efficient approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node* next;
};
Node* getNode( int data)
{
Node* newNode = new Node;
newNode->data = data;
newNode->next = NULL;
return newNode;
}
void printLastKRev(Node* head, int k)
{
if (!head)
return ;
stack< int > st;
Node *first = head, *sec = head;
int cnt = 0;
while (cnt < k) {
sec = sec->next;
cnt++;
}
while (sec) {
first = first->next;
sec = sec->next;
}
while (first) {
st.push(first->data);
first = first->next;
}
while (!st.empty()) {
cout << st.top() << " " ;
st.pop();
}
}
int main()
{
Node* head = getNode(1);
head->next = getNode(2);
head->next->next = getNode(3);
head->next->next->next = getNode(4);
head->next->next->next->next = getNode(5);
int k = 4;
printLastKRev(head, k);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static class Node
{
int data;
Node next;
};
static Node getNode( int data)
{
Node newNode = new Node();
newNode.data = data;
newNode.next = null ;
return newNode;
}
static void printLastKRev(Node head, int k)
{
if (head == null )
return ;
Stack<Integer> st = new Stack<Integer>();
Node first = head, sec = head;
int cnt = 0 ;
while (cnt < k)
{
sec = sec.next;
cnt++;
}
while (sec != null )
{
first = first.next;
sec = sec.next;
}
while (first != null )
{
st.push(first.data);
first = first.next;
}
while (!st.empty())
{
System.out.print(st.peek() + " " );
st.pop();
}
}
public static void main(String[] args)
{
Node head = getNode( 1 );
head.next = getNode( 2 );
head.next.next = getNode( 3 );
head.next.next.next = getNode( 4 );
head.next.next.next.next = getNode( 5 );
int k = 4 ;
printLastKRev(head, k);
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self . next = None
def getNode(data):
newNode = Node( 0 )
newNode.data = data
newNode. next = None
return newNode
def printLastKRev( head, k):
if (head = = None ):
return
st = []
first = head
sec = head
cnt = 0
while (cnt < k) :
sec = sec. next
cnt = cnt + 1
while (sec ! = None ):
first = first. next
sec = sec. next
while (first ! = None ):
st.append(first.data)
first = first. next
while ( len (st)):
print ( st[ - 1 ], end = " " )
st.pop()
head = getNode( 1 )
head. next = getNode( 2 )
head. next . next = getNode( 3 )
head. next . next . next = getNode( 4 )
head. next . next . next . next = getNode( 5 )
k = 4
printLastKRev(head, k)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
class Node
{
public int data;
public Node next;
};
static Node getNode( int data)
{
Node newNode = new Node();
newNode.data = data;
newNode.next = null ;
return newNode;
}
static void printLastKRev(Node head, int k)
{
if (head == null )
return ;
Stack< int > st = new Stack< int >();
Node first = head, sec = head;
int cnt = 0;
while (cnt < k)
{
sec = sec.next;
cnt++;
}
while (sec != null )
{
first = first.next;
sec = sec.next;
}
while (first != null )
{
st.Push(first.data);
first = first.next;
}
while (st.Count != 0)
{
Console.Write(st.Peek() + " " );
st.Pop();
}
}
public static void Main(String[] args)
{
Node head = getNode(1);
head.next = getNode(2);
head.next.next = getNode(3);
head.next.next.next = getNode(4);
head.next.next.next.next = getNode(5);
int k = 4;
printLastKRev(head, k);
}
}
|
Javascript
<script>
class Node {
constructor() {
this .data = 0;
this .next = null ;
}
}
function getNode(data) {
var newNode = new Node();
newNode.data = data;
newNode.next = null ;
return newNode;
}
function printLastKRev(head, k) {
if (head == null ) return ;
var st = [];
var first = head,
sec = head;
var cnt = 0;
while (cnt < k) {
sec = sec.next;
cnt++;
}
while (sec != null ) {
first = first.next;
sec = sec.next;
}
while (first != null ) {
st.push(first.data);
first = first.next;
}
while (st.length != 0) {
document.write(st[st.length - 1] + " " );
st.pop();
}
}
var head = getNode(1);
head.next = getNode(2);
head.next.next = getNode(3);
head.next.next.next = getNode(4);
head.next.next.next.next = getNode(5);
var k = 4;
printLastKRev(head, k);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(k)
Approach-2:
- Count the number of nodes in the linked list.
- Declare an array with the number of nodes as its size.
- Start storing the value of nodes of the linked list from the end of the array i.e. reverse manner.
- Print k values from starting of the array.
C++
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
Node* getNode( int data){
Node* newNode = new Node;
newNode->data = data;
newNode->next = NULL;
return newNode;
}
void printLastKRev(Node* head,
int & count, int k) {
struct Node* cur = head;
while (cur != NULL){
count++;
cur = cur->next;
}
int arr[count], temp = count;
cur = head;
while (cur != NULL){
arr[--temp] = cur->data;
cur = cur->next;
}
for ( int i = 0; i < k; i++)
cout << arr[i] << " " ;
}
int main()
{
Node* head = getNode(1);
head->next = getNode(2);
head->next->next = getNode(3);
head->next->next->next = getNode(4);
head->next->next->next->next = getNode(5);
head->next->next->next->next->next = getNode(10);
int k = 4, count = 0;
printLastKRev(head, count, k);
return 0;
}
|
Java
class GFG
{
static class Node
{
int data;
Node next;
};
static Node getNode( int data)
{
Node newNode = new Node();
newNode.data = data;
newNode.next = null ;
return newNode;
}
static void printLastKRev(Node head,
int count, int k)
{
Node cur = head;
while (cur != null )
{
count++;
cur = cur.next;
}
int []arr = new int [count];
int temp = count;
cur = head;
while (cur != null )
{
arr[--temp] = cur.data;
cur = cur.next;
}
for ( int i = 0 ; i < k; i++)
System.out.print(arr[i] + " " );
}
public static void main(String[] args)
{
Node head = getNode( 1 );
head.next = getNode( 2 );
head.next.next = getNode( 3 );
head.next.next.next = getNode( 4 );
head.next.next.next.next = getNode( 5 );
head.next.next.next.next.next = getNode( 10 );
int k = 4 , count = 0 ;
printLastKRev(head, count, k);
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self . next = None
def getNode(data):
newNode = Node(data)
return newNode
def printLastKRev(head, count,k):
cur = head;
while (cur ! = None ):
count + = 1
cur = cur. next ;
arr = [ 0 for i in range (count)]
temp = count;
cur = head;
while (cur ! = None ):
temp - = 1
arr[temp] = cur.data;
cur = cur. next ;
for i in range (k):
print (arr[i], end = ' ' )
if __name__ = = '__main__' :
head = getNode( 1 );
head. next = getNode( 2 );
head. next . next = getNode( 3 );
head. next . next . next = getNode( 4 );
head. next . next . next . next = getNode( 5 );
head. next . next . next . next . next = getNode( 10 );
k = 4
count = 0 ;
printLastKRev(head, count, k);
|
C#
using System;
class GFG
{
class Node
{
public int data;
public Node next;
};
static Node getNode( int data)
{
Node newNode = new Node();
newNode.data = data;
newNode.next = null ;
return newNode;
}
static void printLastKRev(Node head,
int count, int k)
{
Node cur = head;
while (cur != null )
{
count++;
cur = cur.next;
}
int []arr = new int [count];
int temp = count;
cur = head;
while (cur != null )
{
arr[--temp] = cur.data;
cur = cur.next;
}
for ( int i = 0; i < k; i++)
Console.Write(arr[i] + " " );
}
public static void Main(String[] args)
{
Node head = getNode(1);
head.next = getNode(2);
head.next.next = getNode(3);
head.next.next.next = getNode(4);
head.next.next.next.next = getNode(5);
head.next.next.next.next.next = getNode(10);
int k = 4, count = 0;
printLastKRev(head, count, k);
}
}
|
Javascript
<script>
class Node {
constructor() {
this .data = 0;
this .next = null ;
}
}
function getNode( data)
{
var newNode = new Node();
newNode.data = data;
newNode.next = null ;
return newNode;
}
function printLastKRev( head, count, k)
{
var cur = head;
while (cur != null )
{
count++;
cur = cur.next;
}
let arr = new Array(count);
let temp = count;
cur = head;
while (cur != null )
{
arr[--temp] = cur.data;
cur = cur.next;
}
for (let i = 0; i < k; i++)
document.write(arr[i] + " " );
}
var head = getNode(1);
head.next = getNode(2);
head.next.next = getNode(3);
head.next.next.next = getNode(4);
head.next.next.next.next = getNode(5);
head.next.next.next.next.next = getNode(10);
let k = 4, count = 0;
printLastKRev(head, count, k);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Approach-3: The idea is to first reverse the linked list iteratively as discussed in following post: Reverse a linked list. After reversing print first k nodes of the reversed list. After printing restore the list by reversing the list again.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node* next;
};
Node* getNode( int data)
{
Node* newNode = new Node;
newNode->data = data;
newNode->next = NULL;
return newNode;
}
Node* reverseLL(Node* head)
{
if (!head || !head->next)
return head;
Node *prev = NULL, *next = NULL, *curr = head;
while (curr) {
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
void printLastKRev(Node* head, int k)
{
if (!head)
return ;
head = reverseLL(head);
Node* curr = head;
int cnt = 0;
while (cnt < k) {
cout << curr->data << " " ;
cnt++;
curr = curr->next;
}
head = reverseLL(head);
}
int main()
{
Node* head = getNode(1);
head->next = getNode(2);
head->next->next = getNode(3);
head->next->next->next = getNode(4);
head->next->next->next->next = getNode(5);
int k = 4;
printLastKRev(head, k);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static class Node
{
int data;
Node next;
};
static Node getNode( int data)
{
Node newNode = new Node();
newNode.data = data;
newNode.next = null ;
return newNode;
}
static Node reverseLL(Node head)
{
if (head == null || head.next == null )
return head;
Node prev = null , next = null , curr = head;
while (curr != null )
{
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
static void printLastKRev(Node head, int k)
{
if (head == null )
return ;
head = reverseLL(head);
Node curr = head;
int cnt = 0 ;
while (cnt < k)
{
System.out.print(curr.data + " " );
cnt++;
curr = curr.next;
}
head = reverseLL(head);
}
public static void main(String[] args)
{
Node head = getNode( 1 );
head.next = getNode( 2 );
head.next.next = getNode( 3 );
head.next.next.next = getNode( 4 );
head.next.next.next.next = getNode( 5 );
int k = 4 ;
printLastKRev(head, k);
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self . next = None
def getNode(data):
newNode = Node(data)
return newNode
def reverseLL(head):
if ( not head or not head. next ):
return head
prev = None
next = None
curr = head;
while (curr):
next = curr. next
curr. next = prev
prev = curr
curr = next
return prev
def printLastKRev(head, k):
if ( not head):
return
head = reverseLL(head)
curr = head
cnt = 0
while (cnt < k):
print (curr.data, end = ' ' )
cnt + = 1
curr = curr. next
head = reverseLL(head)
if __name__ = = '__main__' :
head = getNode( 1 )
head. next = getNode( 2 )
head. next . next = getNode( 3 )
head. next . next . next = getNode( 4 )
head. next . next . next . next = getNode( 5 )
k = 4
printLastKRev(head, k)
|
C#
using System;
class GFG
{
public class Node
{
public int data;
public Node next;
};
static Node getNode( int data)
{
Node newNode = new Node();
newNode.data = data;
newNode.next = null ;
return newNode;
}
static Node reverseLL(Node head)
{
if (head == null || head.next == null )
return head;
Node prev = null , next = null , curr = head;
while (curr != null )
{
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
static void printLastKRev(Node head, int k)
{
if (head == null )
return ;
head = reverseLL(head);
Node curr = head;
int cnt = 0;
while (cnt < k)
{
Console.Write(curr.data + " " );
cnt++;
curr = curr.next;
}
head = reverseLL(head);
}
public static void Main(String[] args)
{
Node head = getNode(1);
head.next = getNode(2);
head.next.next = getNode(3);
head.next.next.next = getNode(4);
head.next.next.next.next = getNode(5);
int k = 4;
printLastKRev(head, k);
}
}
|
Javascript
<script>
class Node
{
constructor()
{
this .data = 0;
this .next = null ;
}
}
function getNode(data)
{
let newNode = new Node();
newNode.data = data;
newNode.next = null ;
return newNode;
}
function reverseLL(head)
{
if (head == null || head.next == null )
return head;
let prev = null , next = null , curr = head;
while (curr != null )
{
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
function printLastKRev(head,k)
{
if (head == null )
return ;
head = reverseLL(head);
let curr = head;
let cnt = 0;
while (cnt < k)
{
document.write(curr.data + " " );
cnt++;
curr = curr.next;
}
head = reverseLL(head);
}
let head = getNode(1);
head.next = getNode(2);
head.next.next = getNode(3);
head.next.next.next = getNode(4);
head.next.next.next.next = getNode(5);
let k = 4;
printLastKRev(head, k);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!