# Number of Boomerangs

- slug: number-of-boomerangs
- difficulty: Medium

You are given `n` `points` in the plane that are all **distinct**, where `points[i] = [xi, yi]`. A **boomerang** is a tuple of points `(i, j, k)` such that the distance between `i` and `j` equals the distance between `i` and `k` **(the order of the tuple matters)**.

Return _the number of boomerangs_.

**Example 1:**

**Input:** points = \[\[0,0\],\[1,0\],\[2,0\]\]
**Output:** 2
**Explanation:** The two boomerangs are \[\[1,0\],\[0,0\],\[2,0\]\] and \[\[1,0\],\[2,0\],\[0,0\]\].

**Example 2:**

**Input:** points = \[\[1,1\],\[2,2\],\[3,3\]\]
**Output:** 2

**Example 3:**

**Input:** points = \[\[1,1\]\]
**Output:** 0

**Constraints:**

*   `n == points.length`
*   `1 <= n <= 500`
*   `points[i].length == 2`
*   `-104 <= xi, yi <= 104`
*   All the points are **unique**.

## A solution in Java

```java
import java.util.HashMap;

public int numberOfBoomerangs(int[][] points) {
    int count = 0;

    for (int[] i : points) {
        HashMap<Integer, Integer> group_count = new HashMap<>();
        for (int[] j : points) {
            int dx = i[0] - j[0], dy = i[1] - j[1];
            int dist = dx * dx + dy * dy;

            group_count.put(dist, group_count.getOrDefault(dist, 0) + 1);
        }

        for (int g : group_count.values()) {
            count += g * (g - 1);
        }
    }

    return count;
}
```
1. For every point `i` in the input, we create a hash map called `group_count` to store the count of points with the same distance from point `i`.
2. For every point `j`, we calculate the squared distance from `i` to `j`. We use the squared distance to avoid using a square root function, as it's not necessary for this problem.
3. Increment the count of the squared distance in `group_count`.
4. To calculate the number of boomerangs, iterate through the values of `group_count`. For every count `g`, we have `g * (g - 1)` boomerangs because there are `g` choices for the second point and `g - 1` choices for the third point.
5. Return the total number of boomerangs.

## A solution in C++

```cpp
#include <unordered_map>

int numberOfBoomerangs(vector<vector<int>>& points) {
    int count = 0;

    for (auto& i : points) {
        unordered_map<int, int> group_count;
        for (auto& j : points) {
            int dx = i[0] - j[0], dy = i[1] - j[1];
            int dist = dx * dx + dy * dy;
            group_count[dist]++;
        }

        for (auto& g : group_count) {
            count += g.second * (g.second - 1);
        }
    }

    return count;
}
```
1. For every point `i` in the input, we create a hash map called `group_count` to store the count of points with the same distance from point `i`.
2. For every point `j`, we calculate the squared distance from `i` to `j`. We use the squared distance to avoid using a square root function, as it's not necessary for this problem.
3. Increment the count of the squared distance in `group_count`.
4. To calculate the number of boomerangs, iterate through the values of `group_count`. For every count `g`, we have `g * (g - 1)` boomerangs because there are `g` choices for the second point and `g - 1` choices for the third point.
5. Return the total number of boomerangs.

## A solution in Python

```python
def numberOfBoomerangs(points):
    count = 0

    for i in points:
        group_count = {}
        for j in points:
            dx, dy = i[0] - j[0], i[1] - j[1]
            dist = dx * dx + dy * dy
            group_count[dist] = group_count.get(dist, 0) + 1

        for g in group_count.values():
            count += g * (g - 1)

    return count
```
1. For every point `i` in the input, we create a hash map called `group_count` to store the count of points with the same distance from point `i`.
2. For every point `j`, we calculate the squared distance from `i` to `j`. We use the squared distance to avoid using a square root function, as it's not necessary for this problem.
3. Increment the count of the squared distance in `group_count`.
4. To calculate the number of boomerangs, iterate through the values of `group_count`. For every count `g`, we have `g * (g - 1)` boomerangs because there are `g` choices for the second point and `g - 1` choices for the third point.
5. Return the total number of boomerangs.

## A solution in Javascript

```javascript
function numberOfBoomerangs(points) {
    let count = 0;

    for (let i of points) {
        let group_count = new Map();
        for (let j of points) {
            let dx = i[0] - j[0], dy = i[1] - j[1];
            let dist = dx * dx + dy * dy;
            group_count.set(dist, (group_count.get(dist) || 0) + 1);
        }

        for (let g of group_count.values()) {
            count += g * (g - 1);
        }
    }

    return count;
}
```
1. For every point `i` in the input, we create a hash map called `group_count` to store the count of points with the same distance from point `i`.
2. For every point `j`, we calculate the squared distance from `i` to `j`. We use the squared distance to avoid using a square root function, as it's not necessary for this problem.
3. Increment the count of the squared distance in `group_count`.
4. To calculate the number of boomerangs, iterate through the values of `group_count`. For every count `g`, we have `g * (g - 1)` boomerangs because there are `g` choices for the second point and `g - 1` choices for the third point.
5. Return the total number of boomerangs.


# Find All Numbers Disappeared in an Array

- slug: find-all-numbers-disappeared-in-an-array
- difficulty: Easy

Given an array `nums` of `n` integers where `nums[i]` is in the range `[1, n]`, return _an array of all the integers in the range_ `[1, n]` _that do not appear in_ `nums`.

**Example 1:**

**Input:** nums = \[4,3,2,7,8,2,3,1\]
**Output:** \[5,6\]

**Example 2:**

**Input:** nums = \[1,1\]
**Output:** \[2\]

**Constraints:**

*   `n == nums.length`
*   `1 <= n <= 105`
*   `1 <= nums[i] <= n`

**Follow up:** Could you do it without extra space and in `O(n)` runtime? You may assume the returned list does not count as extra space.

## A solution in Java

```java
import java.util.ArrayList;
import java.util.List;

public List<Integer> findDisappearedNumbers(int[] nums) {
    List<Integer> result = new ArrayList<>();

    for (int i = 0; i < nums.length; i++) {
        int index = Math.abs(nums[i]) - 1;
        nums[index] = -Math.abs(nums[index]);
    }

    for (int i = 0; i < nums.length; i++) {
        if (nums[i] > 0) {
            result.add(i + 1);
        }
    }

    return result;
}
```
The algorithm works as follows:

1. Iterate through the input array.
2. For each value `nums[i]`, find its index by subtracting 1 (`index = abs(nums[i]) - 1`). This is because the integers in the range are 1 to n, and indices are 0-indexed.
3. Negate the value at this index (`nums[index] = -abs(nums[index])`). This marks the value as "found".
4. Iterate through the modified array.
5. If a value is positive, it means the integer corresponding to that index hasn't been found. Add it to the result array.

This algorithm has a time complexity of O(n) and doesn't use any additional space other than the result array.

## A solution in C++

```cpp
#include <vector>
using namespace std;

vector<int> findDisappearedNumbers(vector<int> &nums) {
    vector<int> result;

    for (int i = 0; i < nums.size(); ++i) {
        int index = abs(nums[i]) - 1;
        nums[index] = -abs(nums[index]);
    }

    for (int i = 0; i < nums.size(); ++i) {
        if (nums[i] > 0) {
            result.push_back(i + 1);
        }
    }

    return result;
}
```
The algorithm works as follows:

1. Iterate through the input array.
2. For each value `nums[i]`, find its index by subtracting 1 (`index = abs(nums[i]) - 1`). This is because the integers in the range are 1 to n, and indices are 0-indexed.
3. Negate the value at this index (`nums[index] = -abs(nums[index])`). This marks the value as "found".
4. Iterate through the modified array.
5. If a value is positive, it means the integer corresponding to that index hasn't been found. Add it to the result array.

This algorithm has a time complexity of O(n) and doesn't use any additional space other than the result array.

## A solution in Python

```python
def find_disappeared_numbers(nums):
    result = []

    for num in nums:
        index = abs(num) - 1
        nums[index] = -abs(nums[index])

    for i, num in enumerate(nums):
        if num > 0:
            result.append(i + 1)

    return result
```
The algorithm works as follows:

1. Iterate through the input array.
2. For each value `nums[i]`, find its index by subtracting 1 (`index = abs(nums[i]) - 1`). This is because the integers in the range are 1 to n, and indices are 0-indexed.
3. Negate the value at this index (`nums[index] = -abs(nums[index])`). This marks the value as "found".
4. Iterate through the modified array.
5. If a value is positive, it means the integer corresponding to that index hasn't been found. Add it to the result array.

This algorithm has a time complexity of O(n) and doesn't use any additional space other than the result array.

## A solution in Javascript

```javascript
function findDisappearedNumbers(nums) {
    const result = [];

    for (let i = 0; i < nums.length; i++) {
        const index = Math.abs(nums[i]) - 1;
        nums[index] = -Math.abs(nums[index]);
    }

    for (let i = 0; i < nums.length; i++) {
        if (nums[i] > 0) {
            result.push(i + 1);
        }
    }

    return result;
}
```
The algorithm works as follows:

1. Iterate through the input array.
2. For each value `nums[i]`, find its index by subtracting 1 (`index = abs(nums[i]) - 1`). This is because the integers in the range are 1 to n, and indices are 0-indexed.
3. Negate the value at this index (`nums[index] = -abs(nums[index])`). This marks the value as "found".
4. Iterate through the modified array.
5. If a value is positive, it means the integer corresponding to that index hasn't been found. Add it to the result array.

This algorithm has a time complexity of O(n) and doesn't use any additional space other than the result array.


# Serialize and Deserialize BST

- slug: serialize-and-deserialize-bst
- difficulty: Medium

Serialization is converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.

Design an algorithm to serialize and deserialize a **binary search tree**. There is no restriction on how your serialization/deserialization algorithm should work. You need to ensure that a binary search tree can be serialized to a string, and this string can be deserialized to the original tree structure.

**The encoded string should be as compact as possible.**

**Example 1:**

**Input:** root = \[2,1,3\]
**Output:** \[2,1,3\]

**Example 2:**

**Input:** root = \[\]
**Output:** \[\]

**Constraints:**

*   The number of nodes in the tree is in the range `[0, 104]`.
*   `0 <= Node.val <= 104`
*   The input tree is **guaranteed** to be a binary search tree.

## A solution in Java

```java
import java.util.Arrays;
import java.util.Queue;
import java.util.LinkedList;

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public class Codec {

    public String serialize(TreeNode root) {
        if (root == null) return "#";
        return root.val + "," + serialize(root.left) + "," + serialize(root.right);
    }

    public TreeNode deserialize(String data) {
        Queue<String> queue = new LinkedList<>(Arrays.asList(data.split(",")));
        return deserializeHelper(queue);
    }

    private TreeNode deserializeHelper(Queue<String> queue) {
        String val = queue.poll();
        if ("#".equals(val)) return null;
        TreeNode node = new TreeNode(Integer.parseInt(val));
        node.left = deserializeHelper(queue);
        node.right = deserializeHelper(queue);
        return node;
    }
}
```
The algorithm utilizes a pre-order traversal to serialize the binary search tree. When the tree is serialized, the val of each TreeNode is visited before its children. Empty nodes are represented by "#" and commas are used to separate values in the serialized string.

To deserialize, the function processes the serialized string and reconstructs the tree using the pre-order traversal pattern. When an empty node is encountered (indicated by "#"), it returns null. Otherwise, it constructs a TreeNode for the current value, recursively deserializes the left and right children, and returns the constructed node.

## A solution in C++

```cpp
#include <sstream>
#include <string>
#include <iostream>

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

std::string serialize(TreeNode* root) {
    if (!root) return "#";
    return std::to_string(root->val) + ',' + serialize(root->left) + ',' + serialize(root->right);
}

TreeNode* deserialize(std::string data) {
    std::istringstream data_stream(data);
    return deserialize_helper(data_stream);
}

TreeNode* deserialize_helper(std::istringstream& data_stream) {
    std::string val;
    std::getline(data_stream, val, ',');

    if (val == "#") return nullptr;
    TreeNode* node = new TreeNode(std::stoi(val));
    node->left = deserialize_helper(data_stream);
    node->right = deserialize_helper(data_stream);
    return node;
}
```
The algorithm utilizes a pre-order traversal to serialize the binary search tree. When the tree is serialized, the val of each TreeNode is visited before its children. Empty nodes are represented by "#" and commas are used to separate values in the serialized string.

To deserialize, the function processes the serialized string and reconstructs the tree using the pre-order traversal pattern. When an empty node is encountered (indicated by "#"), it returns null. Otherwise, it constructs a TreeNode for the current value, recursively deserializes the left and right children, and returns the constructed node.

## A solution in Python

```python
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

def serialize(root):
    if not root:
        return "#"
    return str(root.val) + "," + serialize(root.left) + "," + serialize(root.right)

def deserialize(data):
    def deserialize_helper(values):
        val = next(values)
        if val == "#":
            return None
        node = TreeNode(int(val))
        node.left = deserialize_helper(values)
        node.right = deserialize_helper(values)
        return node

    values = iter(data.split(","))
    return deserialize_helper(values)
```
The algorithm utilizes a pre-order traversal to serialize the binary search tree. When the tree is serialized, the val of each TreeNode is visited before its children. Empty nodes are represented by "#" and commas are used to separate values in the serialized string.

To deserialize, the function processes the serialized string and reconstructs the tree using the pre-order traversal pattern. When an empty node is encountered (indicated by "#"), it returns null. Otherwise, it constructs a TreeNode for the current value, recursively deserializes the left and right children, and returns the constructed node.

## A solution in Javascript

```javascript
class TreeNode {
    constructor(val) {
        this.val = val;
        this.left = this.right = null;
    }
}

function serialize(root) {
    if (!root) return "#";
    return root.val + "," + serialize(root.left) + "," + serialize(root.right);
}

function deserialize(data) {
    const values = data.split(",");

    function deserialize_helper() {
        const val = values.shift();

        if (val === "#") return null;
        const node = new TreeNode(parseInt(val));
        node.left = deserialize_helper();
        node.right = deserialize_helper();
        return node;
    }

    return deserialize_helper();
}
```
The algorithm utilizes a pre-order traversal to serialize the binary search tree. When the tree is serialized, the val of each TreeNode is visited before its children. Empty nodes are represented by "#" and commas are used to separate values in the serialized string.

To deserialize, the function processes the serialized string and reconstructs the tree using the pre-order traversal pattern. When an empty node is encountered (indicated by "#"), it returns null. Otherwise, it constructs a TreeNode for the current value, recursively deserializes the left and right children, and returns the constructed node.


# Delete Node in a BST

- slug: delete-node-in-a-bst
- difficulty: Medium

Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return _the **root node reference** (possibly updated) of the BST_.

Basically, the deletion can be divided into two stages:

1.  Search for a node to remove.
2.  If the node is found, delete the node.

**Example 1:**

**Input:** root = \[5,3,6,2,4,null,7\], key = 3
**Output:** \[5,4,6,2,null,null,7\]
**Explanation:** Given key to delete is 3. So we find the node with value 3 and delete it.
One valid answer is \[5,4,6,2,null,null,7\], shown in the above BST.
Please notice that another valid answer is \[5,2,6,null,4,null,7\] and it's also accepted.

**Example 2:**

**Input:** root = \[5,3,6,2,4,null,7\], key = 0
**Output:** \[5,3,6,2,4,null,7\]
**Explanation:** The tree does not contain a node with value = 0.

**Example 3:**

**Input:** root = \[\], key = 0
**Output:** \[\]

**Constraints:**

*   The number of nodes in the tree is in the range `[0, 104]`.
*   `-105 <= Node.val <= 105`
*   Each node has a **unique** value.
*   `root` is a valid binary search tree.
*   `-105 <= key <= 105`

**Follow up:** Could you solve it with time complexity `O(height of tree)`?

## A solution in Java

```java
public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public TreeNode deleteNode(TreeNode root, int key) {
    if (root == null) return null;

    if (key < root.val) {
        root.left = deleteNode(root.left, key);
    } else if (key > root.val) {
        root.right = deleteNode(root.right, key);
    } else {
        if (root.left == null) {
            return root.right;
        } else if (root.right == null) {
            return root.left;
        } else {
            TreeNode temp = root.right;
            while (temp.left != null) temp = temp.left;
            root.val = temp.val;
            root.right = deleteNode(root.right, temp.val);
        }
    }
    return root;
}
```
1. If the root is null, return null.
2. If the key is smaller than the root's key, then it lies in the left subtree, so set root's left child be the result of the deleteNode function, where root's left child is the root.
3. If the key is larger, it lies in the right subtree, so set root's right child be the result of the deleteNode function, where root's right child is the root.
4. If the key is equal to the root's key, this is the node to be deleted.
   - If the node with the key has no left child, return its right child.
   - If the node with the key has no right child, return its left child.
   - If the node has both children, find the inorder successor (smallest in the right subtree), replace the node's value with the value of the inorder successor, and then delete the inorder successor.
5. Update the root and return it.

## A solution in C++

```cpp
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

TreeNode* deleteNode(TreeNode* root, int key) {
    if (root == nullptr) return nullptr;

    if (key < root->val) {
        root->left = deleteNode(root->left, key);
    } else if (key > root->val) {
        root->right = deleteNode(root->right, key);
    } else {
        if (root->left == nullptr) {
            TreeNode* temp = root->right;
            delete root;
            return temp;
        } else if (root->right == nullptr) {
            TreeNode* temp = root->left;
            delete root;
            return temp;
        } else {
            TreeNode* temp = root->right;
            while (temp->left) temp = temp->left;
            root->val = temp->val;
            root->right = deleteNode(root->right, temp->val);
        }
    }
    return root;
}
```
1. If the root is null, return null.
2. If the key is smaller than the root's key, then it lies in the left subtree, so set root's left child be the result of the deleteNode function, where root's left child is the root.
3. If the key is larger, it lies in the right subtree, so set root's right child be the result of the deleteNode function, where root's right child is the root.
4. If the key is equal to the root's key, this is the node to be deleted.
   - If the node with the key has no left child, return its right child.
   - If the node with the key has no right child, return its left child.
   - If the node has both children, find the inorder successor (smallest in the right subtree), replace the node's value with the value of the inorder successor, and then delete the inorder successor.
5. Update the root and return it.

## A solution in Python

```python
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

def deleteNode(root, key):
    if root is None:
        return None

    if key < root.val:
        root.left = deleteNode(root.left, key)
    elif key > root.val:
        root.right = deleteNode(root.right, key)
    else:
        if root.left is None:
            return root.right
        elif root.right is None:
            return root.left
        else:
            temp = root.right
            while temp.left is not None:
                temp = temp.left
            root.val = temp.val
            root.right = deleteNode(root.right, temp.val)

    return root
```
1. If the root is null, return null.
2. If the key is smaller than the root's key, then it lies in the left subtree, so set root's left child be the result of the deleteNode function, where root's left child is the root.
3. If the key is larger, it lies in the right subtree, so set root's right child be the result of the deleteNode function, where root's right child is the root.
4. If the key is equal to the root's key, this is the node to be deleted.
   - If the node with the key has no left child, return its right child.
   - If the node with the key has no right child, return its left child.
   - If the node has both children, find the inorder successor (smallest in the right subtree), replace the node's value with the value of the inorder successor, and then delete the inorder successor.
5. Update the root and return it.

## A solution in Javascript

```javascript
class TreeNode {
    constructor(val, left = null, right = null) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

function deleteNode(root, key) {
    if (!root) return null;

    if (key < root.val) {
        root.left = deleteNode(root.left, key);
    } else if (key > root.val) {
        root.right = deleteNode(root.right, key);
    } else {
        if (!root.left) {
            return root.right;
        } else if (!root.right) {
            return root.left;
        } else {
            let temp = root.right;
            while (temp.left) {
                temp = temp.left;
            }
            root.val = temp.val;
            root.right = deleteNode(root.right, temp.val);
        }
    }
    return root;
}
```
1. If the root is null, return null.
2. If the key is smaller than the root's key, then it lies in the left subtree, so set root's left child be the result of the deleteNode function, where root's left child is the root.
3. If the key is larger, it lies in the right subtree, so set root's right child be the result of the deleteNode function, where root's right child is the root.
4. If the key is equal to the root's key, this is the node to be deleted.
   - If the node with the key has no left child, return its right child.
   - If the node with the key has no right child, return its left child.
   - If the node has both children, find the inorder successor (smallest in the right subtree), replace the node's value with the value of the inorder successor, and then delete the inorder successor.
5. Update the root and return it.


# Sort Characters By Frequency

- slug: sort-characters-by-frequency
- difficulty: Medium

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 1:**

**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.

**Example 2:**

**Input:** s =  "cccaaa "
**Output:**  "aaaccc "
**Explanation:** Both 'c' and 'a' appear three times, so both  "cccaaa " and  "aaaccc " are valid answers.
Note that  "cacaca " is incorrect, as the same characters must be together.

**Example 3:**

**Input:** s =  "Aabb "
**Output:**  "bbAa "
**Explanation:**  "bbaA " is also a valid answer, but  "Aabb " is incorrect.
Note that 'A' and 'a' are treated as two different characters.

**Constraints:**

*   `1 <= s.length <= 5 * 105`
*   `s` consists of uppercase and lowercase English letters and digits.

## A solution in Java

```java
import java.util.*;

public String sortByFrequency(String s) {
    Map<Character, Integer> freq = new HashMap<>();
    Character[] chars = new Character[m.length()];

    for (int i = 0; i < m.length(); i++) {
        chars[i] = m.charAt(i);
        freq.put(chars[i], freq.getOrDefault(chars[i], 0) + 1);
    }

    Arrays.sort(chars, (a, b) -> freq.get(b).compareTo(freq.get(a)));

    StringBuilder sb = new StringBuilder();
    for (Character c : chars) {
        sb.append(c);
    }
    return sb.toString();
}
```
1. Create a frequency map `freq` to store the frequency of each character in the input string.
2. Create an array or list `chars` containing all characters of the input string.
3. Loop through the input string and increment the frequency count for each character in the frequency map.
4. Sort the `chars` array or list based on the frequency of each character in the frequency map in descending order (higher frequency first).
5. Combine the sorted `chars` array or list into a string and return the result.

## A solution in C++

```cpp
#include <unordered_map>
#include <vector>
#include <algorithm>

std::string sortByFrequency(std::string s) {
    std::unordered_map<char, int> freq;
    std::vector<char> chars(s.begin(), s.end());

    for (char c : s)
        freq[c]++;

    std::sort(chars.begin(), chars.end(),
              [&](char a, char b) { return freq[a] > freq[b]; });

    return std::string(chars.begin(), chars.end());
}
```
1. Create a frequency map `freq` to store the frequency of each character in the input string.
2. Create an array or list `chars` containing all characters of the input string.
3. Loop through the input string and increment the frequency count for each character in the frequency map.
4. Sort the `chars` array or list based on the frequency of each character in the frequency map in descending order (higher frequency first).
5. Combine the sorted `chars` array or list into a string and return the result.

## A solution in Python

```python
from collections import Counter

def sort_by_frequency(s):
    freq = Counter(s)
    chars = list(s)
    chars.sort(key=lambda c: freq[c], reverse=True)
    return ''.join(chars)
```
1. Create a frequency map `freq` to store the frequency of each character in the input string.
2. Create an array or list `chars` containing all characters of the input string.
3. Loop through the input string and increment the frequency count for each character in the frequency map.
4. Sort the `chars` array or list based on the frequency of each character in the frequency map in descending order (higher frequency first).
5. Combine the sorted `chars` array or list into a string and return the result.

## A solution in Javascript

```javascript
function sortByFrequency(s) {
    const freq = {};
    const chars = [...s];

    for (const c of s)
        freq[c] = (freq[c] || 0) + 1;

    chars.sort((a, b) => freq[b] - freq[a]);

    return chars.join('');
}
```
1. Create a frequency map `freq` to store the frequency of each character in the input string.
2. Create an array or list `chars` containing all characters of the input string.
3. Loop through the input string and increment the frequency count for each character in the frequency map.
4. Sort the `chars` array or list based on the frequency of each character in the frequency map in descending order (higher frequency first).
5. Combine the sorted `chars` array or list into a string and return the result.


# Minimum Number of Arrows to Burst Balloons

- slug: minimum-number-of-arrows-to-burst-balloons
- difficulty: Medium

There are some spherical balloons taped onto a flat wall that represents the XY-plane. The balloons are represented as a 2D integer array `points` where `points[i] = [xstart, xend]` denotes a balloon whose **horizontal diameter** stretches between `xstart` and `xend`. You do not know the exact y-coordinates of the balloons.

Arrows can be shot up **directly vertically** (in the positive y-direction) from different points along the x-axis. A balloon with `xstart` and `xend` is **burst** by an arrow shot at `x` if `xstart <= x <= xend`. There is **no limit** to the number of arrows that can be shot. A shot arrow keeps traveling up infinitely, bursting any balloons in its path.

Given the array `points`, return _the **minimum** number of arrows that must be shot to burst all balloons_.

**Example 1:**

**Input:** points = \[\[10,16\],\[2,8\],\[1,6\],\[7,12\]\]
**Output:** 2
**Explanation:** The balloons can be burst by 2 arrows:
- Shoot an arrow at x = 6, bursting the balloons \[2,8\] and \[1,6\].
- Shoot an arrow at x = 11, bursting the balloons \[10,16\] and \[7,12\].

**Example 2:**

**Input:** points = \[\[1,2\],\[3,4\],\[5,6\],\[7,8\]\]
**Output:** 4
**Explanation:** One arrow needs to be shot for each balloon for a total of 4 arrows.

**Example 3:**

**Input:** points = \[\[1,2\],\[2,3\],\[3,4\],\[4,5\]\]
**Output:** 2
**Explanation:** The balloons can be burst by 2 arrows:
- Shoot an arrow at x = 2, bursting the balloons \[1,2\] and \[2,3\].
- Shoot an arrow at x = 4, bursting the balloons \[3,4\] and \[4,5\].

**Constraints:**

*   `1 <= points.length <= 105`
*   `points[i].length == 2`
*   `-231 <= xstart < xend <= 231 - 1`

## A solution in Java

```java
import java.util.Arrays;
import java.util.Comparator;

public int findMinArrowShots(int[][] points) {
    if (points.length == 0) return 0;
    Arrays.sort(points, Comparator.comparingInt(a -> a[1]));

    int arrows = 1;
    int end = points[0][1];

    for (int i = 1; i < points.length; i++) {
        if (points[i][0] > end) {
            arrows++;
            end = points[i][1];
        }
    }

    return arrows;
}
```
The algorithm sorts the given points by the end value of their ranges. Then, it initializes a variable `arrows` to 1 (to count the first arrow) and `end` to the end value of the first point (to keep track of the last point reached by arrows).

Then, it iterates through the array, starting from the second point to the end. For each point, it checks whether the start value is greater than the current `end` value. If it is, that means this point is not covered by the previous arrows, so it increments the `arrows` counter and updates `end` to the end value of the current point.

Finally, it returns the value of `arrows` as the minimum number of arrows needed to burst all balloons.

## A solution in C++

```cpp
#include <vector>
#include <algorithm>

int findMinArrowShots(std::vector<std::vector<int>>& points) {
    if (points.empty()) return 0;
    std::sort(points.begin(), points.end(), [](const std::vector<int>& a, const std::vector<int>& b) {
        return a[1] < b[1];
    });

    int arrows = 1;
    int end = points[0][1];

    for (int i = 1; i < points.size(); ++i) {
        if (points[i][0] > end) {
            arrows++;
            end = points[i][1];
        }
    }

    return arrows;
}
```
The algorithm sorts the given points by the end value of their ranges. Then, it initializes a variable `arrows` to 1 (to count the first arrow) and `end` to the end value of the first point (to keep track of the last point reached by arrows).

Then, it iterates through the array, starting from the second point to the end. For each point, it checks whether the start value is greater than the current `end` value. If it is, that means this point is not covered by the previous arrows, so it increments the `arrows` counter and updates `end` to the end value of the current point.

Finally, it returns the value of `arrows` as the minimum number of arrows needed to burst all balloons.

## A solution in Python

```python
def findMinArrowShots(points):
    if not points:
        return 0
    points.sort(key=lambda x: x[1])

    arrows = 1
    end = points[0][1]

    for i in range(1, len(points)):
        if points[i][0] > end:
            arrows += 1
            end = points[i][1]

    return arrows
```
The algorithm sorts the given points by the end value of their ranges. Then, it initializes a variable `arrows` to 1 (to count the first arrow) and `end` to the end value of the first point (to keep track of the last point reached by arrows).

Then, it iterates through the array, starting from the second point to the end. For each point, it checks whether the start value is greater than the current `end` value. If it is, that means this point is not covered by the previous arrows, so it increments the `arrows` counter and updates `end` to the end value of the current point.

Finally, it returns the value of `arrows` as the minimum number of arrows needed to burst all balloons.

## A solution in Javascript

```javascript
function findMinArrowShots(points) {
    if (points.length === 0) return 0;
    points.sort((a, b) => a[1] - b[1]);

    let arrows = 1;
    let end = points[0][1];

    for (let i = 1; i < points.length; i++) {
        if (points[i][0] > end) {
            arrows++;
            end = points[i][1];
        }
    }

    return arrows;
}
```
The algorithm sorts the given points by the end value of their ranges. Then, it initializes a variable `arrows` to 1 (to count the first arrow) and `end` to the end value of the first point (to keep track of the last point reached by arrows).

Then, it iterates through the array, starting from the second point to the end. For each point, it checks whether the start value is greater than the current `end` value. If it is, that means this point is not covered by the previous arrows, so it increments the `arrows` counter and updates `end` to the end value of the current point.

Finally, it returns the value of `arrows` as the minimum number of arrows needed to burst all balloons.


# Minimum Moves to Equal Array Elements

- slug: minimum-moves-to-equal-array-elements
- difficulty: Medium

Given an integer array `nums` of size `n`, return _the minimum number of moves required to make all array elements equal_.

In one move, you can increment `n - 1` elements of the array by `1`.

**Example 1:**

**Input:** nums = \[1,2,3\]
**Output:** 3
**Explanation:** Only three moves are needed (remember each move increments two elements):
\[1,2,3\]  =>  \[2,3,3\]  =>  \[3,4,3\]  =>  \[4,4,4\]

**Example 2:**

**Input:** nums = \[1,1,1\]
**Output:** 0

**Constraints:**

*   `n == nums.length`
*   `1 <= nums.length <= 105`
*   `-109 <= nums[i] <= 109`
*   The answer is guaranteed to fit in a **32-bit** integer.

## A solution in Java

```java
public int minMoves(int[] nums) {
    int min_element = nums[0];
    for (int num : nums) {
        min_element = Math.min(min_element, num);
    }
    int moves = 0;
    for (int num : nums) {
        moves += (num - min_element);
    }
    return moves;
}
```
The algorithm works as follows:

1. Find the minimum element in nums.
2. Calculate the number of moves required to make other elements equal to the minimum element by summing the difference between each element and the minimum element (n-1 up moves for each number).
3. Return the calculated number of moves.

The algorithm has a time complexity of O(n) as it iterates through the array twice. The space complexity is also O(n) in the case of the Python solution (due to list comprehensions), otherwise O(1).

## A solution in C++

```cpp
int minMoves(vector<int>& nums) {
    int min_element = *min_element(nums.begin(), nums.end());
    int moves = 0;
    for (int num : nums) {
        moves += (num - min_element);
    }
    return moves;
}
```
The algorithm works as follows:

1. Find the minimum element in nums.
2. Calculate the number of moves required to make other elements equal to the minimum element by summing the difference between each element and the minimum element (n-1 up moves for each number).
3. Return the calculated number of moves.

The algorithm has a time complexity of O(n) as it iterates through the array twice. The space complexity is also O(n) in the case of the Python solution (due to list comprehensions), otherwise O(1).

## A solution in Python

```python
def min_moves(nums):
    min_element = min(nums)
    moves = sum(num - min_element for num in nums)
    return moves
```
The algorithm works as follows:

1. Find the minimum element in nums.
2. Calculate the number of moves required to make other elements equal to the minimum element by summing the difference between each element and the minimum element (n-1 up moves for each number).
3. Return the calculated number of moves.

The algorithm has a time complexity of O(n) as it iterates through the array twice. The space complexity is also O(n) in the case of the Python solution (due to list comprehensions), otherwise O(1).

## A solution in Javascript

