diff --git a/problems/451. Sort Characters By Frequency.md b/problems/451. Sort Characters By Frequency.md new file mode 100644 index 000000000..de6e5bb9f --- /dev/null +++ b/problems/451. Sort Characters By Frequency.md @@ -0,0 +1,160 @@ +## Problem +https://leetcode.com/problems/sort-characters-by-frequency/description/ + +## Problem Description +``` +Given a string s, sort it in decreasing order based on the frequency of the characters. The frequency of a character is the number of times it appears in the string. + +Return the sorted string. If there are multiple answers, return any of them. + +Example: + +Input: s = "tree" +Output: "eert" +Explanation: 'e' appears twice while 'r' and 't' both appear once. +So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid answer. + +``` + +## Solution +Map `Hash Map` from left to right, during traverse, group nodes in k, then reverse each group. +How to reverse a linked list given start, end node? + +1. Initializing Variables + +* `biggest`: This variable is used to keep track of the highest frequency of any character in the string s. + +* `hold`: This is a dictionary (hash map) used to store the frequency of each character in the string. The keys represent the characters, and the values represent the number of times they appear. + +```python +biggest = 0 +hold = {} +``` + + +2. Building the Frequency Dictionary + +* For each character (`char`) in the string `s`: + +* If the character is not already in the dictionary `hold`, it is added to the dictionary with a count of `1`. + +* If the character already exists in the dictionary, its count is incremented by `1`. + +* `biggest` keeps track of the highest frequency of any character in `s` by updating it using `max(biggest, hold[char])` for each character. + +```python +for char in s: + if char not in hold: + hold[char] = 1 + else: + hold[char] += 1 + biggest = max(biggest, hold[char]) +``` + ++ Example: + +* For a string like s = "abbccc", this step would produce: + +* `hold = {'a': 1, 'b': 2, 'c': 3}` + +* `biggest = 3 (since the character c appears the most with a frequency of 3).` + + +3. Creating an Array to Hold Characters by Frequency + +* The `array` is created with `biggest + 1` empty strings. The purpose of this array is to group characters by their frequency. + +* For a string like s = "abbccc", this step would produce: + + +```python +array = [""] * (biggest + 1) +``` + + +4. Populating the Frequency Array + +* This loop iterates over each character (key) and its frequency (value) in the hold dictionary. + +* For each character, it places that character (repeated value times) at the index corresponding to its frequency in the array. The string of characters is concatenated at the corresponding index in array. + + +```python +for key, value in hold.items(): + array[value] += key * value +``` + + ++ Example: + +* Continuing with `s = "abbccc"`: + +* `hold = {'a': 1, 'b': 2, 'c': 3}` +* After this step, array will look like this: + - `array = ['', 'a', 'bb', 'ccc']` + - `array[1]` has `"a"` because `a` appears once. + - `array[2]` has `"bb"` because `b` appears twice. + - `array[3]` has `"ccc"` because `c` appears three times. + + +5. Building the Answer String in Decreasing Order of Frequency + +* The answer variable is initialized as an empty string. It will store the final result. + +* A loop iterates through the array, and in each iteration, it pops the last element of the array (i.e., removes it from the end) and appends it to answer. + +* Since array.pop() removes elements from the end, it effectively appends characters to answer in decreasing order of their frequency. + +```python +answer = "" +for i in range(len(array)): + answer += array.pop() +return answer +``` + + ++ Example: + ++ With array = ['', 'a', 'bb', 'ccc'], the popping process will occur as follows: + +* Pop "ccc" → answer = "ccc" +* Pop "bb" → answer = "cccbb" +* Pop "a" → answer = "cccbbba" + +#### Complexity Analysis +- *Time Complexity:* `O(n) - n is number of characters in s` +- *Space Complexity:* `O(n)` + +## Summary of Key Operations: +1. Build a frequency dictionary. +2. Create an array where the index represents the frequency of characters. +3. Populate the array with the characters at the index corresponding to their frequency. +4. Build the result by popping elements from the array in reverse order. + +## Code (`Python3`) +*Python3 Code* +```python +class Solution: + def frequencySort(self, s: str) -> str: + biggest = 0 + hold = {} + + + for char in s: + if char not in hold: + hold[char] = 1 + else: + hold[char] += 1 + biggest = max(biggest, hold[char]) + + + array = [""]*(biggest+1) + for key, value in hold.items(): + array[value] += key*value + + answer = "" + for i in range(len(array)): + answer += array.pop() + + return answer +''' \ No newline at end of file