K most occurring strings
Given an array arr[] of N strings and an integer K, the task is to print K strings which occurred the most number of times in the arr[]. If two or more strings have the same frequency then print the lexicographically smallest string.
Note: The value of K is always less than or equal to the number of distinct elements in the array.
Examples:
Input: str[] = {“geeks”, “geeksforgeeks”, “geeks”, “article”}, K = 1
Output: “geeks”
Explanation:
“geeks” –> 2
“geeksforgeeks” –> 1
“article” –> 1
Hence, the most occurring string is “geeks”Input: str[] = {“car”, “bus”, “car”, “bike”, “car”, “bus”, “bike”, “cycle”}, K = 2
Output : “car”, “bus”
Explanation:
“car” –> 3
“bus” –> 2
“bike” –> 2
“cycle” –> 1
string “car” has highest frequency, string “bus” and “bike” both have second highest frequency, but string “bus” is lexicographically small because it has shorter length.
Approach:
- Count the frequency of each string in the array and store it in a HashMap where the string is the key and frequency as the value.
- Now, sort these keys according to their frequencies in ascending order, this is done to keep keys with the least frequencies at the top.
- The strings with equal frequencies are prioritized alphabetically, i.e., the string which is alphabetically greater has a higher priority.
- Delete the top N – K key-value pairs from the HashMap. By doing this the container is left with K keys with the highest frequencies, in reverse order.
- Print the strings stored in the HashMap.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function that returns list of K // most frequent strings map<string, int > Freq; class compare { public : bool operator()(string& a, string& b) { if (a == b) { return Freq[a] > Freq[b]; } return a > b; } }; vector<string> frequentWords(vector<string> arr, int K) { // Hash map to store the frequency // of each string map<string, int > Freq; // Set the default frequency of // each string 0 for ( auto word : arr) { Freq[word]++; } // Using a priority queue to store // the strings in accordance of the // frequency and alphabetical order // (if frequency is equal) // Lambda expression is used set the // priority, if frequencies are not // equal than the string with greater // frequency is returned else the // string which is lexically smaller // is returned priority_queue<string, vector<string>, compare> Order; // Traverse the HashMap for ( auto it : Freq) { Order.push(it.first); // Remove top (N - K) elements if (Order.size() > K) { Order.pop(); } } // Order queue has K most frequent // strings in a reverse order vector<string> ans; while (Order.size()) { ans.push_back(Order.top()); Order.pop(); } // Reverse the ArrayList so as // to get in the desired order reverse(ans.begin(), ans.end()); return ans; } // Driver Code int main() { int N = 3, K = 2; // Given array vector<string> arr{ "car" , "bus" , "car" }; // Function Call vector<string> ans = frequentWords(arr, K); // Print the K most occurring strings for ( auto it : ans) { cout << it << endl; } } // This code is contributed by garg28harsh. |
Java
// Java program for the above approach import java.util.*; class FrequentWords { // Function that returns list of K // most frequent strings public static ArrayList<String> frequentWords(ArrayList<String> arr, int K) { // Hash map to store the frequency // of each string HashMap<String, Integer> Freq = new HashMap<>(); // Set the default frequency of // each string 0 for (String word : arr) { Freq.put(word, Freq.getOrDefault(word, 0 ) + 1 ); } // Using a priority queue to store // the strings in accordance of the // frequency and alphabetical order // (if frequency is equal) // Lambda expression is used set the // priority, if frequencies are not // equal than the string with greater // frequency is returned else the // string which is lexically smaller // is returned PriorityQueue<String> Order = new PriorityQueue<>( (a, b) -> (Freq.get(a) != Freq.get(b)) ? Freq.get(a) - Freq.get(b) : b.compareTo(a)); // Traverse the HashMap for (String word : Freq.keySet()) { Order.offer(word); // Remove top (N - K) elements if (Order.size() > K) { Order.poll(); } } // Order queue has K most frequent // strings in a reverse order ArrayList<String> ans = new ArrayList<>(); while (!Order.isEmpty()) { ans.add(Order.poll()); } // Reverse the ArrayList so as // to get in the desired order Collections.reverse(ans); return ans; } // Driver Code public static void main(String[] args) { int N = 3 , K = 2 ; // Given array ArrayList<String> arr = new ArrayList<String>(); arr.add( "car" ); arr.add( "bus" ); arr.add( "car" ); // Function Call ArrayList<String> ans = frequentWords(arr, K); // Print the K most occurring strings for (String word : ans) { System.out.println(word + " " ); } } } |
Javascript
<script> // Javascript program for the above approach // Function that returns list of K // most frequent strings function frequentWords(arr, K) { // Hash map to store the frequency // of each string var Freq = new Map(); // Set the default frequency of // each string 0 for ( var word of arr) { Freq.set(word, Freq.has(word)?Freq.get(word):0); } // Using a priority queue to store // the strings in accordance of the // frequency and alphabetical order // (if frequency is equal) // Lambda expression is used set the // priority, if frequencies are not // equal than the string with greater // frequency is returned else the // string which is lexically smaller // is returned var Order = []; // Traverse the HashMap for ( var word of [...Freq.keys()]) { Order.push(word); // Remove top (N - K) elements if (Order.length > K) { Order.pop(); } } // Order queue has K most frequent // strings in a reverse order var ans = []; Order.sort((a,b)=>a[0]-b[0]); while (Order.length!=0) { ans.push(Order[Order.length-1]) Order.pop(); } // Reverse the ArrayList so as // to get in the desired order ans.reverse(); return ans; } // Driver Code var N = 3, K = 2; // Given array var arr = []; arr.push( "car" ); arr.push( "bus" ); arr.push( "car" ); // Function Call var ans = frequentWords(arr, K); // Print the K most occurring strings for ( var word of ans) { document.write(word + "<br>" ); } // This code is contributed by noob2000. </script> |
car bus
Time Complexity: O(N*log2N)
Auxiliary Space: O(N)
Please Login to comment...