Find the element in a linked list with frequency at least N/3

Given a linked list of size N consisting of a string as node value, the task is to find the majority string, having frequency greater than [N/3], in the linked list.
Note: It is guaranteed that there is only one majority string.

Examples:

Input: head -> geeks -> geeks -> abcd -> game -> knight -> geeks -> harry.
Output: geeks.
Explanation:
The frequency of geeks string in link list is 3 which is greater than [7/3] i.e 2.

Input: head -> hot -> hot -> cold -> hot -> hot
Output: hot
Explanation:
The frequency of hot string in the link list is 4 which is greater than [5/3] i.e 1.

Naive Approach:
Store the frequency of every string in a Map. Traverse the map and look for the string whose frequency is ≥ N / 3.
Time Complexity: O(N)
Auxiliary Space: O(N)



Efficient Approach:
The idea is based on Moore’s Voting algorithm.
Find two candidates and check if any of these two candidates is actually a majority element or not.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find an
// element with frequency
// of at least N / 3
// in a linked list
  
#include <bits/stdc++.h>
using namespace std;
  
// Structure of a node
// for the linked list
struct node {
    string i;
    node* next = NULL;
};
  
// Utility function to
// create a node
struct node* newnode(string s)
{
    struct node* temp = (struct node*)
        malloc(sizeof(struct node));
    temp->i = s;
    temp->next = NULL;
    return temp;
}
  
// Function to find and return
// the element with frequency
// of at least N/3
string Majority_in_linklist(node* head)
{
    // Candidates for
    // being the required
    // majority element
    string s = "", t = "";
  
    // Store the frequencies
    // of the respective candidates
    int p = 0, q = 0;
    node* ptr = NULL;
  
    // Iterate all nodes
    while (head != NULL) {
        if (s.compare(head->i) == 0) {
            // Increase frequency
            // of candidate s
            p = p + 1;
        }
        else {
            if (t.compare(head->i) == 0) {
                // Increase frequency
                // of candidate t
                q = q + 1;
            }
            else {
                if (p == 0) {
                    // Set the new sting as
                    // candidate for majority
                    s = head->i;
                    p = 1;
                }
                else {
                    if (q == 0) {
                        // Set the new sting as
                        // second candidate
                        // for majority
                        t = head->i;
                        q = 1;
                    }
                    else {
                        // Decrease the frequency
                        p = p - 1;
                        q = q - 1;
                    }
                }
            }
        }
        head = head->next;
    }
    head = ptr;
    p = 0;
    q = 0;
  
    // Check the frequency of two
    // final selected candidate linklist
    while (head != NULL) {
        if (s.compare(head->i) == 0) {
            // Increase the frequency
            // of first candidate
            p = 1;
        }
        else {
            if (t.compare(head->i) == 0) {
                // Increase the frequency
                // of second candidate
                q = 1;
            }
        }
        head = head->next;
    }
    // Return the string with
    // higher frequency
    if (p > q) {
        return s;
    }
    else {
        return t;
    }
}
// Driver Code
int main()
{
    node* ptr = NULL;
    node* head = newnode("geeks");
    head->next = newnode("geeks");
    head->next->next = newnode("abcd");
    head->next->next->next
        = newnode("game");
    head->next->next->next->next
        = newnode("game");
    head->next->next->next->next->next
        = newnode("knight");
    head->next->next->next->next->next->next
        = newnode("harry");
    head->next->next->next->next->next->next
        ->next
        = newnode("geeks");
  
    cout << Majority_in_linklist(head) << endl;
  
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find an element
# with frequency of at least N / 3 
# in a linked list 
  
# Structure of a node 
# for the linked list
class Node:
    def __init__(self, s):
          
        self.i = s
        self.next = None
          
# Function to find and return 
# the element with frequency 
# of at least N/3 
def Majority_in_linklist(head):
      
    # Candidates for 
    # being the required 
    # majority element 
    s, t = "", ""
      
    # Store the frequencies 
    # of the respective candidates 
    p, q = 0, 0
    ptr = None
      
    # Iterate all nodes
    while head != None:
        if s == head.i:
              
            # Increase frequency 
            # of candidate s 
            p = p + 1
        else:
            if t == head.i:
                  
                # Increase frequency 
                # of candidate t 
                q = q + 1
            else:
                if p == 0:
                      
                    # Set the new sting as 
                    # candidate for majority 
                    s = head.i
                    p = 1
                else:
                    if q == 0:
                          
                        # Set the new sting as 
                        # second candidate 
                        # for majority
                        t = head.i
                        q = 1
                    else:
                          
                        # Decrease the frequency 
                        p = p - 1
                        q = q - 1
                          
        head = head.next
          
    head = ptr
    p = 0
    q = 0
      
    # Check the frequency of two 
    # final selected candidate linklist 
    while head != None:
        if s == head.i:
              
            # Increase the frequency 
            # of first candidate 
            p = 1
        else:
            if t == head.i:
                  
                # Increase the frequency 
                # of second candidate 
                q = 1
                  
        head = head.next
      
    # Return the string with 
    # higher frequency 
    if p > q:
        return s
    else:
        return t
  
# Driver code
ptr = None
head = Node("geeks"
head.next = Node("geeks"
head.next.next = Node("abcd"
head.next.next.next = Node("game"
head.next.next.next.next = Node("game"
head.next.next.next.next.next = Node("knight"
head.next.next.next.next.next.next = Node("harry"
head.next.next.next.next.next.next.next = Node("geeks"
  
print(Majority_in_linklist(head))
  
# This code is contributed by stutipathak31jan

chevron_right


Output:

geeks

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

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : stutipathak31jan