Bird
Raised Fist0
Interview Preptop-k-elementsmediumAmazonFacebookGoogle

Sort Characters By Frequency

Choose your preparation mode4 modes available
</>
IDE
def frequencySort(s: str) -> str:public String frequencySort(String s)string frequencySort(string s)function frequencySort(s)
def frequencySort(s: str) -> str:
    # Write your solution here
    pass
class Solution {
    public String frequencySort(String s) {
        // Write your solution here
        return "";
    }
}
#include <string>
using namespace std;

string frequencySort(string s) {
    // Write your solution here
    return "";
}
function frequencySort(s) {
    // Write your solution here
}
Coming soon
0/10
Common Bugs to Avoid
Wrong: Characters not grouped by frequency or unordered outputNot sorting characters by frequency descending before building output string✅ Sort characters by frequency descending using sorted(freq.items(), key=lambda x: x[1], reverse=True)
Wrong: Crashes or errors on empty string inputNo check for empty input before processing✅ Add a condition to return empty string if input is empty
Wrong: Incorrect output when multiple characters have same frequencyAssuming unique frequencies or incorrect tie handling✅ Allow ties and group characters with equal frequency without changing counts
Wrong: Fails on large input due to time limit exceededUsing brute force or inefficient sorting with O(n^2) complexity✅ Use frequency counting and bucket sort or max heap to achieve O(n) or O(n log n) time
Wrong: Greedy approach picks characters incorrectlyNot sorting or using max heap, picking characters in wrong order✅ Use max heap or sort frequencies descending before building output
✓
Test Cases
t1_01basic
Input{"s":"tree"}
Expected"eert"

The character 'e' appears twice, so it should come before 'r' and 't' which appear once each.

t1_02basic
Input{"s":"cccaaa"}
Expected"cccaaa"

Both 'c' and 'a' appear three times; output can be 'cccaaa' or 'aaaccc'. Here we expect 'cccaaa'.

t2_01edge
Input{"s":""}
Expected""

Empty string input should return empty string output.

t2_02edge
Input{"s":"z"}
Expected"z"

Single character string returns the same character.

t2_03edge
Input{"s":"aabbcc"}
Expected"aabbcc"

All characters have the same frequency (2); output can be any permutation with grouped characters.

t2_04edge
Input{"s":"abcde"}
Expected"abcde"

All characters are unique; output can be any permutation of input characters.

t3_01corner
Input{"s":"bbbaaaac"}
Expected"aaaabbbc"

Frequency: a=4, b=3, c=1; output must order by frequency descending.

t3_02corner
Input{"s":"aabbccddeeffgg"}
Expected"aabbccddeeffgg"

All characters have frequency 2; output can be any order with grouped characters.

t3_03corner
Input{"s":"aabbccddeeffgggh"}
Expected"gggaabbccddeeffh"

Frequency: g=3, others=2, h=1; output must order by frequency descending.

t4_01performance
Input{"s":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccccccccccccccccccccccdddddddddddddddddddddddddddddddddddddddddddddd"}
⏱ Performance - must finish in 2000ms

Input length n=100,000; solution must run in O(n) or O(n log n) time within 2 seconds.

Practice

(1/5)
1. You are given an unsorted array of integers and asked to find the k-th smallest absolute difference between any two elements. Which approach guarantees an optimal solution in terms of time complexity?
easy
A. Use a brute force nested loop to generate all pairs, then sort the distances and pick the k-th smallest.
B. Sort the array, then use a min-heap to merge pairs starting from adjacent elements to efficiently find the k-th smallest pair distance.
C. Use dynamic programming to build a table of pair distances and select the k-th smallest from the table.
D. Apply a greedy algorithm that repeatedly selects the smallest available pair distance without sorting.

Solution

  1. Step 1: Understand problem constraints and approaches

    Brute force (A) is correct but inefficient with O(n^2 log n) time. Dynamic programming (C) is not applicable as pair distances don't form overlapping subproblems. Greedy (D) fails because pair distances are not independent and require sorting.
  2. Step 2: Identify optimal approach

    Sorting the array and using a min-heap to merge pairs starting from adjacent elements (B) leverages sorted order to generate pairs in ascending order efficiently, achieving O(n log n + k log n) time complexity.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Heap-based merging of sorted pairs is optimal and efficient [OK]
Hint: Heap merge after sorting is optimal for k-th smallest pair distance [OK]
Common Mistakes:
  • Assuming DP applies to pair distances
  • Thinking greedy works without sorting
  • Believing brute force is optimal
2. You are given a list of points on a 2D plane and need to find the k points closest to the origin (0,0). Which algorithmic approach best balances average time complexity and space usage for this problem?
easy
A. Use a Quickselect algorithm to partition points around a pivot distance until the k closest are identified.
B. Use a greedy algorithm that iteratively picks the closest point until k points are selected.
C. Use a dynamic programming approach to build up solutions for subsets of points.
D. Sort all points by their distance to the origin and return the first k points.

Solution

  1. Step 1: Understand problem constraints

    The problem requires finding the k closest points efficiently, ideally better than sorting all points which is O(n log n).
  2. Step 2: Identify algorithm characteristics

    Quickselect partitions points around a pivot and reduces the problem size each iteration, achieving average O(n) time and O(1) extra space, making it optimal.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Quickselect is known for average linear time selection problems [OK]
Hint: Quickselect offers average O(n) vs sorting's O(n log n) [OK]
Common Mistakes:
  • Confusing sorting with selection algorithms
  • Assuming greedy always works for closest points
3. Examine the following buggy Quickselect code for finding k closest points. Which line contains the subtle bug that can cause incorrect results or failure on edge cases?
def kClosest(points: List[List[int]], k: int) -> List[List[int]]:
    def dist(i):
        return (points[i][0]**2 + points[i][1]**2)**0.5  # Bug here

    def partition(left, right, pivot_index):
        pivot_dist = dist(pivot_index)
        points[pivot_index], points[right] = points[right], points[pivot_index]
        store_index = left
        for i in range(left, right):
            if dist(i) < pivot_dist:
                points[store_index], points[i] = points[i], points[store_index]
                store_index += 1
        points[right], points[store_index] = points[store_index], points[right]
        return store_index

    def quickselect(left, right, k_smallest):
        if left == right:
            return
        pivot_index = random.randint(left, right)
        pivot_index = partition(left, right, pivot_index)
        if k_smallest == pivot_index:
            return
        elif k_smallest < pivot_index:
            quickselect(left, pivot_index - 1, k_smallest)
        else:
            quickselect(pivot_index + 1, right, k_smallest)

    quickselect(0, len(points) - 1, k - 1)
    return points[:k]
medium
A. Line defining dist(i) using sqrt in distance calculation
B. Line swapping pivot with right element in partition
C. Line incrementing store_index inside partition loop
D. Line returning points[:k] after quickselect completes

Solution

  1. Step 1: Identify inefficiency in distance calculation

    Using sqrt is unnecessary since squared distances preserve order and avoids floating-point overhead.
  2. Step 2: Understand impact on correctness and performance

    Using sqrt slows down comparisons and can introduce floating-point precision issues, potentially causing incorrect partitioning.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Removing sqrt improves speed and correctness [OK]
Hint: Avoid sqrt; squared distances suffice for comparison [OK]
Common Mistakes:
  • Using sqrt unnecessarily
  • Misplacing pivot swaps
  • Incorrect slicing after quickselect
4. Suppose the frequency stack must support a new operation popK(k) that removes and returns the top k most frequent elements in order, breaking ties by recency. Which modification to the optimal heap-based approach correctly supports this operation efficiently?
hard
A. Perform k consecutive pop() calls on the heap, updating frequencies after each pop.
B. Use a separate max-heap for each frequency level and merge results on popK(k).
C. Modify the heap to store lists of elements per frequency and pop from these lists in order.
D. Maintain a global sorted list of elements by frequency and recency, and slice the top k on popK(k).

Solution

  1. Step 1: Understand popK(k) requirements

    We must pop the top k elements by frequency and recency order, updating frequencies after each pop.
  2. Step 2: Evaluate modifications

    Perform k consecutive pop() calls on the heap, updating frequencies after each pop. This performs k pops sequentially, each O(log n), correctly updating frequencies and maintaining heap invariants. Options A, B, and D either complicate the data structure or lose efficiency and correctness.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Sequential pops maintain correctness and efficiency [OK]
Hint: Sequential pops maintain heap correctness for top-k [OK]
Common Mistakes:
  • Trying to pop multiple elements at once without updating frequencies
  • Using complex data structures that break heap invariants
5. Suppose you want to find the top k frequent words but now words can be reused infinitely many times (like unlimited supply). Which modification to the optimal bucket sort approach correctly handles this scenario?
hard
A. This problem reduces to a knapsack variant; bucket sort no longer applies
B. Modify frequency counting to consider infinite reuse, then apply bucket sort as usual
C. Use a dynamic programming approach to count combinations of words for frequencies
D. Use a max heap keyed by frequency and word lex order, repeatedly pop top k elements

Solution

  1. Step 1: Understand infinite reuse impact

    Infinite reuse means frequency counts are not fixed; problem becomes combinatorial.
  2. Step 2: Recognize problem class change

    Top k frequent words with unlimited reuse resembles knapsack or coin change, not simple frequency counting.
  3. Step 3: Bucket sort no longer applies

    Bucket sort relies on fixed frequencies; dynamic programming or other combinatorial methods are needed.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Infinite reuse breaks frequency counting assumptions [OK]
Hint: Infinite reuse changes problem class, bucket sort invalid [OK]
Common Mistakes:
  • Trying to reuse bucket sort with infinite counts
  • Ignoring combinatorial explosion
  • Assuming heap approach suffices
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard