Open In App

Permutation of a Linked List

Last Updated : 06 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given a singly linked list of distinct integers, the task is to generate all possible permutations of the linked list elements.

Examples:

Input: Linked List: 1 -> 2 -> 3
Output:

  • 1 -> 2 -> 3
  • 1 -> 3 -> 2
  • 2 -> 1 -> 3
  • 2 -> 3 -> 1
  • 3 -> 1 -> 2
  • 3 -> 2 -> 1

Input: Linked List: 3 -> 5 -> 7 -> 9
Output:

  • 3 -> 5 -> 7 -> 9
  • 3 -> 5 -> 9 -> 7
  • 3 -> 7 -> 5 -> 9
  • 3 -> 7 -> 9 -> 5
  • 3 -> 9 -> 5 -> 7
  • 3 -> 9 -> 7 -> 5
  • 5 -> 3 -> 7 -> 9
  • 5 -> 3 -> 9 -> 7
  • 5 -> 7 -> 3 -> 9
  • 5 -> 7 -> 9 -> 3
  • 5 -> 9 -> 3 -> 7
  • 5 -> 9 -> 7 -> 3
  • 7 -> 3 -> 5 -> 9
  • 7 -> 3 -> 9 -> 5
  • 7 -> 5 -> 3 -> 9
  • 7 -> 5 -> 9 -> 3
  • 7 -> 9 -> 3 -> 5
  • 7 -> 9 -> 5 -> 3
  • 9 -> 3 -> 5 -> 7
  • 9 -> 3 -> 7 -> 5
  • 9 -> 5 -> 3 -> 7
  • 9 -> 5 -> 7 -> 3
  • 9 -> 7 -> 3 -> 5
  • 9 -> 7 -> 5 -> 3

Approach: To solve the problem follow the below idea:

The provided code generates permutations of a linked list by iteratively swapping elements using a recursive approach. It starts with the first element and swaps it with subsequent elements to create various permutations, effectively exploring all possible orderings. The use of a dummy head node simplifies the storage of each permutation. When the end of the list is reached (base case), a complete permutation is stored, and the code backtracks to explore the remaining permutations.

Steps of the approach:

  • Define a function swap for swapping two integers and a function swapNodes for swapping data within the linked list nodes.
  • Define a recursive function permutations to generate permutations.
  • The function takes a vector to store permutations (res), the current linked list (head), and the current node (current) to consider for swapping.
  • The base case is reached when current becomes nullptr.
  • In the base case, create a new linked list (using a dummy head node) to store the permutation. This involves iterating through the head linked list and copying its elements to the new linked list.
  • Add the newly generated linked list (the permutation) to the res vector.
  • The function then backtracks to the previous state by swapping elements back to their original positions, exploring other permutations.
  • Continue this process by iterating through all possible elements to consider for swapping.
  • Define a function permuteLinkedList that initializes an empty vector for permutations and calls the permutations function with the original linked list.

Below is the implementation:

C++




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
 
struct Node {
    int data;
    Node* next;
    Node(int val)
        : data(val)
        , next(nullptr)
    {
    }
};
 
void swap(int& x, int& y)
{
    int temp = x;
    x = y;
    y = temp;
}
 
void swapNodes(Node* a, Node* b) { swap(a->data, b->data); }
 
void printLinkedList(Node* head)
{
    while (head) {
        cout << head->data;
        if (head->next) {
            cout << " -> ";
        }
        head = head->next;
    }
    cout << " -> nullptr" << endl;
}
 
void permutations(vector<Node*>& res, Node* head,
                  Node* current)
{
    if (!current) {
 
        // Create a dummy head to store
        // the permutation
        Node* newHead = new Node(-1);
        Node* tail = newHead;
        Node* temp = head;
        while (temp) {
            tail->next = new Node(temp->data);
            tail = tail->next;
            temp = temp->next;
        }
        res.push_back(newHead->next);
        delete newHead;
        return;
    }
 
    Node* temp = current;
    while (temp) {
        swapNodes(current, temp);
        permutations(res, head, current->next);
 
        // Backtrack
        swapNodes(current, temp);
        temp = temp->next;
    }
}
 
vector<Node*> permuteLinkedList(Node* head)
{
    vector<Node*> res;
    permutations(res, head, head);
    return res;
}
 