```javascript
function minMoves(nums) {
    let min_element = Math.min(...nums);
    let moves = nums.reduce((acc, num) => acc + (num - min_element), 0);
    return moves;
}
```
The algorithm works as follows:

1. Find the minimum element in nums.
2. Calculate the number of moves required to make other elements equal to the minimum element by summing the difference between each element and the minimum element (n-1 up moves for each number).
3. Return the calculated number of moves.

The algorithm has a time complexity of O(n) as it iterates through the array twice. The space complexity is also O(n) in the case of the Python solution (due to list comprehensions), otherwise O(1).


# 4Sum II

- slug: 4sum-ii
- difficulty: Medium

Given four integer arrays `nums1`, `nums2`, `nums3`, and `nums4` all of length `n`, return the number of tuples `(i, j, k, l)` such that:

*   `0 <= i, j, k, l < n`
*   `nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0`

**Example 1:**

**Input:** nums1 = \[1,2\], nums2 = \[-2,-1\], nums3 = \[-1,2\], nums4 = \[0,2\]
**Output:** 2
**Explanation:**
The two tuples are:
1. (0, 0, 0, 1) -> nums1\[0\] + nums2\[0\] + nums3\[0\] + nums4\[1\] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> nums1\[1\] + nums2\[1\] + nums3\[0\] + nums4\[0\] = 2 + (-1) + (-1) + 0 = 0

**Example 2:**

**Input:** nums1 = \[0\], nums2 = \[0\], nums3 = \[0\], nums4 = \[0\]
**Output:** 1

**Constraints:**

*   `n == nums1.length`
*   `n == nums2.length`
*   `n == nums3.length`
*   `n == nums4.length`
*   `1 <= n <= 200`
*   `-228 <= nums1[i], nums2[i], nums3[i], nums4[i] <= 228`

## A solution in Java

```java
import java.util.HashMap;

public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
    HashMap<Integer, Integer> hashMap = new HashMap<>();
    int count = 0;

    for (int i : nums1) {
        for (int j : nums2) {
            hashMap.put(i + j, hashMap.getOrDefault(i + j, 0) + 1);
        }
    }

    for (int k : nums3) {
        for (int l : nums4) {
            count += hashMap.getOrDefault(-(k + l), 0);
        }
    }

    return count;
}
```
The algorithm follows these steps to solve the problem:
1. Create an empty hashmap to store the sum of two integers and their frequency.
2. Iterate through the first two arrays nums1 and nums2, calculate their sum and store their frequency in the hashmap.
3. Iterate through the third and fourth arrays nums3 and nums4, and for each pair of elements, calculate their sum, and check if the negative of this sum exists in the hashmap. If it exists, add the frequency of that sum to the result count.
4. Finally, return the count.

## A solution in C++

```cpp
#include <unordered_map>

int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
    unordered_map<int, int> hashMap;
    int count = 0;

    for (auto i : nums1) {
        for (auto j : nums2) {
            hashMap[i + j]++;
        }
    }

    for (auto k : nums3) {
        for (auto l : nums4) {
            count += hashMap[-(k + l)];
        }
    }

    return count;
}
```
The algorithm follows these steps to solve the problem:
1. Create an empty hashmap to store the sum of two integers and their frequency.
2. Iterate through the first two arrays nums1 and nums2, calculate their sum and store their frequency in the hashmap.
3. Iterate through the third and fourth arrays nums3 and nums4, and for each pair of elements, calculate their sum, and check if the negative of this sum exists in the hashmap. If it exists, add the frequency of that sum to the result count.
4. Finally, return the count.

## A solution in Python

```python
def fourSumCount(nums1, nums2, nums3, nums4):
    hashMap = {}
    count = 0

    for i in nums1:
        for j in nums2:
            hashMap[i + j] = hashMap.get(i + j, 0) + 1

    for k in nums3:
        for l in nums4:
            count += hashMap.get(-(k + l), 0)

    return count
```
The algorithm follows these steps to solve the problem:
1. Create an empty hashmap to store the sum of two integers and their frequency.
2. Iterate through the first two arrays nums1 and nums2, calculate their sum and store their frequency in the hashmap.
3. Iterate through the third and fourth arrays nums3 and nums4, and for each pair of elements, calculate their sum, and check if the negative of this sum exists in the hashmap. If it exists, add the frequency of that sum to the result count.
4. Finally, return the count.

## A solution in Javascript

```javascript
function fourSumCount(nums1, nums2, nums3, nums4) {
    const hashMap = new Map();
    let count = 0;

    for (const i of nums1) {
        for (const j of nums2) {
            hashMap.set(i + j, (hashMap.get(i + j) || 0) + 1);
        }
    }

    for (const k of nums3) {
        for (const l of nums4) {
            count += hashMap.get(-(k + l)) || 0;
        }
    }

    return count;
}
```
The algorithm follows these steps to solve the problem:
1. Create an empty hashmap to store the sum of two integers and their frequency.
2. Iterate through the first two arrays nums1 and nums2, calculate their sum and store their frequency in the hashmap.
3. Iterate through the third and fourth arrays nums3 and nums4, and for each pair of elements, calculate their sum, and check if the negative of this sum exists in the hashmap. If it exists, add the frequency of that sum to the result count.
4. Finally, return the count.


# Assign Cookies

- slug: assign-cookies
- difficulty: Easy

Assume you are an awesome parent and want to give your children some cookies. But, you should give each child at most one cookie.

Each child `i` has a greed factor `g[i]`, which is the minimum size of a cookie that the child will be content with; and each cookie `j` has a size `s[j]`. If `s[j] >= g[i]`, we can assign the cookie `j` to the child `i`, and the child `i` will be content. Your goal is to maximize the number of your content children and output the maximum number.

**Example 1:**

**Input:** g = \[1,2,3\], s = \[1,1\]
**Output:** 1
**Explanation:** You have 3 children and 2 cookies. The greed factors of 3 children are 1, 2, 3.
And even though you have 2 cookies, since their size is both 1, you could only make the child whose greed factor is 1 content.
You need to output 1.

**Example 2:**

**Input:** g = \[1,2\], s = \[1,2,3\]
**Output:** 2
**Explanation:** You have 2 children and 3 cookies. The greed factors of 2 children are 1, 2.
You have 3 cookies and their sizes are big enough to gratify all of the children,
You need to output 2.

**Constraints:**

*   `1 <= g.length <= 3 * 104`
*   `0 <= s.length <= 3 * 104`
*   `1 <= g[i], s[j] <= 231 - 1`

## A solution in Java

```java
import java.util.Arrays;

public int findContentChildren(int[] g, int[] s) {
    Arrays.sort(g);
    Arrays.sort(s);
    int i = 0, j = 0;

    while (i < g.length && j < s.length) {
        if (s[j] >= g[i]) {
            i++;
        }

        j++;
    }

    return i;
}
```
The algorithm first sorts both the greed factors of children `g` and the sizes of cookies `s`. Next, two pointers are declared, `i` for the greed factors and `j` for the cookies.
The algorithm then iterates through the sorted lists in parallel using a while loop until either the greed factors or the cookies run out. Inside the loop, we check if the current cookie `s[j]` is greater than or equal to the current greed factor `g[i]`. If it is, that means the child is content and we increment the `i` pointer to the next child. In both cases (whether the child is content or not), we move on to the next cookie by incrementing the `j` pointer.
The algorithm returns the number of content children (`i`) once the loop is done.

## A solution in C++

```cpp
#include <vector>
#include <algorithm>

int findContentChildren(std::vector<int>& g, std::vector<int>& s) {
    std::sort(g.begin(), g.end());
    std::sort(s.begin(), s.end());
    int i = 0, j = 0;

    while (i < g.size() && j < s.size()) {
      if (s[j] >= g[i]) {
        i++;
      }

      j++;
    }

    return i;
}
```
The algorithm first sorts both the greed factors of children `g` and the sizes of cookies `s`. Next, two pointers are declared, `i` for the greed factors and `j` for the cookies.
The algorithm then iterates through the sorted lists in parallel using a while loop until either the greed factors or the cookies run out. Inside the loop, we check if the current cookie `s[j]` is greater than or equal to the current greed factor `g[i]`. If it is, that means the child is content and we increment the `i` pointer to the next child. In both cases (whether the child is content or not), we move on to the next cookie by incrementing the `j` pointer.
The algorithm returns the number of content children (`i`) once the loop is done.

## A solution in Python

```python
def find_content_children(g, s):
    g.sort()
    s.sort()
    i = j = 0

    while i < len(g) and j < len(s):
        if s[j] >= g[i]:
            i += 1

        j += 1

    return i
```
The algorithm first sorts both the greed factors of children `g` and the sizes of cookies `s`. Next, two pointers are declared, `i` for the greed factors and `j` for the cookies.
The algorithm then iterates through the sorted lists in parallel using a while loop until either the greed factors or the cookies run out. Inside the loop, we check if the current cookie `s[j]` is greater than or equal to the current greed factor `g[i]`. If it is, that means the child is content and we increment the `i` pointer to the next child. In both cases (whether the child is content or not), we move on to the next cookie by incrementing the `j` pointer.
The algorithm returns the number of content children (`i`) once the loop is done.

## A solution in Javascript

```javascript
function findContentChildren(g, s) {
    g.sort((a, b) => a - b);
    s.sort((a, b) => a - b);
    let i = 0, j = 0;

    while (i < g.length && j < s.length) {
        if (s[j] >= g[i]) {
            i++;
        }

        j++;
    }

    return i;
}
```
The algorithm first sorts both the greed factors of children `g` and the sizes of cookies `s`. Next, two pointers are declared, `i` for the greed factors and `j` for the cookies.
The algorithm then iterates through the sorted lists in parallel using a while loop until either the greed factors or the cookies run out. Inside the loop, we check if the current cookie `s[j]` is greater than or equal to the current greed factor `g[i]`. If it is, that means the child is content and we increment the `i` pointer to the next child. In both cases (whether the child is content or not), we move on to the next cookie by incrementing the `j` pointer.
The algorithm returns the number of content children (`i`) once the loop is done.


# 132 Pattern

- slug: 132-pattern
- difficulty: Medium

Given an array of `n` integers `nums`, a **132 pattern** is a subsequence of three integers `nums[i]`, `nums[j]` and `nums[k]` such that `i < j < k` and `nums[i] < nums[k] < nums[j]`.

Return `true` _if there is a **132 pattern** in_ `nums`_, otherwise, return_ `false`_._

**Example 1:**

**Input:** nums = \[1,2,3,4\]
**Output:** false
**Explanation:** There is no 132 pattern in the sequence.

**Example 2:**

**Input:** nums = \[3,1,4,2\]
**Output:** true
**Explanation:** There is a 132 pattern in the sequence: \[1, 4, 2\].

**Example 3:**

**Input:** nums = \[-1,3,2,0\]
**Output:** true
**Explanation:** There are three 132 patterns in the sequence: \[-1, 3, 2\], \[-1, 3, 0\] and \[-1, 2, 0\].

**Constraints:**

*   `n == nums.length`
*   `1 <= n <= 2 * 105`
*   `-109 <= nums[i] <= 109`

## A solution in Java

```java
public boolean find132pattern(int[] nums) {
    int n = nums.length;
    int[] min = new int[n];
    min[0] = nums[0];
    for (int i = 1; i < n; ++i) {
        min[i] = Math.min(min[i - 1], nums[i]);
    }
    Stack<Integer> stack = new Stack<>();
    for (int j = n - 1; j >= 0; --j) {
        if (nums[j] > min[j]) {
            while (!stack.isEmpty() && stack.peek() <= min[j]) {
                stack.pop();
            }
            if (!stack.isEmpty() && stack.peek() < nums[j]) {
                return true;
            }
            stack.push(nums[j]);
        }
    }
    return false;
}
```
To find the 132 pattern, we iterate through the array from the end to the beginning. We use a stack to keep track of potential third elements (nums[k]) in the 132 pattern. We also keep track of the maximum third element found so far. If we find a number that is smaller than the maximum third element, we know that a 132 pattern exists.

In the Java and Python implementations, we also create a separate array to store the minimum values found so far from the start of the array, which helps in identifying the first element (nums[i]) in the 132 pattern. This step can be skipped in C++ and JavaScript implementations by directly comparing the first element (nums[i]) with the maximum third element stored in the stack.

During the iteration, we check if the current number is smaller than the maximum third element, which would mean a 132 pattern has been found. If not, we update the maximum third element and the stack as necessary to continue searching for the 132 pattern. Finally, we return whether the 132 pattern has been found.

## A solution in C++

```cpp
bool find132pattern(vector<int>& nums) {
    int n = nums.size(), third = INT_MIN;
    stack<int> st;
    for (int i = n - 1; i >= 0; --i) {
        if (nums[i] < third) return true;
        while (!st.empty() && st.top() < nums[i]) {
            third = st.top(); st.pop();
        }
        st.push(nums[i]);
    }
    return false;
}
```
To find the 132 pattern, we iterate through the array from the end to the beginning. We use a stack to keep track of potential third elements (nums[k]) in the 132 pattern. We also keep track of the maximum third element found so far. If we find a number that is smaller than the maximum third element, we know that a 132 pattern exists.

In the Java and Python implementations, we also create a separate array to store the minimum values found so far from the start of the array, which helps in identifying the first element (nums[i]) in the 132 pattern. This step can be skipped in C++ and JavaScript implementations by directly comparing the first element (nums[i]) with the maximum third element stored in the stack.

During the iteration, we check if the current number is smaller than the maximum third element, which would mean a 132 pattern has been found. If not, we update the maximum third element and the stack as necessary to continue searching for the 132 pattern. Finally, we return whether the 132 pattern has been found.

## A solution in Python

```python
def find132pattern(nums):
    third, stack = float('-inf'), []
    for num in reversed(nums):
        if num < third:
            return True
        while stack and stack[-1] < num:
            third = stack.pop()
        stack.append(num)
    return False
```
To find the 132 pattern, we iterate through the array from the end to the beginning. We use a stack to keep track of potential third elements (nums[k]) in the 132 pattern. We also keep track of the maximum third element found so far. If we find a number that is smaller than the maximum third element, we know that a 132 pattern exists.

In the Java and Python implementations, we also create a separate array to store the minimum values found so far from the start of the array, which helps in identifying the first element (nums[i]) in the 132 pattern. This step can be skipped in C++ and JavaScript implementations by directly comparing the first element (nums[i]) with the maximum third element stored in the stack.

During the iteration, we check if the current number is smaller than the maximum third element, which would mean a 132 pattern has been found. If not, we update the maximum third element and the stack as necessary to continue searching for the 132 pattern. Finally, we return whether the 132 pattern has been found.

## A solution in Javascript

```javascript
function find132pattern(nums) {
    const stack = [];
    let third = Number.MIN_SAFE_INTEGER;
    for (let i = nums.length - 1; i >= 0; --i) {
        if (nums[i] < third) {
            return true;
        }
        while (stack.length && stack[stack.length - 1] < nums[i]) {
            third = stack.pop();
        }
        stack.push(nums[i]);
    }
    return false;
}
```
To find the 132 pattern, we iterate through the array from the end to the beginning. We use a stack to keep track of potential third elements (nums[k]) in the 132 pattern. We also keep track of the maximum third element found so far. If we find a number that is smaller than the maximum third element, we know that a 132 pattern exists.

In the Java and Python implementations, we also create a separate array to store the minimum values found so far from the start of the array, which helps in identifying the first element (nums[i]) in the 132 pattern. This step can be skipped in C++ and JavaScript implementations by directly comparing the first element (nums[i]) with the maximum third element stored in the stack.

During the iteration, we check if the current number is smaller than the maximum third element, which would mean a 132 pattern has been found. If not, we update the maximum third element and the stack as necessary to continue searching for the 132 pattern. Finally, we return whether the 132 pattern has been found.


# Circular Array Loop

- slug: circular-array-loop
- difficulty: Medium

You are playing a game involving a **circular** array of non-zero integers `nums`. Each `nums[i]` denotes the number of indices forward/backward you must move if you are located at index `i`:

*   If `nums[i]` is positive, move `nums[i]` steps **forward**, and
*   If `nums[i]` is negative, move `nums[i]` steps **backward**.

Since the array is **circular**, you may assume that moving forward from the last element puts you on the first element, and moving backwards from the first element puts you on the last element.

A **cycle** in the array consists of a sequence of indices `seq` of length `k` where:

*   Following the movement rules above results in the repeating index sequence `seq[0] -> seq[1] -> ... -> seq[k - 1] -> seq[0] -> ...`
*   Every `nums[seq[j]]` is either **all positive** or **all negative**.
*   `k > 1`

Return `true` _if there is a **cycle** in_ `nums`_, or_ `false` _otherwise_.

**Example 1:**

**Input:** nums = \[2,-1,1,2,2\]
**Output:** true
**Explanation:** The graph shows how the indices are connected. White nodes are jumping forward, while red is jumping backward.
We can see the cycle 0 --> 2 --> 3 --> 0 --> ..., and all of its nodes are white (jumping in the same direction).

**Example 2:**

**Input:** nums = \[-1,-2,-3,-4,-5,6\]
**Output:** false
**Explanation:** The graph shows how the indices are connected. White nodes are jumping forward, while red is jumping backward.
The only cycle is of size 1, so we return false.

**Example 3:**

**Input:** nums = \[1,-1,5,1,4\]
**Output:** true
**Explanation:** The graph shows how the indices are connected. White nodes are jumping forward, while red is jumping backward.
We can see the cycle 0 --> 1 --> 0 --> ..., and while it is of size > 1, it has a node jumping forward and a node jumping backward, so **it is not a cycle**.
We can see the cycle 3 --> 4 --> 3 --> ..., and all of its nodes are white (jumping in the same direction).

**Constraints:**

*   `1 <= nums.length <= 5000`
*   `-1000 <= nums[i] <= 1000`
*   `nums[i] != 0`

**Follow up:** Could you solve it in `O(n)` time complexity and `O(1)` extra space complexity?

## A solution in Java

```java
public boolean circularArrayLoop(int[] nums) {
    int N = nums.length;
    for (int i = 0; i < N; i++) {
        int slow = i, fast = i;
        do {
            slow = getNextIndex(slow, nums);
            fast = getNextIndex(getNextIndex(fast, nums), nums);
        } while (slow != fast && nums[slow] * nums[fast] > 0);

        if (slow != fast) continue;
        boolean cycle = false;
        int start = slow;
        do {
            cycle |= getNextIndex(start, nums) == start;
            start = getNextIndex(start, nums);
        } while (start != slow);
        if (!cycle) return true;
    }
    return false;
}

int getNextIndex(int idx, int[] nums) {
    int N = nums.length;
    return ((idx + nums[idx]) % N + N) % N;
}
```
The algorithm is designed to detect a cycle in a circular array. It uses a slow and fast pointer approach inspired by the "Floyd's Tortoise and Hare" algorithm. The slow pointer moves one step at a time and the fast pointer moves two steps at a time. If there is a cycle in the array, the slow and fast pointers will eventually meet at the same index.

The algorithm iterates through the entire array to detect any possible cycle with the given starting index. For each index, the slow and fast pointers are initialized, and the getNextIndex function is used to get the next index, considering the circular nature of the array. The loop continues to execute as long as the slow and fast pointers are different and the product of nums[slow] and nums[fast] is positive.

If the slow and fast pointers meet, there is a possibility of having a cycle. To verify this, the algorithm checks if there is a cycle by traversing from the start index, and if there is no cycle, it returns true. If no cycle is found, the algorithm continues to search the array for cycles.

Finally, if there is no cycle in the whole array, it returns false.

## A solution in C++

```cpp
bool circularArrayLoop(vector<int>& nums) {
    int N = nums.size();
    for (int i = 0; i < N; i++) {
        int slow = i, fast = i;
        do {
            slow = getNextIndex(slow, nums);
            fast = getNextIndex(getNextIndex(fast, nums), nums);
        } while (slow != fast && nums[slow] * nums[fast] > 0);

        if (slow != fast) continue;
        bool cycle = false;
        int start = slow;
        do {
            cycle |= getNextIndex(start, nums) == start;
            start = getNextIndex(start, nums);
        } while (start != slow);
        if (!cycle) return true;
    }
    return false;
}

int getNextIndex(int idx, vector<int>& nums) {
    int N = nums.size();
    return ((idx + nums[idx]) % N + N) % N;
}
```
The algorithm is designed to detect a cycle in a circular array. It uses a slow and fast pointer approach inspired by the "Floyd's Tortoise and Hare" algorithm. The slow pointer moves one step at a time and the fast pointer moves two steps at a time. If there is a cycle in the array, the slow and fast pointers will eventually meet at the same index.

The algorithm iterates through the entire array to detect any possible cycle with the given starting index. For each index, the slow and fast pointers are initialized, and the getNextIndex function is used to get the next index, considering the circular nature of the array. The loop continues to execute as long as the slow and fast pointers are different and the product of nums[slow] and nums[fast] is positive.

If the slow and fast pointers meet, there is a possibility of having a cycle. To verify this, the algorithm checks if there is a cycle by traversing from the start index, and if there is no cycle, it returns true. If no cycle is found, the algorithm continues to search the array for cycles.

Finally, if there is no cycle in the whole array, it returns false.

## A solution in Python

```python
def circularArrayLoop(nums: List[int]) -> bool:
    N = len(nums)
    for i in range(N):
        slow, fast = i, i
        while True:
            slow = getNextIndex(slow, nums)
            fast = getNextIndex(getNextIndex(fast, nums), nums)
            if slow != fast and nums[slow] * nums[fast] > 0:
                break
            if slow == fast:
                break
        else:
            continue
        cycle = False
        start = slow
        while start != slow:
            cycle |= getNextIndex(start, nums) == start
            start = getNextIndex(start, nums)
        if not cycle:
            return True
    return False

def getNextIndex(idx: int, nums: List[int]) -> int:
    N = len(nums)
    return (idx + nums[idx]) % N
```
The algorithm is designed to detect a cycle in a circular array. It uses a slow and fast pointer approach inspired by the "Floyd's Tortoise and Hare" algorithm. The slow pointer moves one step at a time and the fast pointer moves two steps at a time. If there is a cycle in the array, the slow and fast pointers will eventually meet at the same index.

The algorithm iterates through the entire array to detect any possible cycle with the given starting index. For each index, the slow and fast pointers are initialized, and the getNextIndex function is used to get the next index, considering the circular nature of the array. The loop continues to execute as long as the slow and fast pointers are different and the product of nums[slow] and nums[fast] is positive.

If the slow and fast pointers meet, there is a possibility of having a cycle. To verify this, the algorithm checks if there is a cycle by traversing from the start index, and if there is no cycle, it returns true. If no cycle is found, the algorithm continues to search the array for cycles.

Finally, if there is no cycle in the whole array, it returns false.

## A solution in Javascript

```javascript
function circularArrayLoop(nums) {
  const N = nums.length;
  for (let i = 0; i < N; i++) {
    let slow = i, fast = i;
    do {
      slow = getNextIndex(slow, nums);
      fast = getNextIndex(getNextIndex(fast, nums), nums);
    } while (slow !== fast && nums[slow] * nums[fast] > 0);

    if (slow !== fast) continue;
    let cycle = false;
    let start = slow;
    do {
      cycle |= getNextIndex(start, nums) === start;
      start = getNextIndex(start, nums);
    } while (start !== slow);
    if (!cycle) return true;
  }
  return false;
}

function getNextIndex(idx, nums) {
    const N = nums.length;
    return ((idx + nums[idx]) % N + N) % N;
}
```
The algorithm is designed to detect a cycle in a circular array. It uses a slow and fast pointer approach inspired by the "Floyd's Tortoise and Hare" algorithm. The slow pointer moves one step at a time and the fast pointer moves two steps at a time. If there is a cycle in the array, the slow and fast pointers will eventually meet at the same index.

The algorithm iterates through the entire array to detect any possible cycle with the given starting index. For each index, the slow and fast pointers are initialized, and the getNextIndex function is used to get the next index, considering the circular nature of the array. The loop continues to execute as long as the slow and fast pointers are different and the product of nums[slow] and nums[fast] is positive.

If the slow and fast pointers meet, there is a possibility of having a cycle. To verify this, the algorithm checks if there is a cycle by traversing from the start index, and if there is no cycle, it returns true. If no cycle is found, the algorithm continues to search the array for cycles.

Finally, if there is no cycle in the whole array, it returns false.


# Poor Pigs

- slug: poor-pigs
- difficulty: Hard

There are `buckets` buckets of liquid, where **exactly one** of the buckets is poisonous. To figure out which one is poisonous, you feed some number of (poor) pigs the liquid to see whether they will die or not. Unfortunately, you only have `minutesToTest` minutes to determine which bucket is poisonous.

You can feed the pigs according to these steps:

1.  Choose some live pigs to feed.
2.  For each pig, choose which buckets to feed it. The pig will consume all the chosen buckets simultaneously and will take no time. Each pig can feed from any number of buckets, and each bucket can be fed from by any number of pigs.
3.  Wait for `minutesToDie` minutes. You may **not** feed any other pigs during this time.
4.  After `minutesToDie` minutes have passed, any pigs that have been fed the poisonous bucket will die, and all others will survive.
5.  Repeat this process until you run out of time.

Given `buckets`, `minutesToDie`, and `minutesToTest`, return _the **minimum** number of pigs needed to figure out which bucket is poisonous within the allotted time_.

**Example 1:**

**Input:** buckets = 4, minutesToDie = 15, minutesToTest = 15
**Output:** 2
**Explanation:** We can determine the poisonous bucket as follows:
At time 0, feed the first pig buckets 1 and 2, and feed the second pig buckets 2 and 3.
At time 15, there are 4 possible outcomes:
- If only the first pig dies, then bucket 1 must be poisonous.
- If only the second pig dies, then bucket 3 must be poisonous.
- If both pigs die, then bucket 2 must be poisonous.
- If neither pig dies, then bucket 4 must be poisonous.

**Example 2:**

**Input:** buckets = 4, minutesToDie = 15, minutesToTest = 30
**Output:** 2
**Explanation:** We can determine the poisonous bucket as follows:
At time 0, feed the first pig bucket 1, and feed the second pig bucket 2.
At time 15, there are 2 possible outcomes:
- If either pig dies, then the poisonous bucket is the one it was fed.
- If neither pig dies, then feed the first pig bucket 3, and feed the second pig bucket 4.
At time 30, one of the two pigs must die, and the poisonous bucket is the one it was fed.

**Constraints:**

*   `1 <= buckets <= 1000`
*   `1 <= minutesToDie <= minutesToTest <= 100`

## A solution in Java

```java
public int poorPigs(int buckets, int minutesToDie, int minutesToTest) {
    int pigs = 0;
    while (Math.pow((minutesToTest / minutesToDie) + 1, pigs) < buckets) {
        pigs++;
    }
    return pigs;
}
```
The algorithm calculates the minimum number of pigs required to test all the buckets within the given time constraint. It is based on the fact that each pig can be used to test multiple buckets (in a binary search manner) within the time constraint, as it is repeatedly fed different buckets.

1. Initialize the number of pigs to 0.
2. Calculate the maximum number of tests each pig can make within the given time constraint (`minutesToTest / minutesToDie + 1`).
3. Iterate and increment the number of pigs until the total number of buckets is less than the power of the number of tests each pig can make to the number of pigs.
4. Return the minimum number of pigs required.

The algorithm leverages the multi-level testing capacity of the pigs within the given time frame to minimize the number of pigs needed. Each pig represents an additional level of testing capacity, reducing the total number of tests needed.

## A solution in C++

```cpp
int poorPigs(int buckets, int minutesToDie, int minutesToTest) {
    int pigs = 0;
    while (pow((minutesToTest / minutesToDie) + 1, pigs) < buckets) {
        pigs++;
    }
    return pigs;
}
```
The algorithm calculates the minimum number of pigs required to test all the buckets within the given time constraint. It is based on the fact that each pig can be used to test multiple buckets (in a binary search manner) within the time constraint, as it is repeatedly fed different buckets.

1. Initialize the number of pigs to 0.
2. Calculate the maximum number of tests each pig can make within the given time constraint (`minutesToTest / minutesToDie + 1`).
3. Iterate and increment the number of pigs until the total number of buckets is less than the power of the number of tests each pig can make to the number of pigs.
4. Return the minimum number of pigs required.

The algorithm leverages the multi-level testing capacity of the pigs within the given time frame to minimize the number of pigs needed. Each pig represents an additional level of testing capacity, reducing the total number of tests needed.

## A solution in Python

```python
def poor_pigs(buckets, minutes_to_die, minutes_to_test):
    pigs = 0
    while (minutes_to_test // minutes_to_die + 1) ** pigs < buckets:
        pigs += 1
    return pigs
```
The algorithm calculates the minimum number of pigs required to test all the buckets within the given time constraint. It is based on the fact that each pig can be used to test multiple buckets (in a binary search manner) within the time constraint, as it is repeatedly fed different buckets.

1. Initialize the number of pigs to 0.
2. Calculate the maximum number of tests each pig can make within the given time constraint (`minutesToTest / minutesToDie + 1`).
3. Iterate and increment the number of pigs until the total number of buckets is less than the power of the number of tests each pig can make to the number of pigs.
4. Return the minimum number of pigs required.

The algorithm leverages the multi-level testing capacity of the pigs within the given time frame to minimize the number of pigs needed. Each pig represents an additional level of testing capacity, reducing the total number of tests needed.

## A solution in Javascript

```javascript
function poorPigs(buckets, minutesToDie, minutesToTest) {
    let pigs = 0;
    while (Math.pow(Math.floor(minutesToTest / minutesToDie) + 1, pigs) < buckets) {
        pigs++;
    }
    return pigs;
}
```
The algorithm calculates the minimum number of pigs required to test all the buckets within the given time constraint. It is based on the fact that each pig can be used to test multiple buckets (in a binary search manner) within the time constraint, as it is repeatedly fed different buckets.

1. Initialize the number of pigs to 0.
2. Calculate the maximum number of tests each pig can make within the given time constraint (`minutesToTest / minutesToDie + 1`).
3. Iterate and increment the number of pigs until the total number of buckets is less than the power of the number of tests each pig can make to the number of pigs.
4. Return the minimum number of pigs required.

The algorithm leverages the multi-level testing capacity of the pigs within the given time frame to minimize the number of pigs needed. Each pig represents an additional level of testing capacity, reducing the total number of tests needed.


# Repeated Substring Pattern

- slug: repeated-substring-pattern
- difficulty: Easy

Given a string `s`, check if it can be constructed by taking a substring of it and appending multiple copies of the substring together.

**Example 1:**

**Input:** s =  "abab "
**Output:** true
**Explanation:** It is the substring  "ab " twice.

**Example 2:**

**Input:** s =  "aba "
**Output:** false

**Example 3:**

**Input:** s =  "abcabcabcabc "
**Output:** true
**Explanation:** It is the substring  "abc " four times or the substring  "abcabc " twice.

**Constraints:**

*   `1 <= s.length <= 104`
*   `s` consists of lowercase English letters.

## A solution in Java

```java
public boolean canConstruct(String s) {
    int n = s.length();
    for (int i = n / 2; i > 0; --i) {
        if (n % i == 0) {
            String substr = s.substring(0, i);
            boolean flag = true;
            for (int j = i; j < n; j += i) {
                if (!s.substring(j, j + i).equals(substr)) {
                    flag = false;
                    break;
                }
            }

            if (flag) return true;
        }
    }
    return false;
}
```
The algorithm iterates through possible substring lengths from half of the length of the given string down to 1 (inclusive). For each length `i`, it checks if the given string can be divided into substrings of equal length `i`. If yes, it takes the first substring and checks if all the remaining substrings of the same length are equal to the first one.

If all the substrings are equal, the function returns `true`, meaning the given string can be constructed by appending multiple copies of the substring together. If none of the lengths results in equal substrings, the function returns `false`.

## A solution in C++

```cpp
bool can_construct(string s) {
    int n = s.size();
    for (int i = n / 2; i > 0; --i) {
        if (n % i == 0) {
            string substr = s.substr(0, i);
            bool flag = true;
            for (int j = i; j < n; j += i) {
                if (s.substr(j, i) != substr) {
                    flag = false;
                    break;
                }
            }

            if (flag) return true;
        }
    }
    return false;
}
```
The algorithm iterates through possible substring lengths from half of the length of the given string down to 1 (inclusive). For each length `i`, it checks if the given string can be divided into substrings of equal length `i`. If yes, it takes the first substring and checks if all the remaining substrings of the same length are equal to the first one.

If all the substrings are equal, the function returns `true`, meaning the given string can be constructed by appending multiple copies of the substring together. If none of the lengths results in equal substrings, the function returns `false`.

## A solution in Python

```python
def can_construct(s):
    n = len(s)
    for i in range(n // 2, 0, -1):
        if n % i == 0:
            substr = s[:i]
            flag = True
            for j in range(i, n, i):
                if s[j:j+i] != substr:
                    flag = False
                    break

            if flag:
                return True

    return False
```
The algorithm iterates through possible substring lengths from half of the length of the given string down to 1 (inclusive). For each length `i`, it checks if the given string can be divided into substrings of equal length `i`. If yes, it takes the first substring and checks if all the remaining substrings of the same length are equal to the first one.

If all the substrings are equal, the function returns `true`, meaning the given string can be constructed by appending multiple copies of the substring together. If none of the lengths results in equal substrings, the function returns `false`.

## A solution in Javascript

```javascript
function canConstruct(s) {
    const n = s.length;
    for (let i = Math.floor(n / 2); i > 0; --i) {
        if (n % i === 0) {
            const substr = s.substring(0, i);
            let flag = true;
            for (let j = i; j < n; j += i) {
                if (s.substring(j, j + i) !== substr) {
                    flag = false;
                    break;
                }
            }

            if (flag) return true;
        }
    }
    return false;
}
```
The algorithm iterates through possible substring lengths from half of the length of the given string down to 1 (inclusive). For each length `i`, it checks if the given string can be divided into substrings of equal length `i`. If yes, it takes the first substring and checks if all the remaining substrings of the same length are equal to the first one.

If all the substrings are equal, the function returns `true`, meaning the given string can be constructed by appending multiple copies of the substring together. If none of the lengths results in equal substrings, the function returns `false`.


# LFU Cache

- slug: lfu-cache
- difficulty: Hard

Design and implement a data structure for a [Least Frequently Used (LFU)](https://en.wikipedia.org/wiki/Least_frequently_used) cache.

Implement the `LFUCache` class:

*   `LFUCache(int capacity)` Initializes the object with the `capacity` of the data structure.
*   `int get(int key)` Gets the value of the `key` if the `key` exists in the cache. Otherwise, returns `-1`.
*   `void put(int key, int value)` Update the value of the `key` if present, or inserts the `key` if not already present. When the cache reaches its `capacity`, it should invalidate and remove the **least frequently used** key before inserting a new item. For this problem, when there is a **tie** (i.e., two or more keys with the same frequency), the **least recently used** `key` would be invalidated.

To determine the least frequently used key, a **use counter** is maintained for each key in the cache. The key with the smallest **use counter** is the least frequently used key.

When a key is first inserted into the cache, its **use counter** is set to `1` (due to the `put` operation). The **use counter** for a key in the cache is incremented either a `get` or `put` operation is called on it.

The functions `get` and `put` must each run in `O(1)` average time complexity.

**Example 1:**

**Input**
\[ "LFUCache ",  "put ",  "put ",  "get ",  "put ",  "get ",  "get ",  "put ",  "get ",  "get ",  "get "\]
\[\[2\], \[1, 1\], \[2, 2\], \[1\], \[3, 3\], \[2\], \[3\], \[4, 4\], \[1\], \[3\], \[4\]\]
**Output**
\[null, null, null, 1, null, -1, 3, null, -1, 3, 4\]

**Explanation**
// cnt(x) = the use counter for key x
// cache=\[\] will show the last used order for tiebreakers (leftmost element is  most recent)
LFUCache lfu = new LFUCache(2);
lfu.put(1, 1);   // cache=\[1,\_\], cnt(1)=1
lfu.put(2, 2);   // cache=\[2,1\], cnt(2)=1, cnt(1)=1
lfu.get(1);      // return 1
                 // cache=\[1,2\], cnt(2)=1, cnt(1)=2
lfu.put(3, 3);   // 2 is the LFU key because cnt(2)=1 is the smallest, invalidate 2.
                 // cache=\[3,1\], cnt(3)=1, cnt(1)=2
lfu.get(2);      // return -1 (not found)
lfu.get(3);      // return 3
                 // cache=\[3,1\], cnt(3)=2, cnt(1)=2
lfu.put(4, 4);   // Both 1 and 3 have the same cnt, but 1 is LRU, invalidate 1.
                 // cache=\[4,3\], cnt(4)=1, cnt(3)=2
lfu.get(1);      // return -1 (not found)
lfu.get(3);      // return 3
                 // cache=\[3,4\], cnt(4)=1, cnt(3)=3
lfu.get(4);      // return 4
                 // cache=\[4,3\], cnt(4)=2, cnt(3)=3

**Constraints:**

*   `1 <= capacity <= 104`
*   `0 <= key <= 105`
*   `0 <= value <= 109`
*   At most `2 * 105` calls will be made to `get` and `put`.

## A solution in Java

```java
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;

class LFUCache {
    private int minFreq;
    private int capacity;
    private Map<Integer, Integer> keyValue;
    private Map<Integer, Integer> keyFreq;
    private Map<Integer, LinkedHashSet<Integer>> freqList;

    public LFUCache(int capacity) {
        this.capacity = capacity;
        this.minFreq = 0;
        this.keyValue = new HashMap<>();
        this.keyFreq = new HashMap<>();
        this.freqList = new HashMap<>();
        freqList.put(1, new LinkedHashSet<>());
    }

    public int get(int key) {
        if (!keyValue.containsKey(key)) return -1;
        int count = keyFreq.get(key);
        keyFreq.put(key, count + 1);
        freqList.get(count).remove(key);

        if (count == minFreq && freqList.get(count).size() == 0) minFreq++;

        freqList.computeIfAbsent(count + 1, k -> new LinkedHashSet<>());
        freqList.get(count + 1).add(key);

        return keyValue.get(key);
    }

    public void put(int key, int value) {
        if (capacity <= 0) return;
        if (keyValue.containsKey(key)) {
            keyValue.put(key, value);
            get(key);
            return;
        }
        if (keyValue.size() >= capacity) {
            int evict = freqList.get(minFreq).iterator().next();
            freqList.get(minFreq).remove(evict);
            keyValue.remove(evict);
        }
        keyValue.put(key, value);
        keyFreq.put(key, 1);
        minFreq = 1;
        freqList.get(1).add(key);
    }
}
```
The implemented LFUCache is a combined data structure using a hash map and linked lists. We maintain 3 key-value mappings: the first is the cache `keyValue` which stores `<key, value>` pairs; the second is `keyFreq`, which keeps track of each key's frequency; the last is `freqList` which keeps the mapping of frequency to a list/set of keys that are at that frequency.

Both get() and put() operations take constant O(1) average time complexity:

1. get():
  - With the help of hashmaps, retrieve the value for the key in constant time.
  - Increment the key’s frequency in `keyFreq` by 1.
  - Update the corresponding list/set of the `freqList`.
  - Update the minFreq if necessary.

2. put():
  - Check if the key is already present in the cache. If it is, update the value, and perform get() operation, thus maintaining frequency count.
  - If the key is not present, add the key-value pair and set its frequency to 1.
  - Evict the LFU (least frequently used) key if necessary, by removing a key from the list/set of `freqList[minFreq]`.

Note that in Java and JavaScript, we use LinkedHashSet / Set, while in Python we use list within the `freqList`. This is due to language-specific details.

## A solution in C++

```cpp
#include <list>
#include <unordered_map>

class LFUCache {
public:
    LFUCache(int capacity) : capacity(capacity), minFreq(0) {}

    int get(int key) {
        if (cache.count(key) == 0) return -1;
        auto& node = cache[key];
        freqList[node.freq].erase(node.iter);
        if (freqList[minFreq].size() == 0) minFreq++;
        node.freq++;
        freqList[node.freq].push_back(key);
        node.iter = prev(freqList[node.freq].end());
        return node.value;
    }

    void put(int key, int value) {
        if (capacity == 0) return;
        if (get(key) != -1) {
            cache[key].value = value;
            return;
        }
        if (cache.size() >= capacity) {
            int toRemove = freqList[minFreq].front();
            freqList[minFreq].pop_front();
            cache.erase(toRemove);
        }
        minFreq = 1;
        freqList[minFreq].push_back(key);
        cache[key] = {1, value, prev(freqList[minFreq].end())};
    }

private:
    struct Node {
        int freq, value;
        std::list<int>::iterator iter;
    };

    int capacity;
    int minFreq;
    std::unordered_map<int, Node> cache;
    std::unordered_map<int, std::list<int>> freqList;
};
```
The implemented LFUCache is a combined data structure using a hash map and linked lists. We maintain 3 key-value mappings: the first is the cache `keyValue` which stores `<key, value>` pairs; the second is `keyFreq`, which keeps track of each key's frequency; the last is `freqList` which keeps the mapping of frequency to a list/set of keys that are at that frequency.

Both get() and put() operations take constant O(1) average time complexity:

1. get():
  - With the help of hashmaps, retrieve the value for the key in constant time.
  - Increment the key’s frequency in `keyFreq` by 1.
  - Update the corresponding list/set of the `freqList`.
  - Update the minFreq if necessary.

2. put():
  - Check if the key is already present in the cache. If it is, update the value, and perform get() operation, thus maintaining frequency count.
  - If the key is not present, add the key-value pair and set its frequency to 1.
  - Evict the LFU (least frequently used) key if necessary, by removing a key from the list/set of `freqList[minFreq]`.

Note that in Java and JavaScript, we use LinkedHashSet / Set, while in Python we use list within the `freqList`. This is due to language-specific details.

## A solution in Python

```python
class LFUCache:
    def __init__(self, capacity: int):
        self.capacity = capacity
        self.min_freq = 0
        self.key_value = {}
        self.key_freq = {}
        self.freq_list = {1: []}

    def get(self, key: int) -> int:
        if key not in self.key_value:
            return -1
        count = self.key_freq[key]
        self.key_freq[key] += 1
        self.freq_list[count].remove(key)

        if count == self.min_freq and not self.freq_list[count]:
            self.min_freq += 1

        if count + 1 not in self.freq_list:
            self.freq_list[count + 1] = []
        self.freq_list[count + 1].append(key)

        return self.key_value[key]

    def put(self, key: int, value: int) -> None:
        if self.capacity <= 0:
            return
        if key in self.key_value:
            self.key_value[key] = value
            self.get(key)
            return

        if len(self.key_value) >= self.capacity:
            evict = self.freq_list[self.min_freq][0]
            self.freq_list[self.min_freq].pop(0)
            del self.key_value[evict]

        self.key_value[key] = value
        self.key_freq[key] = 1
        self.min_freq = 1
        self.freq_list[1].append(key)
```
The implemented LFUCache is a combined data structure using a hash map and linked lists. We maintain 3 key-value mappings: the first is the cache `keyValue` which stores `<key, value>` pairs; the second is `keyFreq`, which keeps track of each key's frequency; the last is `freqList` which keeps the mapping of frequency to a list/set of keys that are at that frequency.

Both get() and put() operations take constant O(1) average time complexity:

1. get():
  - With the help of hashmaps, retrieve the value for the key in constant time.
  - Increment the key’s frequency in `keyFreq` by 1.
  - Update the corresponding list/set of the `freqList`.
  - Update the minFreq if necessary.

2. put():
  - Check if the key is already present in the cache. If it is, update the value, and perform get() operation, thus maintaining frequency count.
  - If the key is not present, add the key-value pair and set its frequency to 1.
  - Evict the LFU (least frequently used) key if necessary, by removing a key from the list/set of `freqList[minFreq]`.

Note that in Java and JavaScript, we use LinkedHashSet / Set, while in Python we use list within the `freqList`. This is due to language-specific details.

## A solution in Javascript

```javascript
class LFUCache {
    constructor(capacity) {
        this.capacity = capacity;
        this.minFreq = 0;
        this.keyValue = new Map();
        this.keyFreq = new Map();
        this.freqList = new Map();
        this.freqList.set(1, new Set());
    }

    get(key) {
        if (!this.keyValue.has(key)) return -1;
        let count = this.keyFreq.get(key);
        this.keyFreq.set(key, count + 1);
        this.freqList.get(count).delete(key);

        if (count === this.minFreq && this.freqList.get(count).size === 0) this.minFreq++;

        if (!this.freqList.has(count + 1)) this.freqList.set(count + 1, new Set());
        this.freqList.get(count + 1).add(key);

        return this.keyValue.get(key);
    }

    put(key, value) {
        if (this.capacity <= 0) return;
        if (this.keyValue.has(key)) {
            this.keyValue.set(key, value);
            this.get(key);
            return;
        }
        if (this.keyValue.size >= this.capacity) {
            const evict = this.freqList.get(this.minFreq).values().next().value;
            this.freqList.get(this.minFreq).delete(evict);
            this.keyValue.delete(evict);
        }
        this.keyValue.set(key, value);
        this.keyFreq.set(key, 1);
        this.minFreq = 1;
        this.freqList.get(1).add(key);
    }
}
```
The implemented LFUCache is a combined data structure using a hash map and linked lists. We maintain 3 key-value mappings: the first is the cache `keyValue` which stores `<key, value>` pairs; the second is `keyFreq`, which keeps track of each key's frequency; the last is `freqList` which keeps the mapping of frequency to a list/set of keys that are at that frequency.

Both get() and put() operations take constant O(1) average time complexity:

1. get():
  - With the help of hashmaps, retrieve the value for the key in constant time.
  - Increment the key’s frequency in `keyFreq` by 1.
  - Update the corresponding list/set of the `freqList`.
  - Update the minFreq if necessary.

2. put():
  - Check if the key is already present in the cache. If it is, update the value, and perform get() operation, thus maintaining frequency count.
  - If the key is not present, add the key-value pair and set its frequency to 1.
  - Evict the LFU (least frequently used) key if necessary, by removing a key from the list/set of `freqList[minFreq]`.

Note that in Java and JavaScript, we use LinkedHashSet / Set, while in Python we use list within the `freqList`. This is due to language-specific details.


# Hamming Distance

- slug: hamming-distance
- difficulty: Easy

The [Hamming distance](https://en.wikipedia.org/wiki/Hamming_distance) between two integers is the number of positions at which the corresponding bits are different.

Given two integers `x` and `y`, return _the **Hamming distance** between them_.

**Example 1:**

**Input:** x = 1, y = 4
**Output:** 2
**Explanation:**
1   (0 0 0 1)
4   (0 1 0 0)
       ↑   ↑
The above arrows point to positions where the corresponding bits are different.

**Example 2:**

**Input:** x = 3, y = 1
**Output:** 1

**Constraints:**

*   `0 <= x, y <= 231 - 1`

## A solution in Java

```java
public int hammingDistance(int x, int y) {
    int dist = 0, xorResult = x ^ y;
    while (xorResult != 0) {
        dist += xorResult & 1;
        xorResult >>= 1;
    }
    return dist;
}
```
We can start by taking the XOR of `x` and `y`. A XOR B value will have a bit set only if both A and B bits are different at that position. We then iterate through the bits of the XOR result, counting the number of set bits, which should give us the Hamming distance required.

1. Calculate `xorResult` by XORing `x` and `y`.
2. Initialize `dist` to 0.
3. While `xorResult` is not 0, do the following:
   a. Add the least significant bit of `xorResult` to `dist`.
   b. Right shift `xorResult` by 1.
4. Return `dist`.

This algorithm performs bitwise operations and loops through the bits of `xorResult`, which has a maximum of 31 bits due to the constraint `0 <= x, y <= 2^31 - 1`. Thus, the time complexity is O(31) = O(1).

## A solution in C++

```cpp
int hammingDistance(int x, int y) {
    int dist = 0, xorResult = x ^ y;
    while (xorResult) {
        dist += xorResult & 1;
        xorResult >>= 1;
    }
    return dist;
}
```
We can start by taking the XOR of `x` and `y`. A XOR B value will have a bit set only if both A and B bits are different at that position. We then iterate through the bits of the XOR result, counting the number of set bits, which should give us the Hamming distance required.

1. Calculate `xorResult` by XORing `x` and `y`.
2. Initialize `dist` to 0.
3. While `xorResult` is not 0, do the following:
   a. Add the least significant bit of `xorResult` to `dist`.
   b. Right shift `xorResult` by 1.
4. Return `dist`.

This algorithm performs bitwise operations and loops through the bits of `xorResult`, which has a maximum of 31 bits due to the constraint `0 <= x, y <= 2^31 - 1`. Thus, the time complexity is O(31) = O(1).

## A solution in Python

```python
def hammingDistance(x: int, y: int) -> int:
    xorResult = x ^ y
    dist = 0
    while xorResult:
        dist += xorResult & 1
        xorResult >>= 1
    return dist
```
We can start by taking the XOR of `x` and `y`. A XOR B value will have a bit set only if both A and B bits are different at that position. We then iterate through the bits of the XOR result, counting the number of set bits, which should give us the Hamming distance required.

1. Calculate `xorResult` by XORing `x` and `y`.
2. Initialize `dist` to 0.
3. While `xorResult` is not 0, do the following:
   a. Add the least significant bit of `xorResult` to `dist`.
   b. Right shift `xorResult` by 1.
4. Return `dist`.

This algorithm performs bitwise operations and loops through the bits of `xorResult`, which has a maximum of 31 bits due to the constraint `0 <= x, y <= 2^31 - 1`. Thus, the time complexity is O(31) = O(1).

## A solution in Javascript

```javascript
function hammingDistance(x, y) {
    let dist = 0;
    let xorResult = x ^ y;
    while (xorResult != 0) {
        dist += xorResult & 1;
        xorResult >>= 1;
    }
    return dist;
}
```
We can start by taking the XOR of `x` and `y`. A XOR B value will have a bit set only if both A and B bits are different at that position. We then iterate through the bits of the XOR result, counting the number of set bits, which should give us the Hamming distance required.

1. Calculate `xorResult` by XORing `x` and `y`.
2. Initialize `dist` to 0.
3. While `xorResult` is not 0, do the following:
   a. Add the least significant bit of `xorResult` to `dist`.
   b. Right shift `xorResult` by 1.
4. Return `dist`.

This algorithm performs bitwise operations and loops through the bits of `xorResult`, which has a maximum of 31 bits due to the constraint `0 <= x, y <= 2^31 - 1`. Thus, the time complexity is O(31) = O(1).


# Minimum Moves to Equal Array Elements II

- slug: minimum-moves-to-equal-array-elements-ii
- difficulty: Medium

Given an integer array `nums` of size `n`, return _the minimum number of moves required to make all array elements equal_.

In one move, you can increment or decrement an element of the array by `1`.

Test cases are designed so that the answer will fit in a **32-bit** integer.

**Example 1:**

**Input:** nums = \[1,2,3\]
**Output:** 2
**Explanation:**
Only two moves are needed (remember each move increments or decrements one element):
\[1,2,3\]  =>  \[2,2,3\]  =>  \[2,2,2\]

**Example 2:**

**Input:** nums = \[1,10,2,9\]
**Output:** 16

**Constraints:**

*   `n == nums.length`
*   `1 <= nums.length <= 105`
*   `-109 <= nums[i] <= 109`

## A solution in Java

```java
public int minMoves2(int[] nums) {
    Arrays.sort(nums);
    int mid = nums[nums.length / 2];
    int moves = 0;
    for (int num : nums) {
        moves += Math.abs(num - mid);
    }
    return moves;
}
```
1. Sort the array `nums` in ascending order.
2. Find the middle element (median) of the sorted array.
3. Initialize a variable `moves` to store the number of moves required.
4. Iterate through the array, and for each element, calculate the absolute difference between the element and the median. Add this difference to the `moves` variable.
5. Return the total `moves`.

The algorithm takes advantage of the fact that the optimal solution is to move all elements towards the median, as it minimizes the total distance between the elements.

## A solution in C++

```cpp
int minMoves2(vector<int>& nums) {
    int n = nums.size();
    sort(nums.begin(), nums.end());
    int mid = nums[n / 2];
    int moves = 0;
    for (int i = 0; i < n; i++) {
        moves += abs(nums[i] - mid);
    }
    return moves;
}
```
1. Sort the array `nums` in ascending order.
2. Find the middle element (median) of the sorted array.
3. Initialize a variable `moves` to store the number of moves required.
4. Iterate through the array, and for each element, calculate the absolute difference between the element and the median. Add this difference to the `moves` variable.
5. Return the total `moves`.

The algorithm takes advantage of the fact that the optimal solution is to move all elements towards the median, as it minimizes the total distance between the elements.

## A solution in Python

```python
def min_moves2(nums):
    nums.sort()
    mid = nums[len(nums) // 2]
    moves = 0
    for num in nums:
        moves += abs(num - mid)
    return moves
```
1. Sort the array `nums` in ascending order.
2. Find the middle element (median) of the sorted array.
3. Initialize a variable `moves` to store the number of moves required.
4. Iterate through the array, and for each element, calculate the absolute difference between the element and the median. Add this difference to the `moves` variable.
5. Return the total `moves`.

The algorithm takes advantage of the fact that the optimal solution is to move all elements towards the median, as it minimizes the total distance between the elements.

## A solution in Javascript

```javascript
function minMoves2(nums) {
    nums.sort((a, b) => a - b);
    const mid = nums[Math.floor(nums.length / 2)];
    let moves = 0;
    for (const num of nums) {
        moves += Math.abs(num - mid);
    }
    return moves;
}
```
1. Sort the array `nums` in ascending order.
2. Find the middle element (median) of the sorted array.
3. Initialize a variable `moves` to store the number of moves required.
4. Iterate through the array, and for each element, calculate the absolute difference between the element and the median. Add this difference to the `moves` variable.
5. Return the total `moves`.

The algorithm takes advantage of the fact that the optimal solution is to move all elements towards the median, as it minimizes the total distance between the elements.