Below is the implementation of the word frequency analyzer:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168/** * Brute Force Approach * Time Complexity: O(n log n) - Dominated by the sorting operation * Space Complexity: O(n) - For storing the frequency map and result array * * @param {string[]} words - Array of words * @param {number} k - Number of top frequent words to return * @return {string[]} - Top k frequent words */function topKFrequent(words, k) { // Count frequency of each word const freq = new Map(); for (const word of words) { freq.set(word, (freq.get(word) || 0) + 1); } // Create list of all unique words const uniqueWords = Array.from(freq.keys()); // Sort words by frequency (descending) and alphabetically (ascending) uniqueWords.sort((a, b) => { const freqA = freq.get(a); const freqB = freq.get(b); if (freqA !== freqB) { return freqB - freqA; // Sort by frequency in descending order } return a.localeCompare(b); // Sort alphabetically if frequencies are equal }); // Return top k words return uniqueWords.slice(0, k);} /** * Heap (Priority Queue) Approach * Note: JavaScript doesn't have a built-in heap, so we'll implement a simple min heap * Time Complexity: O(n log k) - Where n is the number of unique words * Space Complexity: O(n) - For storing the frequency map and heap * * @param {string[]} words - Array of words * @param {number} k - Number of top frequent words to return * @return {string[]} - Top k frequent words */function topKFrequentHeap(words, k) { // Count frequency of each word const freq = new Map(); for (const word of words) { freq.set(word, (freq.get(word) || 0) + 1); } // Create a min heap of size k // In JavaScript, we'll simulate a heap using an array and manual operations const heap = []; // Helper function to compare two words const compare = (a, b) => { const freqA = freq.get(a); const freqB = freq.get(b); if (freqA !== freqB) { return freqA - freqB; // Min heap by frequency } return b.localeCompare(a); // Reverse alphabetical order for min heap }; // Helper function to maintain heap property const heapify = (i) => { const left = 2 * i + 1; const right = 2 * i + 2; let smallest = i; if (left < heap.length && compare(heap[left], heap[smallest]) < 0) { smallest = left; } if (right < heap.length && compare(heap[right], heap[smallest]) < 0) { smallest = right; } if (smallest !== i) { [heap[i], heap[smallest]] = [heap[smallest], heap[i]]; heapify(smallest); } }; // Add word to heap const addToHeap = (word) => { heap.push(word); let i = heap.length - 1; let parent = Math.floor((i - 1) / 2); while (i > 0 && compare(heap[i], heap[parent]) < 0) { [heap[i], heap[parent]] = [heap[parent], heap[i]]; i = parent; parent = Math.floor((i - 1) / 2); } }; // Remove top element from heap const pollFromHeap = () => { const top = heap[0]; heap[0] = heap[heap.length - 1]; heap.pop(); heapify(0); return top; }; // Add words to heap for (const word of freq.keys()) { addToHeap(word); if (heap.length > k) { pollFromHeap(); } } // Extract words from heap in reverse order const result = []; while (heap.length > 0) { result.unshift(pollFromHeap()); } return result;} /** * Bucket Sort Approach * Time Complexity: O(m) - Where m is the length of the input array * Space Complexity: O(m) - For storing the frequency map and buckets * * @param {string[]} words - Array of words * @param {number} k - Number of top frequent words to return * @return {string[]} - Top k frequent words */function topKFrequentBucket(words, k) { // Count frequency of each word const freq = new Map(); for (const word of words) { freq.set(word, (freq.get(word) || 0) + 1); } // Create buckets const buckets = Array(words.length + 1).fill().map(() => []); for (const word of freq.keys()) { const count = freq.get(word); buckets[count].push(word); } // Sort words in each bucket alphabetically for (const bucket of buckets) { bucket.sort(); } // Collect top k words const result = []; for (let i = buckets.length - 1; i >= 0 && result.length < k; i--) { for (const word of buckets[i]) { result.push(word); if (result.length === k) { break; } } } return result;} // Test casesconsole.log(topKFrequent(["i", "love", "leetcode", "i", "love", "coding"], 2)); // ["i", "love"]console.log(topKFrequent(["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], 4)); // ["the", "is", "sunny", "day"]
Let's break down the implementation:
Implement the word frequency analyzer solution in different programming languages.
Below is the implementation of the word frequency analyzer in different programming languages. Select a language tab to view the corresponding code.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168/** * Brute Force Approach * Time Complexity: O(n log n) - Dominated by the sorting operation * Space Complexity: O(n) - For storing the frequency map and result array * * @param {string[]} words - Array of words * @param {number} k - Number of top frequent words to return * @return {string[]} - Top k frequent words */function topKFrequent(words, k) { // Count frequency of each word const freq = new Map(); for (const word of words) { freq.set(word, (freq.get(word) || 0) + 1); } // Create list of all unique words const uniqueWords = Array.from(freq.keys()); // Sort words by frequency (descending) and alphabetically (ascending) uniqueWords.sort((a, b) => { const freqA = freq.get(a); const freqB = freq.get(b); if (freqA !== freqB) { return freqB - freqA; // Sort by frequency in descending order } return a.localeCompare(b); // Sort alphabetically if frequencies are equal }); // Return top k words return uniqueWords.slice(0, k);} /** * Heap (Priority Queue) Approach * Note: JavaScript doesn't have a built-in heap, so we'll implement a simple min heap * Time Complexity: O(n log k) - Where n is the number of unique words * Space Complexity: O(n) - For storing the frequency map and heap * * @param {string[]} words - Array of words * @param {number} k - Number of top frequent words to return * @return {string[]} - Top k frequent words */function topKFrequentHeap(words, k) { // Count frequency of each word const freq = new Map(); for (const word of words) { freq.set(word, (freq.get(word) || 0) + 1); } // Create a min heap of size k // In JavaScript, we'll simulate a heap using an array and manual operations const heap = []; // Helper function to compare two words const compare = (a, b) => { const freqA = freq.get(a); const freqB = freq.get(b); if (freqA !== freqB) { return freqA - freqB; // Min heap by frequency } return b.localeCompare(a); // Reverse alphabetical order for min heap }; // Helper function to maintain heap property const heapify = (i) => { const left = 2 * i + 1; const right = 2 * i + 2; let smallest = i; if (left < heap.length && compare(heap[left], heap[smallest]) < 0) { smallest = left; } if (right < heap.length && compare(heap[right], heap[smallest]) < 0) { smallest = right; } if (smallest !== i) { [heap[i], heap[smallest]] = [heap[smallest], heap[i]]; heapify(smallest); } }; // Add word to heap const addToHeap = (word) => { heap.push(word); let i = heap.length - 1; let parent = Math.floor((i - 1) / 2); while (i > 0 && compare(heap[i], heap[parent]) < 0) { [heap[i], heap[parent]] = [heap[parent], heap[i]]; i = parent; parent = Math.floor((i - 1) / 2); } }; // Remove top element from heap const pollFromHeap = () => { const top = heap[0]; heap[0] = heap[heap.length - 1]; heap.pop(); heapify(0); return top; }; // Add words to heap for (const word of freq.keys()) { addToHeap(word); if (heap.length > k) { pollFromHeap(); } } // Extract words from heap in reverse order const result = []; while (heap.length > 0) { result.unshift(pollFromHeap()); } return result;} /** * Bucket Sort Approach * Time Complexity: O(m) - Where m is the length of the input array * Space Complexity: O(m) - For storing the frequency map and buckets * * @param {string[]} words - Array of words * @param {number} k - Number of top frequent words to return * @return {string[]} - Top k frequent words */function topKFrequentBucket(words, k) { // Count frequency of each word const freq = new Map(); for (const word of words) { freq.set(word, (freq.get(word) || 0) + 1); } // Create buckets const buckets = Array(words.length + 1).fill().map(() => []); for (const word of freq.keys()) { const count = freq.get(word); buckets[count].push(word); } // Sort words in each bucket alphabetically for (const bucket of buckets) { bucket.sort(); } // Collect top k words const result = []; for (let i = buckets.length - 1; i >= 0 && result.length < k; i--) { for (const word of buckets[i]) { result.push(word); if (result.length === k) { break; } } } return result;} // Test casesconsole.log(topKFrequent(["i", "love", "leetcode", "i", "love", "coding"], 2)); // ["i", "love"]console.log(topKFrequent(["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], 4)); // ["the", "is", "sunny", "day"]
First, understand that we need to find the k most frequent words in an array, with a specific sorting order: by frequency in descending order, and if frequencies are equal, by alphabetical order.
Use a hash map or frequency counter to count how many times each word appears in the array.
Decide which approach to use: brute force (sort all words), heap (maintain a min heap of size k), or bucket sort (use buckets for each frequency).
Implement the chosen approach, paying attention to the sorting order: by frequency in descending order, and if frequencies are equal, by alphabetical order.
Consider edge cases such as empty arrays, arrays with all unique words, or arrays with all identical words.
Consider optimizations such as using a heap for O(n log k) time complexity or bucket sort for linear time complexity in certain cases.
Verify the solution with the provided examples and additional test cases.
Modify the code to implement an alternative approach and test it with the same examples.
Implement a function that solves the word frequency analyzer problem using a different approach than shown above.
If the input array is empty, the result should be an empty array.
If all words in the array are unique, they all have the same frequency (1), so they should be sorted alphabetically.
If all words in the array are identical, the result should contain only that word.
If k equals the number of unique words, the result should contain all unique words sorted by frequency and alphabetically.
If multiple words have the same frequency, they should be sorted alphabetically.
Below is the implementation of the word frequency analyzer:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168/** * Brute Force Approach * Time Complexity: O(n log n) - Dominated by the sorting operation * Space Complexity: O(n) - For storing the frequency map and result array * * @param {string[]} words - Array of words * @param {number} k - Number of top frequent words to return * @return {string[]} - Top k frequent words */function topKFrequent(words, k) { // Count frequency of each word const freq = new Map(); for (const word of words) { freq.set(word, (freq.get(word) || 0) + 1); } // Create list of all unique words const uniqueWords = Array.from(freq.keys()); // Sort words by frequency (descending) and alphabetically (ascending) uniqueWords.sort((a, b) => { const freqA = freq.get(a); const freqB = freq.get(b); if (freqA !== freqB) { return freqB - freqA; // Sort by frequency in descending order } return a.localeCompare(b); // Sort alphabetically if frequencies are equal }); // Return top k words return uniqueWords.slice(0, k);} /** * Heap (Priority Queue) Approach * Note: JavaScript doesn't have a built-in heap, so we'll implement a simple min heap * Time Complexity: O(n log k) - Where n is the number of unique words * Space Complexity: O(n) - For storing the frequency map and heap * * @param {string[]} words - Array of words * @param {number} k - Number of top frequent words to return * @return {string[]} - Top k frequent words */function topKFrequentHeap(words, k) { // Count frequency of each word const freq = new Map(); for (const word of words) { freq.set(word, (freq.get(word) || 0) + 1); } // Create a min heap of size k // In JavaScript, we'll simulate a heap using an array and manual operations const heap = []; // Helper function to compare two words const compare = (a, b) => { const freqA = freq.get(a); const freqB = freq.get(b); if (freqA !== freqB) { return freqA - freqB; // Min heap by frequency } return b.localeCompare(a); // Reverse alphabetical order for min heap }; // Helper function to maintain heap property const heapify = (i) => { const left = 2 * i + 1; const right = 2 * i + 2; let smallest = i; if (left < heap.length && compare(heap[left], heap[smallest]) < 0) { smallest = left; } if (right < heap.length && compare(heap[right], heap[smallest]) < 0) { smallest = right; } if (smallest !== i) { [heap[i], heap[smallest]] = [heap[smallest], heap[i]]; heapify(smallest); } }; // Add word to heap const addToHeap = (word) => { heap.push(word); let i = heap.length - 1; let parent = Math.floor((i - 1) / 2); while (i > 0 && compare(heap[i], heap[parent]) < 0) { [heap[i], heap[parent]] = [heap[parent], heap[i]]; i = parent; parent = Math.floor((i - 1) / 2); } }; // Remove top element from heap const pollFromHeap = () => { const top = heap[0]; heap[0] = heap[heap.length - 1]; heap.pop(); heapify(0); return top; }; // Add words to heap for (const word of freq.keys()) { addToHeap(word); if (heap.length > k) { pollFromHeap(); } } // Extract words from heap in reverse order const result = []; while (heap.length > 0) { result.unshift(pollFromHeap()); } return result;} /** * Bucket Sort Approach * Time Complexity: O(m) - Where m is the length of the input array * Space Complexity: O(m) - For storing the frequency map and buckets * * @param {string[]} words - Array of words * @param {number} k - Number of top frequent words to return * @return {string[]} - Top k frequent words */function topKFrequentBucket(words, k) { // Count frequency of each word const freq = new Map(); for (const word of words) { freq.set(word, (freq.get(word) || 0) + 1); } // Create buckets const buckets = Array(words.length + 1).fill().map(() => []); for (const word of freq.keys()) { const count = freq.get(word); buckets[count].push(word); } // Sort words in each bucket alphabetically for (const bucket of buckets) { bucket.sort(); } // Collect top k words const result = []; for (let i = buckets.length - 1; i >= 0 && result.length < k; i--) { for (const word of buckets[i]) { result.push(word); if (result.length === k) { break; } } } return result;} // Test casesconsole.log(topKFrequent(["i", "love", "leetcode", "i", "love", "coding"], 2)); // ["i", "love"]console.log(topKFrequent(["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], 4)); // ["the", "is", "sunny", "day"]
Let's break down the implementation:
Implement the word frequency analyzer solution in different programming languages.
Below is the implementation of the word frequency analyzer in different programming languages. Select a language tab to view the corresponding code.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168/** * Brute Force Approach * Time Complexity: O(n log n) - Dominated by the sorting operation * Space Complexity: O(n) - For storing the frequency map and result array * * @param {string[]} words - Array of words * @param {number} k - Number of top frequent words to return * @return {string[]} - Top k frequent words */function topKFrequent(words, k) { // Count frequency of each word const freq = new Map(); for (const word of words) { freq.set(word, (freq.get(word) || 0) + 1); } // Create list of all unique words const uniqueWords = Array.from(freq.keys()); // Sort words by frequency (descending) and alphabetically (ascending) uniqueWords.sort((a, b) => { const freqA = freq.get(a); const freqB = freq.get(b); if (freqA !== freqB) { return freqB - freqA; // Sort by frequency in descending order } return a.localeCompare(b); // Sort alphabetically if frequencies are equal }); // Return top k words return uniqueWords.slice(0, k);} /** * Heap (Priority Queue) Approach * Note: JavaScript doesn't have a built-in heap, so we'll implement a simple min heap * Time Complexity: O(n log k) - Where n is the number of unique words * Space Complexity: O(n) - For storing the frequency map and heap * * @param {string[]} words - Array of words * @param {number} k - Number of top frequent words to return * @return {string[]} - Top k frequent words */function topKFrequentHeap(words, k) { // Count frequency of each word const freq = new Map(); for (const word of words) { freq.set(word, (freq.get(word) || 0) + 1); } // Create a min heap of size k // In JavaScript, we'll simulate a heap using an array and manual operations const heap = []; // Helper function to compare two words const compare = (a, b) => { const freqA = freq.get(a); const freqB = freq.get(b); if (freqA !== freqB) { return freqA - freqB; // Min heap by frequency } return b.localeCompare(a); // Reverse alphabetical order for min heap }; // Helper function to maintain heap property const heapify = (i) => { const left = 2 * i + 1; const right = 2 * i + 2; let smallest = i; if (left < heap.length && compare(heap[left], heap[smallest]) < 0) { smallest = left; } if (right < heap.length && compare(heap[right], heap[smallest]) < 0) { smallest = right; } if (smallest !== i) { [heap[i], heap[smallest]] = [heap[smallest], heap[i]]; heapify(smallest); } }; // Add word to heap const addToHeap = (word) => { heap.push(word); let i = heap.length - 1; let parent = Math.floor((i - 1) / 2); while (i > 0 && compare(heap[i], heap[parent]) < 0) { [heap[i], heap[parent]] = [heap[parent], heap[i]]; i = parent; parent = Math.floor((i - 1) / 2); } }; // Remove top element from heap const pollFromHeap = () => { const top = heap[0]; heap[0] = heap[heap.length - 1]; heap.pop(); heapify(0); return top; }; // Add words to heap for (const word of freq.keys()) { addToHeap(word); if (heap.length > k) { pollFromHeap(); } } // Extract words from heap in reverse order const result = []; while (heap.length > 0) { result.unshift(pollFromHeap()); } return result;} /** * Bucket Sort Approach * Time Complexity: O(m) - Where m is the length of the input array * Space Complexity: O(m) - For storing the frequency map and buckets * * @param {string[]} words - Array of words * @param {number} k - Number of top frequent words to return * @return {string[]} - Top k frequent words */function topKFrequentBucket(words, k) { // Count frequency of each word const freq = new Map(); for (const word of words) { freq.set(word, (freq.get(word) || 0) + 1); } // Create buckets const buckets = Array(words.length + 1).fill().map(() => []); for (const word of freq.keys()) { const count = freq.get(word); buckets[count].push(word); } // Sort words in each bucket alphabetically for (const bucket of buckets) { bucket.sort(); } // Collect top k words const result = []; for (let i = buckets.length - 1; i >= 0 && result.length < k; i--) { for (const word of buckets[i]) { result.push(word); if (result.length === k) { break; } } } return result;} // Test casesconsole.log(topKFrequent(["i", "love", "leetcode", "i", "love", "coding"], 2)); // ["i", "love"]console.log(topKFrequent(["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], 4)); // ["the", "is", "sunny", "day"]
First, understand that we need to find the k most frequent words in an array, with a specific sorting order: by frequency in descending order, and if frequencies are equal, by alphabetical order.
Use a hash map or frequency counter to count how many times each word appears in the array.
Decide which approach to use: brute force (sort all words), heap (maintain a min heap of size k), or bucket sort (use buckets for each frequency).
Implement the chosen approach, paying attention to the sorting order: by frequency in descending order, and if frequencies are equal, by alphabetical order.
Consider edge cases such as empty arrays, arrays with all unique words, or arrays with all identical words.
Consider optimizations such as using a heap for O(n log k) time complexity or bucket sort for linear time complexity in certain cases.
Verify the solution with the provided examples and additional test cases.
Modify the code to implement an alternative approach and test it with the same examples.
Implement a function that solves the word frequency analyzer problem using a different approach than shown above.
If the input array is empty, the result should be an empty array.
If all words in the array are unique, they all have the same frequency (1), so they should be sorted alphabetically.
If all words in the array are identical, the result should contain only that word.
If k equals the number of unique words, the result should contain all unique words sorted by frequency and alphabetically.
If multiple words have the same frequency, they should be sorted alphabetically.