// Drivers code
int main()
{
    Node* head = new Node(1);
    head->next = new Node(2);
    head->next->next = new Node(3);
 
    vector<Node*> res = permuteLinkedList(head);
 
    for (auto linkedList : res) {
        printLinkedList(linkedList);
    }
 
    // Clean up memory
    for (Node* linkedList : res) {
        Node* current = linkedList;
        while (current) {
            Node* temp = current;
            current = current->next;
            delete temp;
        }
    }
 
    return 0;
}


Java




import java.util.ArrayList;
import java.util.List;
 
class Node {
    int data;
    Node next;
 
    public Node(int val) {
        data = val;
        next = null;
    }
}
 
public class LinkedListPermutations {
 
    // Function to swap two elements in an integer array
    private static void swap(int[] arr, int x, int y) {
        int temp = arr[x];
        arr[x] = arr[y];
        arr[y] = temp;
    }
 
    // Function to swap data of two linked list nodes
    private static void swapNodes(Node a, Node b) {
        int temp = a.data;
        a.data = b.data;
        b.data = temp;
    }
 
    // Function to print the linked list
    private static void printLinkedList(Node head) {
        while (head != null) {
            System.out.print(head.data);
            if (head.next != null) {
                System.out.print(" -> ");
            }
            head = head.next;
        }
        System.out.println(" -> null");
    }
 
    // Function to generate permutations of a linked list
    private static void permutations(List<Node> res, Node head, Node current) {
        if (current == null) {
            // If the current node is null, create a new linked list as a permutation
            Node newHead = new Node(-1); // Create a dummy head for the new linked list
            Node tail = newHead;
            Node temp = head; // Iterate through the original linked list
            while (temp != null) {
                // Copy each element to the new linked list
                tail.next = new Node(temp.data);
                tail = tail.next;
                temp = temp.next;
            }
            res.add(newHead.next); // Add the new permutation to the result list
        } else {
            Node temp = current;
            while (temp != null) {
                swapNodes(current, temp); // Swap the data of two nodes
                permutations(res, head, current.next); // Recursively generate permutations
                swapNodes(current, temp); // Backtrack by swapping the nodes back
                temp = temp.next;
            }
        }
    }
 
    // Function to find all permutations of a linked list
    private static List<Node> permuteLinkedList(Node head) {
        List<Node> res = new ArrayList<>();
        permutations(res, head, head);
        return res;
    }
 
    public static void main(String[] args) {
        Node head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);
 
        // Find all permutations of the linked list
        List<Node> res = permuteLinkedList(head);
 
        // Print each permutation
        for (Node linkedList : res) {
            printLinkedList(linkedList);
        }
 
        
    }
}


Python3




class Node:
    def __init__(self, val):
        self.data = val
        self.next = None
 
# Function to swap data of two linked list nodes
def swap_nodes(a, b):
    temp = a.data
    a.data = b.data
    b.data = temp
 
# Function to print the linked list
def print_linked_list(head):
    while head:
        print(head.data, end="")
        if head.next:
            print(" -> ", end="")
        head = head.next
    print(" -> null")
 
