Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding 451. Sort Characters By Frequency to problems page #606

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 160 additions & 0 deletions problems/451. Sort Characters By Frequency.md
Original file line number Diff line number Diff line change
@@ -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
'''