Given two singly Linked list of integer data. The task is to write a program that efficiently checks if two linked lists are permutations of each other.
Examples:
Input: 1 -> 2 -> 3 -> 4 -> 5
2 -> 1 -> 3 -> 5 -> 4
Output: Yes
Input: 10 -> 20 -> 30 -> 40
20 -> 50 -> 60 -> 70
Output: No
Approach: Do the following for both linked lists:
- Take a temporary node pointing to the head of the linked list.
- Start traversing through the linked list, and keep sum and multiplications of data of nodes.
Note: After having sum and multiplication of both linked list, check if sum and multiplication of both linked lists are equal. If they are equal, it means linked lists are permutations of each other, else not.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node* next;
};
bool isPermutation( struct Node* first, struct Node* second)
{
int sum1 = 0, sum2 = 0, mul1 = 1, mul2 = 1;
struct Node* temp1 = first;
while (temp1 != NULL) {
sum1 += temp1->data;
mul1 *= temp1->data;
temp1 = temp1->next;
}
struct Node* temp2 = second;
while (temp2 != NULL) {
sum2 += temp2->data;
mul2 *= temp2->data;
temp2 = temp2->next;
}
return ((sum1 == sum2) && (mul1 == mul2));
}
void push( struct Node** head_ref, int new_data)
{
struct Node* new_node = ( struct Node*) malloc ( sizeof ( struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
int main()
{
struct Node* first = NULL;
push(&first, 1);
push(&first, 34);
push(&first, 10);
push(&first, 1);
push(&first, 35);
push(&first, 12);
struct Node* second = NULL;
push(&second, 35);
push(&second, 1);
push(&second, 12);
push(&second, 1);
push(&second, 10);
push(&second, 34);
if (isPermutation(first, second)) {
cout << "Yes" << endl;
}
else {
cout << "No" << endl;
}
return 0;
}
|
Java
import java.util.*;
class GFG
{
static class Node
{
int data;
Node next;
};
static boolean isPermutation(Node first,
Node second)
{
int sum1 = 0 , sum2 = 0 ,
mul1 = 1 , mul2 = 1 ;
Node temp1 = first;
while (temp1 != null )
{
sum1 += temp1.data;
mul1 *= temp1.data;
temp1 = temp1.next;
}
Node temp2 = second;
while (temp2 != null )
{
sum2 += temp2.data;
mul2 *= temp2.data;
temp2 = temp2.next;
}
return ((sum1 == sum2) &&
(mul1 == mul2));
}
static Node push(Node head_ref, int new_data)
{
Node new_node = new Node();
new_node.data = new_data;
new_node.next = head_ref;
head_ref = new_node;
return head_ref;
}
public static void main(String[] args)
{
Node first = null ;
first = push(first, 1 );
first = push(first, 34 );
first = push(first, 10 );
first = push(first, 1 );
first = push(first, 35 );
first = push(first, 12 );
Node second = null ;
second = push(second, 35 );
second = push(second, 1 );
second = push(second, 12 );
second = push(second, 1 );
second = push(second, 10 );
second = push(second, 34 );
if (isPermutation(first, second))
{
System.out.print( "Yes" );
}
else
{
System.out.print( "No" );
}
}
}
|
Python3
class Node:
def __init__( self ):
self .data = 0
self . next = None
def isPermutation(first, second):
sum1 = 0
sum2 = 0
mul1 = 1
mul2 = 1
temp1 = first
while (temp1 ! = None ):
sum1 + = temp1.data
mul1 * = temp1.data
temp1 = temp1. next
temp2 = second
while (temp2 ! = None ):
sum2 + = temp2.data
mul2 * = temp2.data
temp2 = temp2. next
return ((sum1 = = sum2) and (mul1 = = mul2))
def push(head_ref, new_data):
new_node = Node()
new_node.data = new_data
new_node. next = head_ref
head_ref = new_node
return head_ref
if __name__ = = '__main__' :
first = None
first = push(first, 1 )
first = push(first, 34 )
first = push(first, 10 )
first = push(first, 1 )
first = push(first, 35 )
first = push(first, 12 )
second = None
second = push(second, 35 )
second = push(second, 1 )
second = push(second, 12 )
second = push(second, 1 )
second = push(second, 10 )
second = push(second, 34 )
if (isPermutation(first, second)):
print ( "Yes" )
else :
print ( "No" )
|
C#
using System;
class GFG
{
public class Node
{
public int data;
public Node next;
};
static bool isPermutation(Node first,
Node second)
{
int sum1 = 0, sum2 = 0,
mul1 = 1, mul2 = 1;
Node temp1 = first;
while (temp1 != null )
{
sum1 += temp1.data;
mul1 *= temp1.data;
temp1 = temp1.next;
}
Node temp2 = second;
while (temp2 != null )
{
sum2 += temp2.data;
mul2 *= temp2.data;
temp2 = temp2.next;
}
return ((sum1 == sum2) &&
(mul1 == mul2));
}
static Node push(Node head_ref, int new_data)
{
Node new_node = new Node();
new_node.data = new_data;
new_node.next = head_ref;
head_ref = new_node;
return head_ref;
}
public static void Main(String[] args)
{
Node first = null ;
first = push(first, 1);
first = push(first, 34);
first = push(first, 10);
first = push(first, 1);
first = push(first, 35);
first = push(first, 12);
Node second = null ;
second = push(second, 35);
second = push(second, 1);
second = push(second, 12);
second = push(second, 1);
second = push(second, 10);
second = push(second, 34);
if (isPermutation(first, second))
{
Console.Write( "Yes" );
}
else
{
Console.Write( "No" );
}
}
}
|
Javascript
<script>
class Node {
constructor() {
this .data = 0;
this .next = null ;
}
}
function isPermutation(first, second) {
var sum1 = 0,
sum2 = 0,
mul1 = 1,
mul2 = 1;
var temp1 = first;
while (temp1 != null ) {
sum1 += temp1.data;
mul1 *= temp1.data;
temp1 = temp1.next;
}
var temp2 = second;
while (temp2 != null ) {
sum2 += temp2.data;
mul2 *= temp2.data;
temp2 = temp2.next;
}
return sum1 == sum2 && mul1 == mul2;
}
function push(head_ref, new_data) {
var new_node = new Node();
new_node.data = new_data;
new_node.next = head_ref;
head_ref = new_node;
return head_ref;
}
var first = null ;
first = push(first, 1);
first = push(first, 34);
first = push(first, 10);
first = push(first, 1);
first = push(first, 35);
first = push(first, 12);
var second = null ;
second = push(second, 35);
second = push(second, 1);
second = push(second, 12);
second = push(second, 1);
second = push(second, 10);
second = push(second, 34);
if (isPermutation(first, second)) {
document.write( "Yes" );
} else {
document.write( "No" );
}
</script>
|
Complexity Analysis:
- Time Complexity: O(N) where N is the size of linked lists
- Auxiliary Space: O(1) because using constant space
Check if two Linked Lists are permutations of each other using Hashing.
Here’s an approach to check if two linked lists are permutations of each other using a hash table:
- Traverse through both linked lists and store the frequency of each element in a hash table. The hash table can be implemented using an array of size equal to the range of the elements in the linked lists.
- Traverse through both linked lists again and compare the frequency of each element in the hash table. If the frequency is not equal, the linked lists are not permutations of each other.
- If the frequency of all elements is equal, the linked lists are permutations of each other.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node* next;
};
bool arePermutations( struct Node* first, struct Node* second) {
const int range = 1000;
int hash[range] = {0};
struct Node* temp = first;
while (temp != NULL) {
hash[temp->data]++;
temp = temp->next;
}
temp = second;
while (temp != NULL) {
if (hash[temp->data] == 0) {
return false ;
}
hash[temp->data]--;
temp = temp->next;
}
for ( int i = 0; i < range; i++) {
if (hash[i] != 0) {
return false ;
}
}
return true ;
}
void push( struct Node** head_ref, int new_data) {
struct Node* new_node = ( struct Node*) malloc ( sizeof ( struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
int main() {
struct Node* first = NULL;
push(&first, 1);
push(&first, 34);
push(&first, 10);
push(&first, 1);
push(&first, 35);
push(&first, 12);
struct Node* second = NULL;
push(&second, 35);
push(&second, 1);
push(&second, 12);
push(&second, 1);
push(&second, 10);
push(&second, 34);
if (arePermutations(first, second)) {
cout << "Yes" << endl;
}
else {
cout << "No" << endl;
}
return 0;
}
|
Javascript
class Node {
constructor(data) {
this .data = data;
this .next = null ;
}
}
function GFG(first, second) {
const range = 1000;
const hash = Array.from({ length: range }, () => 0);
let temp = first;
while (temp !== null ) {
hash[temp.data]++;
temp = temp.next;
}
temp = second;
while (temp !== null ) {
if (hash[temp.data] === 0) {
return false ;
}
hash[temp.data]--;
temp = temp.next;
}
for (let i = 0; i < range; i++) {
if (hash[i] !== 0) {
return false ;
}
}
return true ;
}
function push(headRef, new_data) {
const new_node = new Node(new_data);
new_node.next = headRef;
headRef = new_node;
return headRef;
}
let first = null ;
first = push(first, 1);
first = push(first, 34);
first = push(first, 10);
first = push(first, 1);
first = push(first, 35);
first = push(first, 12);
let second = null ;
second = push(second, 35);
second = push(second, 1);
second = push(second, 12);
second = push(second, 1);
second = push(second, 10);
second = push(second, 34);
if (GFG(first, second)) {
console.log( "Yes" );
} else {
console.log( "No" );
}
|
Complexity Analysis:
- Time Complexity: O(N) where N is the size of linked lists
- Auxiliary Space: O(1) because using constant space