# Function to generate permutations of a linked list
def permutations(res, head, current):
    if current is None:
        # If the current node is None, create a new linked list as a permutation
        new_head = Node(-1# Create a dummy head for the new linked list
        tail = new_head
        temp = head  # Iterate through the original linked list
        while temp:
            # Copy each element to the new linked list
            tail.next = Node(temp.data)
            tail = tail.next
            temp = temp.next
        res.append(new_head.next# Add the new permutation to the result list
    else:
        temp = current
        while temp:
            swap_nodes(current, temp)  # Swap the data of two nodes
            permutations(res, head, current.next# Recursively generate permutations
            swap_nodes(current, temp)  # Backtrack by swapping the nodes back
            temp = temp.next
 
# Function to find all permutations of a linked list
def permute_linked_list(head):
    res = []
    permutations(res, head, head)
    return res
 
if __name__ == "__main__":
    head = Node(1)
    head.next = Node(2)
    head.next.next = Node(3)
 
    # Find all permutations of the linked list
    res = permute_linked_list(head)
 
    # Print each permutation
    for linked_list in res:
        print_linked_list(linked_list)


C#




using System;
using System.Collections.Generic;
 
public class Node
{
    public int data;
    public Node next;
 
    public Node(int val)
    {
        data = val;
        next = null;
    }
}
 
public class LinkedListPermutations
{
    // Function to swap two elements in an integer array
    private static void Swap(int[] arr, int x, int y)
    {
        int temp = arr[x];
        arr[x] = arr[y];
        arr[y] = temp;
    }
 
    // Function to swap data of two linked list nodes
    private static void SwapNodes(Node a, Node b)
    {
        int temp = a.data;
        a.data = b.data;
        b.data = temp;
    }
 
    // Function to print the linked list
    private static void PrintLinkedList(Node head)
    {
        while (head != null)
        {
            Console.Write(head.data);
            if (head.next != null)
            {
                Console.Write(" -> ");
            }
            head = head.next;
        }
        Console.WriteLine(" -> null");
    }
 
    // Function to generate permutations of a linked list
    private static void Permutations(List<Node> res, Node head, Node current)
    {
        if (current == null)
        {
            // If the current node is null, create a new linked list as a permutation
            Node newHead = new Node(-1); // Create a dummy head for the new linked list
            Node tail = newHead;
            Node temp = head; // Iterate through the original linked list
            while (temp != null)
            {
                // Copy each element to the new linked list
                tail.next = new Node(temp.data);
                tail = tail.next;
                temp = temp.next;
            }
            res.Add(newHead.next); // Add the new permutation to the result list
        }
        else
        {
            Node temp = current;
            while (temp != null)
            {
                SwapNodes(current, temp); // Swap the data of two nodes
                Permutations(res, head, current.next); // Recursively generate permutations
                SwapNodes(current, temp); // Backtrack by swapping the nodes back
                temp = temp.next;
            }
        }
    }
 
    // Function to find all permutations of a linked list
    private static List<Node> PermuteLinkedList(Node head)
    {
        List<Node> res = new List<Node>();
        Permutations(res, head, head);
        return res;
    }
 
    public static void Main(string[] args)
    {
        Node head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);
 
        // Find all permutations of the linked list
        List<Node> res = PermuteLinkedList(head);
 
        // Print each permutation
        foreach (Node linkedList in res)
        {
            PrintLinkedList(linkedList);
        }
    }
}


Javascript




class Node {
    constructor(val) {
        this.data = val;
        this.next = null;
    }
}
 
// Function to swap two elements in an integer array
function swap(arr, x, y) {
    let temp = arr[x];
    arr[x] = arr[y];
    arr[y] = temp;
}
 
// Function to swap data of two linked list nodes
function swapNodes(a, b) {
    let temp = a.data;
    a.data = b.data;
    b.data = temp;
}
 
// Function to print the linked list
function printLinkedList(head) {
    while (head !== null) {
        process.stdout.write(head.data.toString());
        if (head.next !== null) {
            process.stdout.write(" -> ");
        }
        head = head.next;
    }
    console.log(" -> null");
}
 
// Function to generate permutations of a linked list
function permutations(res, head, current) {
    if (current === null) {
        // If the current node is null, create a new linked list as a permutation
        let newHead = new Node(-1); // Create a dummy head for the new linked list
        let tail = newHead;
        let temp = head; // Iterate through the original linked list
        while (temp !== null) {
            // Copy each element to the new linked list
            tail.next = new Node(temp.data);
            tail = tail.next;
            temp = temp.next;
        }
        res.push(newHead.next); // Add the new permutation to the result list
    } else {
        let temp = current;
        while (temp !== null) {
            swapNodes(current, temp); // Swap the data of two nodes
            permutations(res, head, current.next); // Recursively generate permutations
            swapNodes(current, temp); // Backtrack by swapping the nodes back
            temp = temp.next;
        }
    }
}
 
// Function to find all permutations of a linked list
function permuteLinkedList(head) {
    let res = [];
    permutations(res, head, head);
    return res;
}
 
// Main function
function main() {
    let head = new Node(1);
    head.next = new Node(2);
    head.next.next = new Node(3);
 
    // Find all permutations of the linked list
    let res = permuteLinkedList(head);
 
    // Print each permutation
    for (let linkedList of res) {
        printLinkedList(linkedList);
    }
}
 
// Calling the main function
main();


Output

1 -> 2 -> 3 -> nullptr
1 -> 3 -> 2 -> nullptr
2 -> 1 -> 3 -> nullptr
2 -> 3 -> 1 -> nullptr
3 -> 2 -> 1 -> nullptr
3 -> 1 -> 2 -> nullptr








Time complexity: O(N*N!): The time complexity is O(N * N!) where N is the number of elements in the linked list. This is because there are N! permutations to be generated, and for each permutation, it takes O(N) time to create a copy of the linked list.
Auxiliary Space: O(N!): The space complexity is O(N!) because we store N! permutations in the res vector, each of which requires O(N) space to store a copy of the linked list.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads