Open In App

Find anagrams in linked list

Last Updated : 05 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a linked list of characters and a string S. Return all the anagrams of the string present in the given linked list. In case of overlapping anagrams choose the first anagram from the left.

Examples:

Input: a -> b -> c -> a -> d -> b -> c -> a, S = bac
Output: [a -> b -> c, b -> c -> a]
Explanation: In the given linked list, there are three anagrams: 

  • a -> b -> c -> a -> d -> b -> c -> a
  • a -> b -> c -> a -> d -> b -> c -> a
  • a -> b -> c -> a -> d -> b -> c -> a

But in 1 and 2, a -> b -> c and b -> c-> a are overlapping. So we take a -> b -> c as it comes first from left. Here we already calculated elements b and c in the first anagram so we can’t consider it again for anagram 2. So the output is: 
[a -> b -> c, b -> c -> a]

Input: a -> b -> d -> c -> a, S = bac
Output: -1 
Explanation: There are no anagrams, so the output is -1

Approach: This can be solved with the following idea:

Using the sliding window approach and map function to maintain the frequency of the string. Traverse the linked list and check at each point whether it is an anagram or not. 

Steps involved in the implementation of code:

  • Create two maps and in one of them store the frequency of each character.
  • Start traversing the linked list. 
    • When we have traversed the length of string s. Check for an anagram is there or not.
    • If it is, move the head pointer to the end of the tail.
    • If not, move the head pointer by one step.
  • Clear the map at each step.

Below is the implementation of the code:

C++




// C++ code of the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Linked list Structure
struct Node {
    char data;
    struct Node* next;
 
    Node(char x)
    {
        data = x;
        next = NULL;
    }
};
 
// Function to print Linked list stored
// in vector
void printList(Node* node)
{
    while (node != NULL) {
        cout << node->data << " ";
        node = node->next;
    }
    cout << endl;
}
 
// Function to create linked list
struct Node* inputList()
{
 
    // Length of link list
    int n = 8;
 
    char data[]
        = { 'a', 'b', 'c', 'a', 'd', 'b', 'c', 'a' };
    struct Node* head = new Node(data[0]);
    struct Node* tail = head;
    for (int i = 1; i < n; ++i) {
        tail->next = new Node(data[i]);
        tail = tail->next;
    }
    return head;
}
 
class Solution {
public:
    // Function to check whether sublink
    // list and are anagrams or not
    bool anagram(unordered_map<char, int>& smp,
                 unordered_map<char, int>& cmp)
    {
 
        if (smp.size() != cmp.size())
            return false;
 
        for (auto it : smp) {
 
            if (it.second != cmp[it.first]) {
 
                return false;
            }
        }
 
        return true;
    }
 
    // Function to find starting points
    // which are anagrams
    vector<Node*> findAnagrams(struct Node* head, string s)
    {
 
        // code here
        vector<Node*> ans;
 
        Node* prev = NULL;
 
        unordered_map<char, int> smp;
 
        unordered_map<char, int> cmp;
 
        struct Node* curr = head;
 
        int n = s.size();
 
        for (int i = 0; i < n; i++) {
 
            smp[s[i]]++;
        }
 
        while (curr != NULL) {
 
            struct Node* temp = curr;
 
            for (int i = 0; i < n && temp != NULL; i++) {
 
                cmp[temp->data]++;
 
                prev = temp;
 
                temp = temp->next;
            }
 
            // If they both are anagrams
            // of each other
            if (anagram(smp, cmp)) {
 
                prev->next = NULL;
 
                ans.push_back(curr);
 
                curr = temp;
            }
 
            // If not
            else {
 
                curr = curr->next;
            }
 
            cmp.clear();
        }
 
        return ans;
    }
};
 
// Driver code
int main()
{
 
    struct Node* head = inputList();
 
    string s = "bac";
 
    Solution obj;
    vector<Node*> res = obj.findAnagrams(head, s);
 
    for (int i = 0; i < res.size(); i++) {
        printList(res[i]);
    }
 
    if (res.size() == 0)
        cout << "-1\n";
}


Java




// Java code of the above approach
 
import java.io.*;
import java.util.*;
 
// Linked list Node
class Node {
    char data;
    Node next;
 
    Node(char x)
    {
        data = x;
        next = null;
    }
}
 
class Solution {
 
    // Function to check whether sublink list and are
    // anagrams or not
    boolean anagram(HashMap<Character, Integer> smp,
                    HashMap<Character, Integer> cmp)
    {
 
        if (smp.size() != cmp.size())
            return false;
 
        for (Map.Entry<Character, Integer> entry :
             smp.entrySet()) {
 
            char key = entry.getKey();
            int value = entry.getValue();
 
            if (!cmp.containsKey(key)
                || cmp.get(key) != value) {
                return false;
            }
        }
 
        return true;
    }
 
    // Function to find starting points which are anagrams
    List<Node> findAnagrams(Node head, String s)
    {
 
        List<Node> ans = new ArrayList<>();
 
        Node prev = null;
 
        HashMap<Character, Integer> smp = new HashMap<>();
        HashMap<Character, Integer> cmp = new HashMap<>();
 
        Node curr = head;
        int n = s.length();
 
        for (int i = 0; i < n; i++) {
            char c = s.charAt(i);
            smp.put(c, smp.getOrDefault(c, 0) + 1);
        }
 
        while (curr != null) {
            Node temp = curr;
            for (int i = 0; i < n && temp != null; i++) {
                char c = temp.data;
                cmp.put(c, cmp.getOrDefault(c, 0) + 1);
                prev = temp;
                temp = temp.next;
            }
 
            // If they both are anagrams of each other
            if (anagram(smp, cmp)) {
                prev.next = null;
                ans.add(curr);
                curr = temp;
            }
 
            // If not
            else {
                curr = curr.next;
            }
            cmp.clear();
        }
        return ans;
    }
}
 
class GFG {
 
    // Function to print Linked list stored
    // in vector
    static void printList(Node node)
    {
        while (node != null) {
            System.out.print(node.data + " ");
            node = node.next;
        }
        System.out.println();
    }
 
    // Function to create linked list
    static Node inputList()
    {
 
        // Length of link list
        int n = 8;
 
        char[] data
            = { 'a', 'b', 'c', 'a', 'd', 'b', 'c', 'a' };
        Node head = new Node(data[0]);
        Node tail = head;
        for (int i = 1; i < n; ++i) {
            tail.next = new Node(data[i]);
            tail = tail.next;
        }
        return head;
    }
 
    public static void main(String[] args)
    {
        Node head = inputList();
        String s = "bac";
 
        Solution obj = new Solution();
        List<Node> res = obj.findAnagrams(head, s);
 
        for (int i = 0; i < res.size(); i++) {
            printList(res.get(i));
        }
 
        if (res.size() == 0)
            System.out.println("-1");
    }
}
 
// This code is contributed by lokesh.


Python3




# Python 3 code of the above approach
 
# Linked list Structure
class Node:
    def __init__(self, x):
        self.data = x
        self.next = None
 
# Function to print Linked list stored
# in vector
def printList(node):
    while (node != None):
        print(node.data, end=" ")
        node = node.next
    print()
 
# Function to create linked list
def inputList():
 
    # Length of link list
    n = 8
 
    data = ['a', 'b', 'c', 'a', 'd', 'b', 'c', 'a']
    head = Node(data[0])
    tail = head
    for i in range(1, n):
        tail.next = Node(data[i])
        tail = tail.next
    return head
 
class Solution:
    # Function to check whether sublink
    # list and are anagrams or not
    def anagram(self, smp, cmp):
        if len(smp) != len(cmp):
            return False
 
        for k, v in smp.items():
            if cmp.get(k) != v:
                return False
 
        return True
 
    # Function to find starting points
    # which are anagrams
    def findAnagrams(self, head, s):
 
        # code here
        ans = []
 
        prev = None
 
        smp = {}
 
        cmp = {}
 
        curr = head
 
        n = len(s)
 
        for i in range(n):
            if s[i] in smp:
                smp[s[i]] += 1
            else:
                smp[s[i]] = 1
 
        while curr != None:
            temp = curr
 
            for i in range(n):
                if temp == None:
                    break
 
                if temp.data in cmp:
                    cmp[temp.data] += 1
                else:
                    cmp[temp.data] = 1
 
                prev = temp
 
                temp = temp.next
 
            # If they both are anagrams
            # of each other
            if self.anagram(smp, cmp):
 
                prev.next = None
 
                ans.append(curr)
 
                curr = temp
 
            # If not
            else:
 
                curr = curr.next
 
            cmp.clear()
 
        return ans
 
# Driver code
if __name__ == "__main__":
    head = inputList()
 
    s = "bac"
 
    obj = Solution()
    res = obj.findAnagrams(head, s)
 
    for i in range(len(res)):
        printList(res[i])
 
    if len(res) == 0:
        print("-1")
 
#This code is contributed by Akash Jha


Javascript




// Linked list Structure
class Node {
    constructor(x) {
        this.data = x;
        this.next = null;
    }
}
 
// Function to print Linked list stored
// in vector
function printList(node) {
    while (node != null) {
        console.log(node.data + " ");
        node = node.next;
    }
    console.log();
}
 
// Function to create linked list
function inputList() {
 
    // Length of link list
    let n = 8;
 
    let data = ['a', 'b', 'c', 'a', 'd', 'b', 'c', 'a'];
    let head = new Node(data[0]);
    let tail = head;
    for (let i = 1; i < n; ++i) {
        tail.next = new Node(data[i]);
        tail = tail.next;
    }
    return head;
}
 
class Solution {
    // Function to check whether sublink
    // list and are anagrams or not
    anagram(smp, cmp) {
 
        if (Object.keys(smp).length != Object.keys(cmp).length)
            return false;
 
        for (let key in smp) {
 
            if (smp[key] != cmp[key]) {
 
                return false;
            }
        }
 
        return true;
    }
 
    // Function to find starting points
    // which are anagrams
    findAnagrams(head, s) {
 
        let ans = [];
 
        let prev = null;
 
        let smp = {};
 
        let cmp = {};
 
        let curr = head;
 
        let n = s.length;
 
        for (let i = 0; i < n; i++) {
 
            if(s[i] in smp){
                smp[s[i]]++;
            }else{
                smp[s[i]] = 1;
            }
        }
 
        while (curr != null) {
 
            let temp = curr;
 
            for (let i = 0; i < n && temp != null; i++) {
 
                if(temp.data in cmp){
                    cmp[temp.data]++;
                }else{
                    cmp[temp.data] = 1;
                }
 
                prev = temp;
 
                temp = temp.next;
            }
 
            // If they both are anagrams
            // of each other
            if (this.anagram(smp, cmp)) {
 
                prev.next = null;
 
                ans.push(curr);
 
                curr = temp;
            }
 
            // If not
            else {
 
                curr = curr.next;
            }
 
            cmp = {};
        }
 
        return ans;
    }
}
 
// Driver code
function main() {
 
    let head = inputList();
 
    let s = "bac";
 
    let obj = new Solution();
    let res = obj.findAnagrams(head, s);
 
    for (let i = 0; i < res.length; i++) {
        printList(res[i]);
    }
 
    if (res.length == 0)
        console.log("-1");
}
 
main();
 
//This code is contributed by Akash Jha


C#




using System;
using System.Collections.Generic;
 
// Linked list Structure
class Node
{
    public char data;
    public Node next;
 
    public Node(char x)
    {
        data = x;
        next = null;
    }
}
 
// Function to print Linked list stored
// in vector
void printList(Node node)
{
    while (node != null)
    {
        Console.Write(node.data + " ");
        node = node.next;
    }
    Console.WriteLine();
}
 
// Function to create linked list
Node inputList()
{
    // Length of link list
    int n = 8;
 
    char[] data = { 'a', 'b', 'c', 'a', 'd', 'b', 'c', 'a' };
 
    Node head = new Node(data[0]);
    Node tail = head;
    for (int i = 1; i < n; ++i)
    {
        tail.next = new Node(data[i]);
        tail = tail.next;
    }
    return head;
}
 
class Solution
{
    // Function to check whether sublink
    // list and are anagrams or not
    public bool anagram(Dictionary<char, int> smp, Dictionary<char, int> cmp)
    {
        if (smp.Count != cmp.Count)
            return false;
 
        foreach (KeyValuePair<char, int> kvp in smp)
        {
            if (!cmp.ContainsKey(kvp.Key) || cmp[kvp.Key] != kvp.Value)
                return false;
        }
        return true;
    }
 
    // Function to find starting points
    // which are anagrams
    public List<Node> findAnagrams(Node head, string s)
    {
        // code here
        List<Node> ans = new List<Node>();
 
        Node prev = null;
 
        Dictionary<char, int> smp = new Dictionary<char, int>();
 
        Dictionary<char, int> cmp = new Dictionary<char, int>();
 
        Node curr = head;
 
        int n = s.Length;
 
        for (int i = 0; i < n; i++)
        {
            if (!smp.ContainsKey(s[i]))
            {
                smp.Add(s[i], 0);
            }
            smp[s[i]]++;
        }
 
        while (curr != null)
        {
            Node temp = curr;
 
            for (int i = 0; i < n && temp != null; i++)
            {
                if (!cmp.ContainsKey(temp.data))
                {
                    cmp.Add(temp.data, 0);
                }
                cmp[temp.data]++;
 
                prev = temp;
 
                temp = temp.next;
            }
 
            // If they both are anagrams
            // of each other
            if (anagram(smp, cmp))
            {
                prev.next = null;
 
                ans.Add(curr);
 
                curr = temp;
            }
            // If not
            else
            {
                curr = curr.next;
            }
 
            cmp.Clear();
        }
 
        return ans;
    }
}
 
// Driver code
public class Program
{
    public static void Main()
    {
        Node head = inputList();
 
        string s = "bac";
 
        Solution obj = new Solution();
        List<Node> res = obj.findAnagrams(head, s);
 
        for (int i = 0; i < res.Count; i++)
        {
            printList(res[i]);
        }
 
        if (res.Count == 0)
            Console.WriteLine("-1");
    }
}
//This code is contributed by Akash Jha


Output

a b c 
b c a 

Time Complexity: O(N)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads