# 3Sum With Multiplicity

- slug: 3sum-with-multiplicity
- difficulty: Medium

Given an integer array `arr`, and an integer `target`, return the number of tuples `i, j, k` such that `i < j < k` and `arr[i] + arr[j] + arr[k] == target`.

As the answer can be very large, return it **modulo** `109 + 7`.

**Example 1:**

**Input:** arr = \[1,1,2,2,3,3,4,4,5,5\], target = 8
**Output:** 20
**Explanation:**
Enumerating by the values (arr\[i\], arr\[j\], arr\[k\]):
(1, 2, 5) occurs 8 times;
(1, 3, 4) occurs 8 times;
(2, 2, 4) occurs 2 times;
(2, 3, 3) occurs 2 times.

**Example 2:**

**Input:** arr = \[1,1,2,2,2,2\], target = 5
**Output:** 12
**Explanation:**
arr\[i\] = 1, arr\[j\] = arr\[k\] = 2 occurs 12 times:
We choose one 1 from \[1,1\] in 2 ways,
and two 2s from \[2,2,2,2\] in 6 ways.

**Example 3:**

**Input:** arr = \[2,1,3\], target = 6
**Output:** 1
**Explanation:** (1, 2, 3) occured one time in the array so we return 1.

**Constraints:**

*   `3 <= arr.length <= 3000`
*   `0 <= arr[i] <= 100`
*   `0 <= target <= 300`

## A solution in Java

```java
int minMoves(int k, int n) {
    if (k == 1 || n == 0 || n == 1) {
        return n;
    }
    int res = Integer.MAX_VALUE;
    for (int i = 1; i <= n; i++) {
        int temp = Math.max(minMoves(k - 1, i - 1), minMoves(k, n - i));
        res = Math.min(res, temp);
    }
    return res + 1;
}
```
The problem can be solved recursively. We start by trying to drop an egg from every floor `i` (1 to `n`). If the egg breaks at floor `i`, the highest `f` could be is floor `i-1` and we have `k-1` eggs left. If it doesn't break, we know `f` is in the range between `i+1` and `n`, so we try with the remaining `n-i` floors, still having `k` eggs.

To find the minimum number of moves, we compare both scenarios: breaking and not breaking. But, we must ensure that we take the worst-case number of moves, so we take the maximum moves between breaking and not breaking. We do this for all floors and pick the minimum number of moves found.

Finally, we return the minimum value found, plus 1, as the value of dropping an egg is also considered a move.

## A solution in C++

```cpp
int min_moves(int k, int n) {
    if (k == 1 || n == 0 || n == 1) {
        return n;
    }
    int res = INT_MAX;
    for (int i = 1; i <= n; i++) {
        int temp = max(min_moves(k - 1, i - 1), min_moves(k, n - i));
        res = min(res, temp);
    }
    return res + 1;
}
```
The problem can be solved recursively. We start by trying to drop an egg from every floor `i` (1 to `n`). If the egg breaks at floor `i`, the highest `f` could be is floor `i-1` and we have `k-1` eggs left. If it doesn't break, we know `f` is in the range between `i+1` and `n`, so we try with the remaining `n-i` floors, still having `k` eggs.

To find the minimum number of moves, we compare both scenarios: breaking and not breaking. But, we must ensure that we take the worst-case number of moves, so we take the maximum moves between breaking and not breaking. We do this for all floors and pick the minimum number of moves found.

Finally, we return the minimum value found, plus 1, as the value of dropping an egg is also considered a move.

## A solution in Python

```python
def min_moves(k, n):
    if k == 1 or n == 0 or n == 1:
        return n

    res = float('inf')
    for i in range(1, n + 1):
        temp = max(min_moves(k - 1, i - 1), min_moves(k, n - i))
        res = min(res, temp)

    return res + 1
```
The problem can be solved recursively. We start by trying to drop an egg from every floor `i` (1 to `n`). If the egg breaks at floor `i`, the highest `f` could be is floor `i-1` and we have `k-1` eggs left. If it doesn't break, we know `f` is in the range between `i+1` and `n`, so we try with the remaining `n-i` floors, still having `k` eggs.

To find the minimum number of moves, we compare both scenarios: breaking and not breaking. But, we must ensure that we take the worst-case number of moves, so we take the maximum moves between breaking and not breaking. We do this for all floors and pick the minimum number of moves found.

Finally, we return the minimum value found, plus 1, as the value of dropping an egg is also considered a move.

## A solution in Javascript

```javascript
function minMoves(k, n) {
    if (k === 1 || n === 0 || n === 1) {
        return n;
    }
    let res = Number.MAX_VALUE;
    for (let i = 1; i <= n; i++) {
        let temp = Math.max(minMoves(k - 1, i - 1), minMoves(k, n - i));
        res = Math.min(res, temp);
    }
    return res + 1;
}
```
The problem can be solved recursively. We start by trying to drop an egg from every floor `i` (1 to `n`). If the egg breaks at floor `i`, the highest `f` could be is floor `i-1` and we have `k-1` eggs left. If it doesn't break, we know `f` is in the range between `i+1` and `n`, so we try with the remaining `n-i` floors, still having `k` eggs.

To find the minimum number of moves, we compare both scenarios: breaking and not breaking. But, we must ensure that we take the worst-case number of moves, so we take the maximum moves between breaking and not breaking. We do this for all floors and pick the minimum number of moves found.

Finally, we return the minimum value found, plus 1, as the value of dropping an egg is also considered a move.


# Minimize Malware Spread

- slug: minimize-malware-spread
- difficulty: Hard

You are given a network of `n` nodes represented as an `n x n` adjacency matrix `graph`, where the `ith` node is directly connected to the `jth` node if `graph[i][j] == 1`.

Some nodes `initial` are initially infected by malware. Whenever two nodes are directly connected, and at least one of those two nodes is infected by malware, both nodes will be infected by malware. This spread of malware will continue until no more nodes can be infected in this manner.

Suppose `M(initial)` is the final number of nodes infected with malware in the entire network after the spread of malware stops. We will remove **exactly one node** from `initial`.

Return the node that, if removed, would minimize `M(initial)`. If multiple nodes could be removed to minimize `M(initial)`, return such a node with **the smallest index**.

Note that if a node was removed from the `initial` list of infected nodes, it might still be infected later due to the malware spread.

**Example 1:**

**Input:** graph = \[\[1,1,0\],\[1,1,0\],\[0,0,1\]\], initial = \[0,1\]
**Output:** 0

**Example 2:**

**Input:** graph = \[\[1,0,0\],\[0,1,0\],\[0,0,1\]\], initial = \[0,2\]
**Output:** 0

**Example 3:**

**Input:** graph = \[\[1,1,1\],\[1,1,1\],\[1,1,1\]\], initial = \[1,2\]
**Output:** 1

**Constraints:**

*   `n == graph.length`
*   `n == graph[i].length`
*   `2 <= n <= 300`
*   `graph[i][j]` is `0` or `1`.
*   `graph[i][j] == graph[j][i]`
*   `graph[i][i] == 1`
*   `1 <= initial.length <= n`
*   `0 <= initial[i] <= n - 1`
*   All the integers in `initial` are **unique**.

## A solution in Java

```java
public int[] fairCandySwap(int[] aliceSizes, int[] bobSizes) {
    int aliceTotal = 0, bobTotal = 0;
    for (int candy : aliceSizes) aliceTotal += candy;
    for (int candy : bobSizes) bobTotal += candy;

    int delta = (bobTotal - aliceTotal) / 2;
    for (int a : aliceSizes) {
        for (int b : bobSizes) {
            if (a + delta == b) {
                return new int[]{a, b};
            }
        }
    }
    return new int[]{};
}
```
1. Calculate the total number of candies for both Alice and Bob by summing their respective arrays.
2. Calculate the difference between their totals divided by 2. This will be the amount needed to balance their candies after the swap.
3. Iterate over both arrays (nested loop), and if a value from Alice's array plus the calculated difference equals a value from Bob's array, return the pair as the answer. This is because swapping these two boxes would result in equal total candies for both.
4. If no such pair is found (which is not possible as per the given problem statement), return an empty array or list based on the language.

## A solution in C++

```cpp
#include <vector>

std::vector<int> fairCandySwap(std::vector<int>& aliceSizes, std::vector<int>& bobSizes) {
    int aliceTotal = 0, bobTotal = 0;
    for (int candy : aliceSizes) aliceTotal += candy;
    for (int candy : bobSizes) bobTotal += candy;

    int delta = (bobTotal - aliceTotal) / 2;
    for (int a : aliceSizes) {
        for (int b : bobSizes) {
            if (a + delta == b) {
                return {a, b};
            }
        }
    }
    return {};
}
```
1. Calculate the total number of candies for both Alice and Bob by summing their respective arrays.
2. Calculate the difference between their totals divided by 2. This will be the amount needed to balance their candies after the swap.
3. Iterate over both arrays (nested loop), and if a value from Alice's array plus the calculated difference equals a value from Bob's array, return the pair as the answer. This is because swapping these two boxes would result in equal total candies for both.
4. If no such pair is found (which is not possible as per the given problem statement), return an empty array or list based on the language.

## A solution in Python

```python
def fair_candy_swap(aliceSizes, bobSizes):
    aliceTotal, bobTotal = sum(aliceSizes), sum(bobSizes)
    delta = (bobTotal - aliceTotal) // 2
    for a in aliceSizes:
        for b in bobSizes:
            if a + delta == b:
                return [a, b]
    return []
```
1. Calculate the total number of candies for both Alice and Bob by summing their respective arrays.
2. Calculate the difference between their totals divided by 2. This will be the amount needed to balance their candies after the swap.
3. Iterate over both arrays (nested loop), and if a value from Alice's array plus the calculated difference equals a value from Bob's array, return the pair as the answer. This is because swapping these two boxes would result in equal total candies for both.
4. If no such pair is found (which is not possible as per the given problem statement), return an empty array or list based on the language.

## A solution in Javascript

```javascript
function fairCandySwap(aliceSizes, bobSizes) {
    const aliceTotal = aliceSizes.reduce((a, b) => a + b, 0);
    const bobTotal = bobSizes.reduce((a, b) => a + b, 0);

    const delta = (bobTotal - aliceTotal) / 2;
    for (const a of aliceSizes) {
        for (const b of bobSizes) {
            if (a + delta === b) {
                return [a, b];
            }
        }
    }
    return [];
}
```
1. Calculate the total number of candies for both Alice and Bob by summing their respective arrays.
2. Calculate the difference between their totals divided by 2. This will be the amount needed to balance their candies after the swap.
3. Iterate over both arrays (nested loop), and if a value from Alice's array plus the calculated difference equals a value from Bob's array, return the pair as the answer. This is because swapping these two boxes would result in equal total candies for both.
4. If no such pair is found (which is not possible as per the given problem statement), return an empty array or list based on the language.


# Long Pressed Name

- slug: long-pressed-name
- difficulty: Easy

Your friend is typing his `name` into a keyboard. Sometimes, when typing a character `c`, the key might get _long pressed_, and the character will be typed 1 or more times.

You examine the `typed` characters of the keyboard. Return `True` if it is possible that it was your friends name, with some characters (possibly none) being long pressed.

**Example 1:**

**Input:** name =  "alex ", typed =  "aaleex "
**Output:** true
**Explanation:** 'a' and 'e' in 'alex' were long pressed.

**Example 2:**

**Input:** name =  "saeed ", typed =  "ssaaedd "
**Output:** false
**Explanation:** 'e' must have been pressed twice, but it was not in the typed output.

**Constraints:**

*   `1 <= name.length, typed.length <= 1000`
*   `name` and `typed` consist of only lowercase English letters.

## A solution in Java

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

class Solution {
    public TreeNode constructFromPrePost(int[] pre, int[] post) {
        return buildTree(pre, 0, pre.length, post, 0, post.length);
    }

    private TreeNode buildTree(int[] pre, int preStart, int preEnd, int[] post, int postStart, int postEnd) {
        if (preStart == preEnd) return null;

        TreeNode root = new TreeNode(pre[preStart]);

        if (preStart + 1 == preEnd) return root;

        int leftRoot = pre[preStart + 1];

        int leftSize = 0;
        for (int i = postStart; i < postEnd; ++i) {
            if (post[i] == leftRoot) {
                leftSize = i - postStart + 1;
                break;
            }
        }

        root.left = buildTree(pre, preStart + 1, preStart + 1 + leftSize, post, postStart, postStart + leftSize);
        root.right = buildTree(pre, preStart + 1 + leftSize, preEnd, post, postStart + leftSize, postEnd - 1);

        return root;
    }
}
```
The reconstruction of binary tree can be done using a divide-and-conquer strategy.

1. The first element of the preorder array is the root node.
2. The second element of the preorder array is the root of the left subtree.
3. Find the index of the left subtree root in the postorder array. The left subtree size can be calculated as `index - postStart + 1`.
4. The left subtree ranges can be found using `preStart + 1` and `preStart + 1 + leftSize` in the preorder array, `postStart` and `postStart + leftSize` in the postorder array.
5. The right subtree ranges can be found with `preStart + 1 + leftSize` and `preEnd` in the preorder array, `postStart + leftSize` and `postEnd - 1` in the postorder array.
6. Recursively build the left subtree and right subtree with the calculated ranges.
7. Connect the left subtree and right subtree to the current root node.

The overall time complexity is O(N^2) due to finding the index of the left subtree root. The space complexity is O(N) because of the recursion stack.

## A solution in C++

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

class Solution {
public:
    TreeNode* constructFromPrePost(vector<int>& preorder, vector<int>& postorder) {
        return buildTree(preorder, 0, preorder.size(), postorder, 0, postorder.size());
    }

    TreeNode* buildTree(vector<int>& pre, int preStart, int preEnd, vector<int>& post, int postStart, int postEnd) {
        if (preStart == preEnd) return nullptr;

        TreeNode* root = new TreeNode(pre[preStart]);

        if (preStart + 1 == preEnd) return root;

        int leftRoot = pre[preStart + 1];

        int leftSize = 0;
        for (int i = postStart; i < postEnd; ++i) {
            if (post[i] == leftRoot) {
                leftSize = i - postStart + 1;
                break;
            }
        }

        root->left = buildTree(pre, preStart + 1, preStart + 1 + leftSize, post, postStart, postStart + leftSize);
        root->right = buildTree(pre, preStart + 1 + leftSize, preEnd, post, postStart + leftSize, postEnd - 1);

        return root;
    }
};
```
The reconstruction of binary tree can be done using a divide-and-conquer strategy.

1. The first element of the preorder array is the root node.
2. The second element of the preorder array is the root of the left subtree.
3. Find the index of the left subtree root in the postorder array. The left subtree size can be calculated as `index - postStart + 1`.
4. The left subtree ranges can be found using `preStart + 1` and `preStart + 1 + leftSize` in the preorder array, `postStart` and `postStart + leftSize` in the postorder array.
5. The right subtree ranges can be found with `preStart + 1 + leftSize` and `preEnd` in the preorder array, `postStart + leftSize` and `postEnd - 1` in the postorder array.
6. Recursively build the left subtree and right subtree with the calculated ranges.
7. Connect the left subtree and right subtree to the current root node.

The overall time complexity is O(N^2) due to finding the index of the left subtree root. The space complexity is O(N) because of the recursion stack.

## A solution in Python

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

class Solution:
    def constructFromPrePost(self, pre, post):
        def buildTree(preStart, preEnd, postStart, postEnd):
            if preStart == preEnd:
                return None

            root = TreeNode(pre[preStart])

            if preStart + 1 == preEnd:
                return root

            leftRoot = pre[preStart + 1]

            leftSize = 0
            for i in range(postStart, postEnd):
                if post[i] == leftRoot:
                    leftSize = i - postStart + 1
                    break

            root.left = buildTree(preStart + 1, preStart + 1 + leftSize, postStart, postStart + leftSize)
            root.right = buildTree(preStart + 1 + leftSize, preEnd, postStart + leftSize, postEnd - 1)

            return root

        return buildTree(0, len(pre), 0, len(post))
```
The reconstruction of binary tree can be done using a divide-and-conquer strategy.

1. The first element of the preorder array is the root node.
2. The second element of the preorder array is the root of the left subtree.
3. Find the index of the left subtree root in the postorder array. The left subtree size can be calculated as `index - postStart + 1`.
4. The left subtree ranges can be found using `preStart + 1` and `preStart + 1 + leftSize` in the preorder array, `postStart` and `postStart + leftSize` in the postorder array.
5. The right subtree ranges can be found with `preStart + 1 + leftSize` and `preEnd` in the preorder array, `postStart + leftSize` and `postEnd - 1` in the postorder array.
6. Recursively build the left subtree and right subtree with the calculated ranges.
7. Connect the left subtree and right subtree to the current root node.

The overall time complexity is O(N^2) due to finding the index of the left subtree root. The space complexity is O(N) because of the recursion stack.

## A solution in Javascript

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

function constructFromPrePost(pre, post) {
    function buildTree(preStart, preEnd, postStart, postEnd) {
        if (preStart === preEnd) return null;

        let root = new TreeNode(pre[preStart]);

        if (preStart + 1 === preEnd) return root;

        let leftRoot = pre[preStart + 1];

        let leftSize = 0;
        for (let i = postStart; i < postEnd; ++i) {
            if (post[i] === leftRoot) {
                leftSize = i - postStart + 1;
                break;
            }
        }

        root.left = buildTree(preStart + 1, preStart + 1 + leftSize, postStart, postStart + leftSize);
        root.right = buildTree(preStart + 1 + leftSize, preEnd, postStart + leftSize, postEnd - 1);

        return root;
    }

    return buildTree(0, pre.length, 0, post.length);
}
```
The reconstruction of binary tree can be done using a divide-and-conquer strategy.

1. The first element of the preorder array is the root node.
2. The second element of the preorder array is the root of the left subtree.
3. Find the index of the left subtree root in the postorder array. The left subtree size can be calculated as `index - postStart + 1`.
4. The left subtree ranges can be found using `preStart + 1` and `preStart + 1 + leftSize` in the preorder array, `postStart` and `postStart + leftSize` in the postorder array.
5. The right subtree ranges can be found with `preStart + 1 + leftSize` and `preEnd` in the preorder array, `postStart + leftSize` and `postEnd - 1` in the postorder array.
6. Recursively build the left subtree and right subtree with the calculated ranges.
7. Connect the left subtree and right subtree to the current root node.

The overall time complexity is O(N^2) due to finding the index of the left subtree root. The space complexity is O(N) because of the recursion stack.


# Flip String to Monotone Increasing

- slug: flip-string-to-monotone-increasing
- difficulty: Medium

A binary string is monotone increasing if it consists of some number of `0`'s (possibly none), followed by some number of `1`'s (also possibly none).

You are given a binary string `s`. You can flip `s[i]` changing it from `0` to `1` or from `1` to `0`.

Return _the minimum number of flips to make_ `s` _monotone increasing_.

**Example 1:**

**Input:** s =  "00110 "
**Output:** 1
**Explanation:** We flip the last digit to get 00111.

**Example 2:**

**Input:** s =  "010110 "
**Output:** 2
**Explanation:** We flip to get 011111, or alternatively 000111.

**Example 3:**

**Input:** s =  "00011000 "
**Output:** 2
**Explanation:** We flip to get 00000000.

**Constraints:**

*   `1 <= s.length <= 105`
*   `s[i]` is either `'0'` or `'1'`.

## A solution in Java

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

public List<String> findAndReplacePatterns(String[] words, String pattern) {
    List<String> result = new ArrayList<>();
    for (String word : words) {
        if (word.length() != pattern.length()) continue;

        Map<Character, Character> w2p = new HashMap<>();
        Map<Character, Character> p2w = new HashMap<>();
        boolean matches = true;
        for (int i = 0; i < word.length(); ++i) {
            char cWord = word.charAt(i);
            char cPattern = pattern.charAt(i);

            if (!w2p.containsKey(cWord)) w2p.put(cWord, cPattern);
            if (!p2w.containsKey(cPattern)) p2w.put(cPattern, cWord);

            if (w2p.get(cWord) != cPattern || p2w.get(cPattern) != cWord) {
                matches = false;
                break;
            }
        }
        if (matches) result.add(word);
    }
    return result;
}
```
1. Initialize an empty list (or vector) `result` to store the words that match the pattern.
2. Iterate through the given list of words.
   a. If the current word has a different length than the pattern, skip it as it will not match.
   b. Create two maps (hashmaps or dictionaries) called `w2p` and `p2w` to store the current word-to-pattern and pattern-to-word character mappings.
   c. Iterate through the characters of the current word and the pattern at the same time.
      i. If the current character in the word is not in `w2p`, add it with the corresponding character in the pattern.
      ii. If the current character in the pattern is not in `p2w`, add it with the corresponding character in the word.
      iii. If the current character mappings do not match, set `matches` to false and break the loop.
   d. If `matches` is true, add the current word to `result`.
3. Return `result`.

## A solution in C++

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

std::vector<std::string> findAndReplacePatterns(std::vector<std::string>& words, std::string pattern) {
    std::vector<std::string> result;
    for (const std::string& word : words) {
        if (word.size() != pattern.size()) continue;

        std::unordered_map<char, char> w2p;
        std::unordered_map<char, char> p2w;
        bool matches = true;
        for (size_t i = 0; i < word.size(); ++i) {
            char cWord = word[i];
            char cPattern = pattern[i];

            if (!w2p.count(cWord)) w2p[cWord] = cPattern;
            if (!p2w.count(cPattern)) p2w[cPattern] = cWord;

            if (w2p[cWord] != cPattern || p2w[cPattern] != cWord) {
                matches = false;
                break;
            }
        }
        if (matches) result.push_back(word);
    }
    return result;
}
```
1. Initialize an empty list (or vector) `result` to store the words that match the pattern.
2. Iterate through the given list of words.
   a. If the current word has a different length than the pattern, skip it as it will not match.
   b. Create two maps (hashmaps or dictionaries) called `w2p` and `p2w` to store the current word-to-pattern and pattern-to-word character mappings.
   c. Iterate through the characters of the current word and the pattern at the same time.
      i. If the current character in the word is not in `w2p`, add it with the corresponding character in the pattern.
      ii. If the current character in the pattern is not in `p2w`, add it with the corresponding character in the word.
      iii. If the current character mappings do not match, set `matches` to false and break the loop.
   d. If `matches` is true, add the current word to `result`.
3. Return `result`.

## A solution in Python

```python
def find_and_replace_patterns(words, pattern):
    result = []
    for word in words:
        if len(word) != len(pattern): continue

        w2p = {}
        p2w = {}
        matches = True
        for cWord, cPattern in zip(word, pattern):
            if cWord not in w2p: w2p[cWord] = cPattern
            if cPattern not in p2w: p2w[cPattern] = cWord

            if w2p[cWord] != cPattern or p2w[cPattern] != cWord:
                matches = False
                break

        if matches: result.append(word)
    return result
```
1. Initialize an empty list (or vector) `result` to store the words that match the pattern.
2. Iterate through the given list of words.
   a. If the current word has a different length than the pattern, skip it as it will not match.
   b. Create two maps (hashmaps or dictionaries) called `w2p` and `p2w` to store the current word-to-pattern and pattern-to-word character mappings.
   c. Iterate through the characters of the current word and the pattern at the same time.
      i. If the current character in the word is not in `w2p`, add it with the corresponding character in the pattern.
      ii. If the current character in the pattern is not in `p2w`, add it with the corresponding character in the word.
      iii. If the current character mappings do not match, set `matches` to false and break the loop.
   d. If `matches` is true, add the current word to `result`.
3. Return `result`.

## A solution in Javascript

```javascript
function findAndReplacePatterns(words, pattern) {
    const result = [];
    for (const word of words) {
        if (word.length !== pattern.length) continue;

        const w2p = new Map();
        const p2w = new Map();
        let matches = true;
        for (let i = 0; i < word.length; ++i) {
            const cWord = word[i];
            const cPattern = pattern[i];

            if (!w2p.has(cWord)) w2p.set(cWord, cPattern);
            if (!p2w.has(cPattern)) p2w.set(cPattern, cWord);

            if (w2p.get(cWord) !== cPattern || p2w.get(cPattern) !== cWord) {
                matches = false;
                break;
            }
        }
        if (matches) result.push(word);
    }
    return result;
}
```
1. Initialize an empty list (or vector) `result` to store the words that match the pattern.
2. Iterate through the given list of words.
   a. If the current word has a different length than the pattern, skip it as it will not match.
   b. Create two maps (hashmaps or dictionaries) called `w2p` and `p2w` to store the current word-to-pattern and pattern-to-word character mappings.
   c. Iterate through the characters of the current word and the pattern at the same time.
      i. If the current character in the word is not in `w2p`, add it with the corresponding character in the pattern.
      ii. If the current character in the pattern is not in `p2w`, add it with the corresponding character in the word.
      iii. If the current character mappings do not match, set `matches` to false and break the loop.
   d. If `matches` is true, add the current word to `result`.
3. Return `result`.


# Three Equal Parts

- slug: three-equal-parts
- difficulty: Hard

You are given an array `arr` which consists of only zeros and ones, divide the array into **three non-empty parts** such that all of these parts represent the same binary value.

If it is possible, return any `[i, j]` with `i + 1 < j`, such that:

*   `arr[0], arr[1], ..., arr[i]` is the first part,
*   `arr[i + 1], arr[i + 2], ..., arr[j - 1]` is the second part, and
*   `arr[j], arr[j + 1], ..., arr[arr.length - 1]` is the third part.
*   All three parts have equal binary values.

If it is not possible, return `[-1, -1]`.

Note that the entire part is used when considering what binary value it represents. For example, `[1,1,0]` represents `6` in decimal, not `3`. Also, leading zeros **are allowed**, so `[0,1,1]` and `[1,1]` represent the same value.

**Example 1:**

**Input:** arr = \[1,0,1,0,1\]
**Output:** \[0,3\]

**Example 2:**

**Input:** arr = \[1,1,0,1,1\]
**Output:** \[-1,-1\]

**Example 3:**

**Input:** arr = \[1,1,0,0,1\]
**Output:** \[0,2\]

**Constraints:**

*   `3 <= arr.length <= 3 * 104`
*   `arr[i]` is `0` or `1`

## A solution in Java

```java
import java.util.Arrays;

public class Solution {
    private static final int MOD = 1000000007;

    public int sumOfWidths(int[] nums) {
        Arrays.sort(nums);
        int n = nums.length;
        long res = 0, c = 1;

        for (int i = 0; i < n; i++, c = c * 2 % MOD)
            res = (res + (nums[i] - nums[n - i - 1]) * c) % MOD;

        return (int) res;
    }
}
```
1. Sort the given array of integers, nums, in ascending order.
2. Initialize a variable, res, to store the final result, and another variable, c, to keep track of the power of 2.
3. Iterate through the sorted nums array.
4. For each element, calculate the difference between the current element and the corresponding element from the end of the array. Multiply the difference by the current value of c and add the result to res.
5. Update the value of c by multiplying it by 2 and taking the modulo value.
6. Continue this process until the entire nums array has been traversed.
7. Return the final value of res modulo 10^9 + 7.

## A solution in C++

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

const int MOD = 1e9 + 7;

int sumOfWidths(std::vector<int>& nums) {
    int n = nums.size();
    std::sort(nums.begin(), nums.end());
    long long res = 0, c = 1;

    for (int i = 0; i < n; i++, c = c * 2 % MOD)
        res = (res + (nums[i] - nums[n - i - 1]) * c) % MOD;

    return res;
}
```
1. Sort the given array of integers, nums, in ascending order.
2. Initialize a variable, res, to store the final result, and another variable, c, to keep track of the power of 2.
3. Iterate through the sorted nums array.
4. For each element, calculate the difference between the current element and the corresponding element from the end of the array. Multiply the difference by the current value of c and add the result to res.
5. Update the value of c by multiplying it by 2 and taking the modulo value.
6. Continue this process until the entire nums array has been traversed.
7. Return the final value of res modulo 10^9 + 7.

## A solution in Python

```python
def sum_of_widths(nums):
    MOD = 10**9 + 7
    nums.sort()
    c, res = 1, 0
    n = len(nums)

    for i in range(n):
        res = (res + (nums[i] - nums[n - i - 1]) * c) % MOD
        c = c * 2 % MOD

    return res
```
1. Sort the given array of integers, nums, in ascending order.
2. Initialize a variable, res, to store the final result, and another variable, c, to keep track of the power of 2.
3. Iterate through the sorted nums array.
4. For each element, calculate the difference between the current element and the corresponding element from the end of the array. Multiply the difference by the current value of c and add the result to res.
5. Update the value of c by multiplying it by 2 and taking the modulo value.
6. Continue this process until the entire nums array has been traversed.
7. Return the final value of res modulo 10^9 + 7.

## A solution in Javascript

```javascript
function sumOfWidths(nums) {
    const MOD = 1e9 + 7;
    nums.sort((a, b) => a - b);
    let res = 0, c = 1, n = nums.length;

    for (let i = 0; i < n; i++, c = (c * 2) % MOD)
        res = (res + (nums[i] - nums[n - i - 1]) * c) % MOD;

    return res;
}
```
1. Sort the given array of integers, nums, in ascending order.
2. Initialize a variable, res, to store the final result, and another variable, c, to keep track of the power of 2.
3. Iterate through the sorted nums array.
4. For each element, calculate the difference between the current element and the corresponding element from the end of the array. Multiply the difference by the current value of c and add the result to res.
5. Update the value of c by multiplying it by 2 and taking the modulo value.
6. Continue this process until the entire nums array has been traversed.
7. Return the final value of res modulo 10^9 + 7.


# Minimize Malware Spread II

- slug: minimize-malware-spread-ii
- difficulty: Hard

You are given a network of `n` nodes represented as an `n x n` adjacency matrix `graph`, where the `ith` node is directly connected to the `jth` node if `graph[i][j] == 1`.

Some nodes `initial` are initially infected by malware. Whenever two nodes are directly connected, and at least one of those two nodes is infected by malware, both nodes will be infected by malware. This spread of malware will continue until no more nodes can be infected in this manner.

Suppose `M(initial)` is the final number of nodes infected with malware in the entire network after the spread of malware stops.

We will remove **exactly one node** from `initial`, **completely removing it and any connections from this node to any other node**.

Return the node that, if removed, would minimize `M(initial)`. If multiple nodes could be removed to minimize `M(initial)`, return such a node with **the smallest index**.

**Example 1:**

**Input:** graph = \[\[1,1,0\],\[1,1,0\],\[0,0,1\]\], initial = \[0,1\]
**Output:** 0

**Example 2:**

**Input:** graph = \[\[1,1,0\],\[1,1,1\],\[0,1,1\]\], initial = \[0,1\]
**Output:** 1

**Example 3:**

**Input:** graph = \[\[1,1,0,0\],\[1,1,1,0\],\[0,1,1,1\],\[0,0,1,1\]\], initial = \[0,1\]
**Output:** 1

**Constraints:**

*   `n == graph.length`
*   `n == graph[i].length`
*   `2 <= n <= 300`
*   `graph[i][j]` is `0` or `1`.
*   `graph[i][j] == graph[j][i]`
*   `graph[i][i] == 1`
*   `1 <= initial.length < n`
*   `0 <= initial[i] <= n - 1`
*   All the integers in `initial` are **unique**.

## A solution in Java

```java
public int surfaceArea(int[][] grid) {
    int n = grid.length;
    int area = 0;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (grid[i][j] > 0) {
                area += 4 * grid[i][j] + 2;
                if (i > 0) area -= 2 * Math.min(grid[i][j], grid[i - 1][j]);
                if (j > 0) area -= 2 * Math.min(grid[i][j], grid[i][j - 1]);
            }
        }
    }

    return area;
}
```
The algorithm iterates through each cell of the given n x n grid. For each cell with value v, the total surface area of the tower of cubes is calculated using the formula `4 * v + 2` (4 sides, top and bottom), plus the adjacent cells' shared side areas. During each iteration, in order to avoid over-counting the shared sides between adjacent cells, we subtract 2 times the minimum of the current cell's height and the adjacent cell's height (for both the left and top neighbors). This way, the result will only take into account the visible surface areas of each shape without considering the shared sides. The final result is the total surface area of all the shapes.

## A solution in C++

```cpp
int surfaceArea(vector<vector<int>>& grid) {
    int n = grid.size();
    int area = 0;

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            if (grid[i][j]) {
                area += 4 * grid[i][j] + 2;
                if (i > 0) area -= 2 * min(grid[i][j], grid[i - 1][j]);
                if (j > 0) area -= 2 * min(grid[i][j], grid[i][j - 1]);
            }
        }
    }

    return area;
}
```
The algorithm iterates through each cell of the given n x n grid. For each cell with value v, the total surface area of the tower of cubes is calculated using the formula `4 * v + 2` (4 sides, top and bottom), plus the adjacent cells' shared side areas. During each iteration, in order to avoid over-counting the shared sides between adjacent cells, we subtract 2 times the minimum of the current cell's height and the adjacent cell's height (for both the left and top neighbors). This way, the result will only take into account the visible surface areas of each shape without considering the shared sides. The final result is the total surface area of all the shapes.

## A solution in Python

```python
def surfaceArea(grid):
    n = len(grid)
    area = 0

    for i in range(n):
        for j in range(n):
            if grid[i][j]:
                area += 4 * grid[i][j] + 2
                if i > 0:
                    area -= 2 * min(grid[i][j], grid[i - 1][j])
                if j > 0:
                    area -= 2 * min(grid[i][j], grid[i][j - 1])

    return area
```
The algorithm iterates through each cell of the given n x n grid. For each cell with value v, the total surface area of the tower of cubes is calculated using the formula `4 * v + 2` (4 sides, top and bottom), plus the adjacent cells' shared side areas. During each iteration, in order to avoid over-counting the shared sides between adjacent cells, we subtract 2 times the minimum of the current cell's height and the adjacent cell's height (for both the left and top neighbors). This way, the result will only take into account the visible surface areas of each shape without considering the shared sides. The final result is the total surface area of all the shapes.

## A solution in Javascript

```javascript
function surfaceArea(grid) {
    const n = grid.length;
    let area = 0;

    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
            if (grid[i][j] > 0) {
                area += 4 * grid[i][j] + 2;
                if (i > 0) area -= 2 * Math.min(grid[i][j], grid[i - 1][j]);
                if (j > 0) area -= 2 * Math.min(grid[i][j], grid[i][j - 1]);
            }
        }
    }

    return area;
}
```
The algorithm iterates through each cell of the given n x n grid. For each cell with value v, the total surface area of the tower of cubes is calculated using the formula `4 * v + 2` (4 sides, top and bottom), plus the adjacent cells' shared side areas. During each iteration, in order to avoid over-counting the shared sides between adjacent cells, we subtract 2 times the minimum of the current cell's height and the adjacent cell's height (for both the left and top neighbors). This way, the result will only take into account the visible surface areas of each shape without considering the shared sides. The final result is the total surface area of all the shapes.


# Unique Email Addresses

- slug: unique-email-addresses
- difficulty: Easy

Every **valid email** consists of a **local name** and a **domain name**, separated by the `'@'` sign. Besides lowercase letters, the email may contain one or more `'.'` or `'+'`.

*   For example, in `"alice@leetcode.com "`, `"alice "` is the **local name**, and `"leetcode.com "` is the **domain name**.

If you add periods `'.'` between some characters in the **local name** part of an email address, mail sent there will be forwarded to the same address without dots in the local name. Note that this rule **does not apply** to **domain names**.

*   For example, `"alice.z@leetcode.com "` and `"alicez@leetcode.com "` forward to the same email address.

If you add a plus `'+'` in the **local name**, everything after the first plus sign **will be ignored**. This allows certain emails to be filtered. Note that this rule **does not apply** to **domain names**.

*   For example, `"m.y+name@email.com "` will be forwarded to `"my@email.com "`.

It is possible to use both of these rules at the same time.

Given an array of strings `emails` where we send one email to each `emails[i]`, return _the number of different addresses that actually receive mails_.

**Example 1:**

**Input:** emails = \[ "test.email+alex@leetcode.com ", "test.e.mail+bob.cathy@leetcode.com ", "testemail+david@lee.tcode.com "\]
**Output:** 2
**Explanation:**  "testemail@leetcode.com " and  "testemail@lee.tcode.com " actually receive mails.

**Example 2:**

**Input:** emails = \[ "a@leetcode.com ", "b@leetcode.com ", "c@leetcode.com "\]
**Output:** 3

**Constraints:**

*   `1 <= emails.length <= 100`
*   `1 <= emails[i].length <= 100`
*   `emails[i]` consist of lowercase English letters, `'+'`, `'.'` and `'@'`.
*   Each `emails[i]` contains exactly one `'@'` character.
*   All local and domain names are non-empty.
*   Local names do not start with a `'+'` character.
*   Domain names end with the `".com "` suffix.

## A solution in Java

```java
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays;

public int numSpecialEquivalentGroups(String[] words) {
    Set<String> groups = new HashSet<>();

    for (String word : words) {
        StringBuilder evens = new StringBuilder();
        StringBuilder odds = new StringBuilder();

        for (int i = 0; i < word.length(); ++i) {
            if (i % 2 == 0) evens.append(word.charAt(i));
            else odds.append(word.charAt(i));
        }

        char[] evenArr = evens.toString().toCharArray();
        Arrays.sort(evenArr);
        char[] oddArr = odds.toString().toCharArray();
        Arrays.sort(oddArr);

        groups.add(new String(evenArr) + new String(oddArr));
    }

    return groups.size();
}
```
1. Initialize an empty set to store the unique groups.
2. For each word in the input list:
   a. Initialize two empty strings `evens` and `odds` to store even and odd indexed characters.
   b. Iterate through the word, and for each character, append it to either `evens` or `odds` based on its index being even or odd.
   c. Sort the `evens` and `odds` strings.
   d. Concatenate `evens` and `odds`, and insert the result into the set. If this string is already in the set, it doesn't get duplicated.
3. Return the size of the set, which represents the number of unique groups.

## A solution in C++

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

int numSpecialEquivalentGroups(std::vector<std::string>& words) {
    std::unordered_set<std::string> groups;

    for (std::string word : words) {
        std::string evens, odds;

        for (size_t i = 0; i < word.size(); ++i) {
            if (i % 2 == 0) evens += word[i];
            else odds += word[i];
        }

        std::sort(evens.begin(), evens.end());
        std::sort(odds.begin(), odds.end());

        groups.insert(evens + odds);
    }

    return groups.size();
}
```
1. Initialize an empty set to store the unique groups.
2. For each word in the input list:
   a. Initialize two empty strings `evens` and `odds` to store even and odd indexed characters.
   b. Iterate through the word, and for each character, append it to either `evens` or `odds` based on its index being even or odd.
   c. Sort the `evens` and `odds` strings.
   d. Concatenate `evens` and `odds`, and insert the result into the set. If this string is already in the set, it doesn't get duplicated.
3. Return the size of the set, which represents the number of unique groups.

## A solution in Python

```python
def num_special_equivalent_groups(words):
    groups = set()

    for word in words:
        evens = "".join(sorted(word[0::2]))
        odds = "".join(sorted(word[1::2]))

        groups.add(evens + odds)

    return len(groups)
```
1. Initialize an empty set to store the unique groups.
2. For each word in the input list:
   a. Initialize two empty strings `evens` and `odds` to store even and odd indexed characters.
   b. Iterate through the word, and for each character, append it to either `evens` or `odds` based on its index being even or odd.
   c. Sort the `evens` and `odds` strings.
   d. Concatenate `evens` and `odds`, and insert the result into the set. If this string is already in the set, it doesn't get duplicated.
3. Return the size of the set, which represents the number of unique groups.

## A solution in Javascript

```javascript
function numSpecialEquivalentGroups(words) {
    const groups = new Set();

    for (const word of words) {
        let evens = "";
        let odds = "";

        for (let i = 0; i < word.length; ++i) {
            if (i % 2 === 0) evens += word[i];
            else odds += word[i];
        }

        evens = evens.split("").sort().join("");
        odds = odds.split("").sort().join("");

        groups.add(evens + odds);
    }

    return groups.size;
}
```
1. Initialize an empty set to store the unique groups.
2. For each word in the input list:
   a. Initialize two empty strings `evens` and `odds` to store even and odd indexed characters.
   b. Iterate through the word, and for each character, append it to either `evens` or `odds` based on its index being even or odd.
   c. Sort the `evens` and `odds` strings.
   d. Concatenate `evens` and `odds`, and insert the result into the set. If this string is already in the set, it doesn't get duplicated.
3. Return the size of the set, which represents the number of unique groups.


# Binary Subarrays With Sum

- slug: binary-subarrays-with-sum
- difficulty: Medium

Given a binary array `nums` and an integer `goal`, return _the number of non-empty **subarrays** with a sum_ `goal`.

A **subarray** is a contiguous part of the array.

**Example 1:**

**Input:** nums = \[1,0,1,0,1\], goal = 2
**Output:** 4
**Explanation:** The 4 subarrays are bolded and underlined below:
\[**1,0,1**,0,1\]
\[**1,0,1,0**,1\]
\[1,**0,1,0,1**\]
\[1,0,**1,0,1**\]

**Example 2:**

**Input:** nums = \[0,0,0,0,0\], goal = 0
**Output:** 15

**Constraints:**

*   `1 <= nums.length <= 3 * 104`
*   `nums[i]` is either `0` or `1`.
*   `0 <= goal <= nums.length`

## A solution in Java

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

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

public List<TreeNode> allPossibleFBT(int n) {
    if (n % 2 == 0) return new ArrayList<>();
    if (n == 1) {
        List<TreeNode> result = new ArrayList<>();
        result.add(new TreeNode(0));
        return result;
    }

    List<TreeNode> result = new ArrayList<>();
    for (int i = 1; i < n; i += 2) {
        List<TreeNode> left = allPossibleFBT(i);
        List<TreeNode> right = allPossibleFBT(n - i - 1);
        for (TreeNode l : left) {
            for (TreeNode r : right) {
                TreeNode root = new TreeNode(0);
                root.left = l;
                root.right = r;
                result.add(root);
            }
        }
    }
    return result;
}
```
The algorithm is based on a recursive approach to build all possible full binary trees. Given an odd integer `n`, the tree will have `n` nodes. We perform a loop over all odd numbers smaller than `n`, considering each `i` as the number of nodes in the left subtree. The right subtree will have `n-i-1` nodes.

In each iteration, we recursively generate all possible full binary trees with `i` nodes for the left subtree and `n-i-1` nodes for the right subtree. We then combine all trees by pairing each left subtree with each right subtree and set the paired trees as children of a new root node `0`. The generated tree is a full binary tree with `n` nodes.

All resulting trees are appended to the result list. The recursion base case occurs when `n` is even (no possible full binary tree) or `n == 1` (the single node tree).

The time complexity of the algorithm is O(n * C(n)) when n is odd, where C(n) are the n-th catalan numbers, and O(1) when n is even. The space complexity is also O(n * C(n)) when n is odd, due to the generated trees.

## A solution in C++

```cpp
#include <vector>

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int _val) : val(_val), left(NULL), right(NULL) {}
};

std::vector<TreeNode*> allPossibleFBT(int n) {
    if (n % 2 == 0) return {};
    if (n == 1) return { new TreeNode(0) };

    std::vector<TreeNode*> result;
    for (int i = 1; i < n; i += 2) {
        std::vector<TreeNode*> left = allPossibleFBT(i);
        std::vector<TreeNode*> right = allPossibleFBT(n - i - 1);
        for (TreeNode* l : left) {
            for (TreeNode* r : right) {
                TreeNode* root = new TreeNode(0);
                root->left = l;
                root->right = r;
                result.push_back(root);
            }
        }
    }
    return result;
}
```
The algorithm is based on a recursive approach to build all possible full binary trees. Given an odd integer `n`, the tree will have `n` nodes. We perform a loop over all odd numbers smaller than `n`, considering each `i` as the number of nodes in the left subtree. The right subtree will have `n-i-1` nodes.

In each iteration, we recursively generate all possible full binary trees with `i` nodes for the left subtree and `n-i-1` nodes for the right subtree. We then combine all trees by pairing each left subtree with each right subtree and set the paired trees as children of a new root node `0`. The generated tree is a full binary tree with `n` nodes.

All resulting trees are appended to the result list. The recursion base case occurs when `n` is even (no possible full binary tree) or `n == 1` (the single node tree).

The time complexity of the algorithm is O(n * C(n)) when n is odd, where C(n) are the n-th catalan numbers, and O(1) when n is even. The space complexity is also O(n * C(n)) when n is odd, due to the generated trees.

## A solution in Python

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

def all_possible_FBT(n):
    if n % 2 == 0:
        return []
    if n == 1:
        return [TreeNode(0)]

    result = []
    for i in range(1, n, 2):
        left = all_possible_FBT(i)
        right = all_possible_FBT(n - i - 1)
        for l in left:
            for r in right:
                root = TreeNode(0)
                root.left = l
                root.right = r
                result.append(root)
    return result
```
The algorithm is based on a recursive approach to build all possible full binary trees. Given an odd integer `n`, the tree will have `n` nodes. We perform a loop over all odd numbers smaller than `n`, considering each `i` as the number of nodes in the left subtree. The right subtree will have `n-i-1` nodes.

In each iteration, we recursively generate all possible full binary trees with `i` nodes for the left subtree and `n-i-1` nodes for the right subtree. We then combine all trees by pairing each left subtree with each right subtree and set the paired trees as children of a new root node `0`. The generated tree is a full binary tree with `n` nodes.

All resulting trees are appended to the result list. The recursion base case occurs when `n` is even (no possible full binary tree) or `n == 1` (the single node tree).

The time complexity of the algorithm is O(n * C(n)) when n is odd, where C(n) are the n-th catalan numbers, and O(1) when n is even. The space complexity is also O(n * C(n)) when n is odd, due to the generated trees.

## A solution in Javascript

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

function allPossibleFBT(n) {
    if (n % 2 === 0) return [];
    if (n === 1) return [new TreeNode(0)];

    let result = [];
    for (let i = 1; i < n; i += 2) {
        let left = allPossibleFBT(i);
        let right = allPossibleFBT(n - i - 1);
        for (let l of left) {
            for (let r of right) {
                let root = new TreeNode(0);
                root.left = l;
                root.right = r;
                result.push(root);
            }
        }
    }
    return result;
}
```
The algorithm is based on a recursive approach to build all possible full binary trees. Given an odd integer `n`, the tree will have `n` nodes. We perform a loop over all odd numbers smaller than `n`, considering each `i` as the number of nodes in the left subtree. The right subtree will have `n-i-1` nodes.

In each iteration, we recursively generate all possible full binary trees with `i` nodes for the left subtree and `n-i-1` nodes for the right subtree. We then combine all trees by pairing each left subtree with each right subtree and set the paired trees as children of a new root node `0`. The generated tree is a full binary tree with `n` nodes.

All resulting trees are appended to the result list. The recursion base case occurs when `n` is even (no possible full binary tree) or `n == 1` (the single node tree).

The time complexity of the algorithm is O(n * C(n)) when n is odd, where C(n) are the n-th catalan numbers, and O(1) when n is even. The space complexity is also O(n * C(n)) when n is odd, due to the generated trees.


# Minimum Falling Path Sum

- slug: minimum-falling-path-sum
- difficulty: Medium

Given an `n x n` array of integers `matrix`, return _the **minimum sum** of any **falling path** through_ `matrix`.

A **falling path** starts at any element in the first row and chooses the element in the next row that is either directly below or diagonally left/right. Specifically, the next element from position `(row, col)` will be `(row + 1, col - 1)`, `(row + 1, col)`, or `(row + 1, col + 1)`.

**Example 1:**

**Input:** matrix = \[\[2,1,3\],\[6,5,4\],\[7,8,9\]\]
**Output:** 13
**Explanation:** There are two falling paths with a minimum sum as shown.

**Example 2:**

**Input:** matrix = \[\[-19,57\],\[-40,-5\]\]
**Output:** -59
**Explanation:** The falling path with a minimum sum is shown.

**Constraints:**

*   `n == matrix.length == matrix[i].length`
*   `1 <= n <= 100`
*   `-100 <= matrix[i][j] <= 100`

## A solution in Java

```java
import java.util.*;

class FreqStack {
    private Map<Integer, Integer> freq;
    private Map<Integer, Stack<Integer>> group;

    public FreqStack() {
        freq = new HashMap<>();
        group = new TreeMap<>(Collections.reverseOrder());
    }

    public void push(int x) {
        int f = freq.getOrDefault(x, 0) + 1;
        freq.put(x, f);
        group.computeIfAbsent(f, k -> new Stack<>()).push(x);
    }

    public int pop() {
        int x = group.get(group.keySet().iterator().next()).pop();
        int f = freq.get(x) - 1;
        freq.put(x, f);

        if (group.get(f + 1).empty()) {
            group.remove(f + 1);
        }

        return x;
    }
}
```
The algorithm maintains two dictionaries (HashMap in Java, unordered_map in C++, Map in JavaScript, and defaultdict in Python): `freq` and `group`.

- `freq` maps elements to their frequencies.
- `group` maps frequencies to elements with this frequency.

When `push` is called, we increase the frequency of the element and add it to the corresponding frequency group.

When `pop` is called, we find the group with the highest frequency (using `rbegin()` in C++, `keySet().iterator().next()` in Java, `max()` in Python, and `Math.max()` in JavaScript). We remove the element from the highest frequency group and decrease the frequency in the `freq` dictionary. If the group is empty after removing the element, we delete it from the `group` dictionary.

The time complexities for both `push` and `pop` operations are O(log N) due to the use of balanced trees under the hood in TreeMap (Java), map (C++) or getting the maximum from the keys in Map (JavaScript), and defaultdict (Python).

## A solution in C++

```cpp
#include <unordered_map>
#include <map>
#include <stack>

class FreqStack {
    std::unordered_map<int, int> freq;
    std::map<int, std::stack<int>> group;

public:
    FreqStack() {}

    void push(int x) {
        int f = ++freq[x];
        group[f].push(x);
    }

    int pop() {
        auto& st = group.rbegin()->second;
        int x = st.top();
        st.pop();
        if (st.empty()) {
            group.erase(group.rbegin()->first);
        }
        --freq[x];
        return x;
    }
};
```
The algorithm maintains two dictionaries (HashMap in Java, unordered_map in C++, Map in JavaScript, and defaultdict in Python): `freq` and `group`.

- `freq` maps elements to their frequencies.
- `group` maps frequencies to elements with this frequency.

When `push` is called, we increase the frequency of the element and add it to the corresponding frequency group.

When `pop` is called, we find the group with the highest frequency (using `rbegin()` in C++, `keySet().iterator().next()` in Java, `max()` in Python, and `Math.max()` in JavaScript). We remove the element from the highest frequency group and decrease the frequency in the `freq` dictionary. If the group is empty after removing the element, we delete it from the `group` dictionary.

The time complexities for both `push` and `pop` operations are O(log N) due to the use of balanced trees under the hood in TreeMap (Java), map (C++) or getting the maximum from the keys in Map (JavaScript), and defaultdict (Python).

## A solution in Python

```python
from collections import defaultdict, deque

class FreqStack:
    def __init__(self):
        self.freq = defaultdict(int)
        self.group = defaultdict(list)

    def push(self, x: int):
        freq = self.freq[x] = self.freq[x] + 1
        self.group[freq].append(x)

    def pop(self) -> int:
        max_freq = max(self.group)
        x = self.group[max_freq].pop()
        self.freq[x] -= 1
        if not self.group[max_freq]:
            del self.group[max_freq]
        return x
```
The algorithm maintains two dictionaries (HashMap in Java, unordered_map in C++, Map in JavaScript, and defaultdict in Python): `freq` and `group`.

- `freq` maps elements to their frequencies.
- `group` maps frequencies to elements with this frequency.

When `push` is called, we increase the frequency of the element and add it to the corresponding frequency group.

When `pop` is called, we find the group with the highest frequency (using `rbegin()` in C++, `keySet().iterator().next()` in Java, `max()` in Python, and `Math.max()` in JavaScript). We remove the element from the highest frequency group and decrease the frequency in the `freq` dictionary. If the group is empty after removing the element, we delete it from the `group` dictionary.

The time complexities for both `push` and `pop` operations are O(log N) due to the use of balanced trees under the hood in TreeMap (Java), map (C++) or getting the maximum from the keys in Map (JavaScript), and defaultdict (Python).

## A solution in Javascript

```javascript
class FreqStack {
    constructor() {
        this.freq = new Map();
        this.group = new Map();
    }

    push(x) {
        let f = (this.freq.get(x) || 0) + 1;
        this.freq.set(x, f);
        let stack = this.group.get(f) || [];
        stack.push(x);
        this.group.set(f, stack);
    }

    pop() {
        let maxFreq = Math.max(...this.group.keys());
        let stack = this.group.get(maxFreq);
        let x = stack.pop();
        this.freq.set(x, this.freq.get(x) - 1);
        if (stack.length === 0) {
            this.group.delete(maxFreq);
        } else {
            this.group.set(maxFreq, stack);
        }
        return x;
    }
}
```
The algorithm maintains two dictionaries (HashMap in Java, unordered_map in C++, Map in JavaScript, and defaultdict in Python): `freq` and `group`.

- `freq` maps elements to their frequencies.
- `group` maps frequencies to elements with this frequency.

When `push` is called, we increase the frequency of the element and add it to the corresponding frequency group.

When `pop` is called, we find the group with the highest frequency (using `rbegin()` in C++, `keySet().iterator().next()` in Java, `max()` in Python, and `Math.max()` in JavaScript). We remove the element from the highest frequency group and decrease the frequency in the `freq` dictionary. If the group is empty after removing the element, we delete it from the `group` dictionary.

The time complexities for both `push` and `pop` operations are O(log N) due to the use of balanced trees under the hood in TreeMap (Java), map (C++) or getting the maximum from the keys in Map (JavaScript), and defaultdict (Python).


# Beautiful Array

- slug: beautiful-array
- difficulty: Medium

An array `nums` of length `n` is **beautiful** if:

*   `nums` is a permutation of the integers in the range `[1, n]`.
*   For every `0 <= i < j < n`, there is no index `k` with `i < k < j` where `2 * nums[k] == nums[i] + nums[j]`.

Given the integer `n`, return _any **beautiful** array_ `nums` _of length_ `n`. There will be at least one valid answer for the given `n`.

**Example 1:**

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

**Example 2:**

**Input:** n = 5
**Output:** \[3,1,2,5,4\]

**Constraints:**

*   `1 <= n <= 1000`

## A solution in Java

```java
public boolean isMonotonic(int[] nums) {
    boolean increasing = true, decreasing = true;
    for (int i = 1; i < nums.length; i++) {
        if (nums[i] > nums[i - 1]) decreasing = false;
        if (nums[i] < nums[i - 1]) increasing = false;
    }
    return increasing || decreasing;
}
```
The algorithm checks whether the given array is monotonic by iterating over the array and checking if it is monotone increasing or monotone decreasing. We use two boolean flags `increasing` and `decreasing` to track the nature of the array. While iterating through the array, if an element is greater than its predecessor, we set `decreasing` to false as it is no longer monotone decreasing. Similarly, if an element is lesser than its predecessor, we set `increasing` to false. If either of the flags remains true throughout the iteration, that means the array is monotonic, and we return true. Else, we return false.

## A solution in C++

```cpp
bool isMonotonic(vector<int>& nums) {
    bool increasing = true, decreasing = true;
    for (int i = 1; i < nums.size(); i++) {
        if (nums[i] > nums[i - 1]) decreasing = false;
        if (nums[i] < nums[i - 1]) increasing = false;
    }
    return increasing || decreasing;
}
```
The algorithm checks whether the given array is monotonic by iterating over the array and checking if it is monotone increasing or monotone decreasing. We use two boolean flags `increasing` and `decreasing` to track the nature of the array. While iterating through the array, if an element is greater than its predecessor, we set `decreasing` to false as it is no longer monotone decreasing. Similarly, if an element is lesser than its predecessor, we set `increasing` to false. If either of the flags remains true throughout the iteration, that means the array is monotonic, and we return true. Else, we return false.

## A solution in Python

```python
def isMonotonic(nums):
    increasing = decreasing = True
    for i in range(1, len(nums)):
        if nums[i] > nums[i - 1]: decreasing = False
        if nums[i] < nums[i - 1]: increasing = False
    return increasing or decreasing
```
The algorithm checks whether the given array is monotonic by iterating over the array and checking if it is monotone increasing or monotone decreasing. We use two boolean flags `increasing` and `decreasing` to track the nature of the array. While iterating through the array, if an element is greater than its predecessor, we set `decreasing` to false as it is no longer monotone decreasing. Similarly, if an element is lesser than its predecessor, we set `increasing` to false. If either of the flags remains true throughout the iteration, that means the array is monotonic, and we return true. Else, we return false.

## A solution in Javascript

```javascript
function isMonotonic(nums) {
    let increasing = true, decreasing = true;
    for (let i = 1; i < nums.length; i++) {
        if (nums[i] > nums[i - 1]) decreasing = false;
        if (nums[i] < nums[i - 1]) increasing = false;
    }
    return increasing || decreasing;
}
```
The algorithm checks whether the given array is monotonic by iterating over the array and checking if it is monotone increasing or monotone decreasing. We use two boolean flags `increasing` and `decreasing` to track the nature of the array. While iterating through the array, if an element is greater than its predecessor, we set `decreasing` to false as it is no longer monotone decreasing. Similarly, if an element is lesser than its predecessor, we set `increasing` to false. If either of the flags remains true throughout the iteration, that means the array is monotonic, and we return true. Else, we return false.


# Number of Recent Calls

- slug: number-of-recent-calls
- difficulty: Easy

You have a `RecentCounter` class which counts the number of recent requests within a certain time frame.

Implement the `RecentCounter` class:

*   `RecentCounter()` Initializes the counter with zero recent requests.
*   `int ping(int t)` Adds a new request at time `t`, where `t` represents some time in milliseconds, and returns the number of requests that has happened in the past `3000` milliseconds (including the new request). Specifically, return the number of requests that have happened in the inclusive range `[t - 3000, t]`.

It is **guaranteed** that every call to `ping` uses a strictly larger value of `t` than the previous call.

**Example 1:**

**Input**
\[ "RecentCounter ",  "ping ",  "ping ",  "ping ",  "ping "\]
\[\[\], \[1\], \[100\], \[3001\], \[3002\]\]
**Output**
\[null, 1, 2, 3, 3\]

**Explanation**
RecentCounter recentCounter = new RecentCounter();
recentCounter.ping(1);     // requests = \[1\], range is \[-2999,1\], return 1
recentCounter.ping(100);   // requests = \[1, 100\], range is \[-2900,100\], return 2
recentCounter.ping(3001);  // requests = \[1, 100, 3001\], range is \[1,3001\], return 3
recentCounter.ping(3002);  // requests = \[1, 100, 3001, 3002\], range is \[2,3002\], return 3

**Constraints:**

*   `1 <= t <= 109`
*   Each test case will call `ping` with **strictly increasing** values of `t`.
*   At most `104` calls will be made to `ping`.

## A solution in Java

```java
public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
}

public TreeNode increasingBST(TreeNode root) {
    TreeNode dummy = new TreeNode(0);
    TreeNode prev = dummy;
    inorder(root, prev);
    return dummy.right;
}

public void inorder(TreeNode node, TreeNode prev) {
    if (node == null) return;

    inorder(node.left, prev);
    prev.right = node;
    prev = node;
    node.left = null;
    inorder(node.right, prev);
}
```
The algorithm uses a recursive inorder traversal of the given binary search tree. It starts by visiting the left child, if any, and then processes the root node, and finally the right child. The important part of this traversal is the processing of each node. When a node is encountered, its left pointer is set to null and its right pointer is set to the current node being processed.

The algorithm maintains a `prev` variable to keep the previous node encountered during the inorder traversal. Initially, we have a dummy node, and during the traversal, we set the right pointer of the `prev` node to the current node and update the `prev` node to the current node.

Finally, after the traversal, the right child of the dummy node points to the root of the modified tree.

## A solution in C++

```cpp
class TreeNode {
public:
    int val;
    TreeNode* left;
    TreeNode* right;
};

void inorder(TreeNode* node, TreeNode*& prev) {
    if (node == nullptr) return;

    inorder(node->left, prev);
    prev->right = node;
    prev = node;
    node->left = nullptr;
    inorder(node->right, prev);
}

TreeNode* increasingBST(TreeNode* root) {
    TreeNode dummy(0);
    TreeNode* prev = &dummy;
    inorder(root, prev);
    return dummy.right;
}
```
The algorithm uses a recursive inorder traversal of the given binary search tree. It starts by visiting the left child, if any, and then processes the root node, and finally the right child. The important part of this traversal is the processing of each node. When a node is encountered, its left pointer is set to null and its right pointer is set to the current node being processed.

The algorithm maintains a `prev` variable to keep the previous node encountered during the inorder traversal. Initially, we have a dummy node, and during the traversal, we set the right pointer of the `prev` node to the current node and update the `prev` node to the current node.

Finally, after the traversal, the right child of the dummy node points to the root of the modified tree.

## A solution in Python

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

def increasingBST(root):
    def inorder(node):
        nonlocal prev
        if not node: return

        inorder(node.left)
        prev.right = node
        prev = node
        node.left = None
        inorder(node.right)

    dummy = TreeNode(0)
    prev = dummy
    inorder(root)
    return dummy.right
```
The algorithm uses a recursive inorder traversal of the given binary search tree. It starts by visiting the left child, if any, and then processes the root node, and finally the right child. The important part of this traversal is the processing of each node. When a node is encountered, its left pointer is set to null and its right pointer is set to the current node being processed.

The algorithm maintains a `prev` variable to keep the previous node encountered during the inorder traversal. Initially, we have a dummy node, and during the traversal, we set the right pointer of the `prev` node to the current node and update the `prev` node to the current node.

Finally, after the traversal, the right child of the dummy node points to the root of the modified tree.

## A solution in Javascript

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

function increasingBST(root) {
    function inorder(node) {
        if (!node) return;

        inorder(node.left);
        prev.right = node;
        prev = node;
        node.left = null;
        inorder(node.right);
    }

    const dummy = new TreeNode(0);
    let prev = dummy;
    inorder(root);
    return dummy.right;
}
```
The algorithm uses a recursive inorder traversal of the given binary search tree. It starts by visiting the left child, if any, and then processes the root node, and finally the right child. The important part of this traversal is the processing of each node. When a node is encountered, its left pointer is set to null and its right pointer is set to the current node being processed.

The algorithm maintains a `prev` variable to keep the previous node encountered during the inorder traversal. Initially, we have a dummy node, and during the traversal, we set the right pointer of the `prev` node to the current node and update the `prev` node to the current node.

Finally, after the traversal, the right child of the dummy node points to the root of the modified tree.


# Shortest Bridge

- slug: shortest-bridge
- difficulty: Medium

You are given an `n x n` binary matrix `grid` where `1` represents land and `0` represents water.

An **island** is a 4-directionally connected group of `1`'s not connected to any other `1`'s. There are **exactly two islands** in `grid`.

You may change `0`'s to `1`'s to connect the two islands to form **one island**.

Return _the smallest number of_ `0`_'s you must flip to connect the two islands_.

**Example 1:**

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

**Example 2:**

**Input:** grid = \[\[0,1,0\],\[0,0,0\],\[0,0,1\]\]
**Output:** 2

**Example 3:**

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

**Constraints:**

*   `n == grid.length == grid[i].length`
*   `2 <= n <= 100`
*   `grid[i][j]` is either `0` or `1`.
*   There are exactly two islands in `grid`.

## A solution in Java

```java
import java.util.HashSet;
import java.util.Set;

public int subarrayBitwiseORs(int[] arr) {
    Set<Integer> result = new HashSet<>(), current, temp;
    for (int num : arr) {
        temp = new HashSet<>();
        temp.add(num);
        for (int c : current) {
            temp.add(num | c);
        }
        current = temp;
        result.addAll(current);
    }
    return result.size();
}
```
The algorithm follows these steps:
1. We initialize the sets `result`, `current`, and `temp` to empty sets. `result` will store all unique bitwise OR results, `current` will store the bitwise OR results of the previous subarray, and `temp` will store the bitwise OR results of the current subarray.
2. We iterate over each element in the array.
3. For each element, create a new `temp` containing the current element; then for each previous result in the `current`, insert the bitwise OR of the current element and the previous result into `temp`. Update `current` to be the new `temp`.
4. Add all elements from `current` into `result`.
5. Return the size of the unique `result` set.

## A solution in C++

```cpp
#include <set>
#include <vector>

int subarrayBitwiseORs(std::vector<int>& arr) {
    std::set<int> result, current, temp;
    for (int num : arr) {
        temp = {num};
        for (int c : current) {
            temp.insert(num | c);
        }
        current = std::move(temp);
        result.insert(current.begin(), current.end());
    }
    return result.size();
}
```
The algorithm follows these steps:
1. We initialize the sets `result`, `current`, and `temp` to empty sets. `result` will store all unique bitwise OR results, `current` will store the bitwise OR results of the previous subarray, and `temp` will store the bitwise OR results of the current subarray.
2. We iterate over each element in the array.
3. For each element, create a new `temp` containing the current element; then for each previous result in the `current`, insert the bitwise OR of the current element and the previous result into `temp`. Update `current` to be the new `temp`.
4. Add all elements from `current` into `result`.
5. Return the size of the unique `result` set.

## A solution in Python

```python
def subarrayBitwiseORs(arr: List[int]) -> int:
    result, current, temp = set(), set(), set()
    for num in arr:
        temp = {num}
        for c in current:
            temp.add(num | c)
        current = temp
        result |= current
    return len(result)
```
The algorithm follows these steps:
1. We initialize the sets `result`, `current`, and `temp` to empty sets. `result` will store all unique bitwise OR results, `current` will store the bitwise OR results of the previous subarray, and `temp` will store the bitwise OR results of the current subarray.
2. We iterate over each element in the array.
3. For each element, create a new `temp` containing the current element; then for each previous result in the `current`, insert the bitwise OR of the current element and the previous result into `temp`. Update `current` to be the new `temp`.
4. Add all elements from `current` into `result`.
5. Return the size of the unique `result` set.

## A solution in Javascript

```javascript
function subarrayBitwiseORs(arr) {
    let result = new Set(), current = new Set(), temp;
    for (const num of arr) {
        temp = new Set([num]);
        for (const c of current) {
            temp.add(num | c);
        }
        current = temp;
        for (const c of current) {
            result.add(c);
        }
    }
    return result.size;
}
```
The algorithm follows these steps:
1. We initialize the sets `result`, `current`, and `temp` to empty sets. `result` will store all unique bitwise OR results, `current` will store the bitwise OR results of the previous subarray, and `temp` will store the bitwise OR results of the current subarray.
2. We iterate over each element in the array.
3. For each element, create a new `temp` containing the current element; then for each previous result in the `current`, insert the bitwise OR of the current element and the previous result into `temp`. Update `current` to be the new `temp`.
4. Add all elements from `current` into `result`.
5. Return the size of the unique `result` set.


# Knight Dialer

- slug: knight-dialer
- difficulty: Medium

The chess knight has a **unique movement**, it may move two squares vertically and one square horizontally, or two squares horizontally and one square vertically (with both forming the shape of an **L**). The possible movements of chess knight are shown in this diagaram:

A chess knight can move as indicated in the chess diagram below:

We have a chess knight and a phone pad as shown below, the knight **can only stand on a numeric cell** (i.e. blue cell).

Given an integer `n`, return how many distinct phone numbers of length `n` we can dial.

You are allowed to place the knight **on any numeric cell** initially and then you should perform `n - 1` jumps to dial a number of length `n`. All jumps should be **valid** knight jumps.

As the answer may be very large, **return the answer modulo** `109 + 7`.

**Example 1:**

**Input:** n = 1
**Output:** 10
**Explanation:** We need to dial a number of length 1, so placing the knight over any numeric cell of the 10 cells is sufficient.

**Example 2:**

**Input:** n = 2
**Output:** 20
**Explanation:** All the valid number we can dial are \[04, 06, 16, 18, 27, 29, 34, 38, 40, 43, 49, 60, 61, 67, 72, 76, 81, 83, 92, 94\]

**Example 3:**

**Input:** n = 3131
**Output:** 136006598
**Explanation:** Please take care of the mod.

**Constraints:**

*   `1 <= n <= 5000`

## A solution in Java

```java
public String lexSmallestString(String s, int k) {
    String res = s;
    for (int i = 0; i < k; i++) {
        String tmp = s.substring(i) + s.substring(0, i);
        if (tmp.compareTo(res) < 0) {
            res = tmp;
        }
    }
    return res;
}
```
The algorithm for this problem is quite simple. We can iterate through the first `k` characters of the input string `s`. In each iteration, we generate a new string by moving the substring consisting of the first `i` characters to the end of the string. Then, we compare the new string with the current result. If the new string is lexicographically smaller, we update the result. After iterating through all `k` possibilities, we return the lexicographically smallest string we've found.

## A solution in C++

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

string lex_smallest_string(string s, int k) {
    string res = s;
    for (int i = 0; i < k; ++i) {
        string tmp = s.substr(i) + s.substr(0, i);
        if (tmp < res) res = tmp;
    }
    return res;
}
```
The algorithm for this problem is quite simple. We can iterate through the first `k` characters of the input string `s`. In each iteration, we generate a new string by moving the substring consisting of the first `i` characters to the end of the string. Then, we compare the new string with the current result. If the new string is lexicographically smaller, we update the result. After iterating through all `k` possibilities, we return the lexicographically smallest string we've found.

## A solution in Python

```python
def lex_smallest_string(s, k):
    res = s
    for i in range(k):
        tmp = s[i:] + s[:i]
        if tmp < res:
            res = tmp
    return res
```
The algorithm for this problem is quite simple. We can iterate through the first `k` characters of the input string `s`. In each iteration, we generate a new string by moving the substring consisting of the first `i` characters to the end of the string. Then, we compare the new string with the current result. If the new string is lexicographically smaller, we update the result. After iterating through all `k` possibilities, we return the lexicographically smallest string we've found.

## A solution in Javascript

```javascript
function lexSmallestString(s, k) {
    let res = s;
    for (let i = 0; i < k; i++) {
        let tmp = s.slice(i) + s.slice(0, i);
        if (tmp < res) {
            res = tmp;
        }
    }
    return res;
}
```
The algorithm for this problem is quite simple. We can iterate through the first `k` characters of the input string `s`. In each iteration, we generate a new string by moving the substring consisting of the first `i` characters to the end of the string. Then, we compare the new string with the current result. If the new string is lexicographically smaller, we update the result. After iterating through all `k` possibilities, we return the lexicographically smallest string we've found.


# Stamping The Sequence

- slug: stamping-the-sequence
- difficulty: Hard

You are given two strings `stamp` and `target`. Initially, there is a string `s` of length `target.length` with all `s[i] == '?'`.

In one turn, you can place `stamp` over `s` and replace every letter in the `s` with the corresponding letter from `stamp`.

*   For example, if `stamp = "abc "` and `target = "abcba "`, then `s` is `"????? "` initially. In one turn you can:

    *   place `stamp` at index `0` of `s` to obtain `"abc?? "`,
    *   place `stamp` at index `1` of `s` to obtain `"?abc? "`, or
    *   place `stamp` at index `2` of `s` to obtain `"??abc "`.

    Note that `stamp` must be fully contained in the boundaries of `s` in order to stamp (i.e., you cannot place `stamp` at index `3` of `s`).

We want to convert `s` to `target` using **at most** `10 * target.length` turns.

Return _an array of the index of the left-most letter being stamped at each turn_. If we cannot obtain `target` from `s` within `10 * target.length` turns, return an empty array.

**Example 1:**

**Input:** stamp =  "abc ", target =  "ababc "
**Output:** \[0,2\]
**Explanation:** Initially s =  "????? ".
- Place stamp at index 0 to get  "abc?? ".
- Place stamp at index 2 to get  "ababc ".
\[1,0,2\] would also be accepted as an answer, as well as some other answers.

**Example 2:**

**Input:** stamp =  "abca ", target =  "aabcaca "
**Output:** \[3,0,1\]
**Explanation:** Initially s =  "??????? ".
- Place stamp at index 3 to get  "???abca ".
- Place stamp at index 0 to get  "abcabca ".
- Place stamp at index 1 to get  "aabcaca ".

**Constraints:**

*   `1 <= stamp.length <= target.length <= 1000`
*   `stamp` and `target` consist of lowercase English letters.

## A solution in Java

```java
class RLEIterator {
    private int[] encoding;
    private int index;

    public RLEIterator(int[] encoding) {
        this.encoding = encoding;
        this.index = 0;
    }

    public int next(int n) {
        while (index < encoding.length) {
            if (n <= encoding[index]) {
                encoding[index] -= n;
                return encoding[index + 1];
            }
            n -= encoding[index];
            index += 2;
        }
        return -1;
    }
}
```
The RLEIterator class creates an iterator for a given run-length encoded array. In the constructor, it initializes the class with the `encoding` array and initializes the `index` variable to 0.

The `next` function takes an integer `n` and iterates through the run-length encoded array to find the value at the given position. If `n` is less than or equal to the current run's count (`encoding[index]), we update the run count by subtracting n and return the corresponding value. If `n` is greater than the run's count, we subtract the run count from `n` and move to the next run by incrementing the index by 2. If the iterator reaches the end of the encoding array, it returns -1.

## A solution in C++

```cpp
class RLEIterator {
public:
    RLEIterator(vector<int>& encoding) {
        data = encoding;
        index = 0;
    }

    int next(int n) {
        while (index < data.size()) {
            if (n <= data[index]) {
                data[index] -= n;
                return data[index + 1];
            }
            n -= data[index];
            index += 2;
        }
        return -1;
    }

private:
    vector<int> data;
    int index;
};
```
The RLEIterator class creates an iterator for a given run-length encoded array. In the constructor, it initializes the class with the `encoding` array and initializes the `index` variable to 0.

The `next` function takes an integer `n` and iterates through the run-length encoded array to find the value at the given position. If `n` is less than or equal to the current run's count (`encoding[index]), we update the run count by subtracting n and return the corresponding value. If `n` is greater than the run's count, we subtract the run count from `n` and move to the next run by incrementing the index by 2. If the iterator reaches the end of the encoding array, it returns -1.

## A solution in Python

```python
class RLEIterator:
    def __init__(self, encoding):
        self.encoding = encoding
        self.index = 0

    def next(self, n):
        while self.index < len(self.encoding):
            if n <= self.encoding[self.index]:
                self.encoding[self.index] -= n
                return self.encoding[self.index + 1]
            n -= self.encoding[self.index]
            self.index += 2
        return -1
```
The RLEIterator class creates an iterator for a given run-length encoded array. In the constructor, it initializes the class with the `encoding` array and initializes the `index` variable to 0.

The `next` function takes an integer `n` and iterates through the run-length encoded array to find the value at the given position. If `n` is less than or equal to the current run's count (`encoding[index]), we update the run count by subtracting n and return the corresponding value. If `n` is greater than the run's count, we subtract the run count from `n` and move to the next run by incrementing the index by 2. If the iterator reaches the end of the encoding array, it returns -1.

## A solution in Javascript

```javascript
class RLEIterator {
    constructor(encoding) {
        this.encoding = encoding;
        this.index = 0;
    }

    next(n) {
        while (this.index < this.encoding.length) {
            if (n <= this.encoding[this.index]) {
                this.encoding[this.index] -= n;
                return this.encoding[this.index + 1];
            }
            n -= this.encoding[this.index];
            this.index += 2;
        }
        return -1;
    }
}
```
The RLEIterator class creates an iterator for a given run-length encoded array. In the constructor, it initializes the class with the `encoding` array and initializes the `index` variable to 0.

The `next` function takes an integer `n` and iterates through the run-length encoded array to find the value at the given position. If `n` is less than or equal to the current run's count (`encoding[index]), we update the run count by subtracting n and return the corresponding value. If `n` is greater than the run's count, we subtract the run count from `n` and move to the next run by incrementing the index by 2. If the iterator reaches the end of the encoding array, it returns -1.


# Reorder Data in Log Files

- slug: reorder-data-in-log-files
- difficulty: Medium

You are given an array of `logs`. Each log is a space-delimited string of words, where the first word is the **identifier**.

There are two types of logs:

*   **Letter-logs**: All words (except the identifier) consist of lowercase English letters.
*   **Digit-logs**: All words (except the identifier) consist of digits.

Reorder these logs so that:

1.  The **letter-logs** come before all **digit-logs**.
2.  The **letter-logs** are sorted lexicographically by their contents. If their contents are the same, then sort them lexicographically by their identifiers.
3.  The **digit-logs** maintain their relative ordering.

Return _the final order of the logs_.

**Example 1:**

**Input:** logs = \[ "dig1 8 1 5 1 ", "let1 art can ", "dig2 3 6 ", "let2 own kit dig ", "let3 art zero "\]
**Output:** \[ "let1 art can ", "let3 art zero ", "let2 own kit dig ", "dig1 8 1 5 1 ", "dig2 3 6 "\]
**Explanation:**
The letter-log contents are all different, so their ordering is  "art can ",  "art zero ",  "own kit dig ".
The digit-logs have a relative order of  "dig1 8 1 5 1 ",  "dig2 3 6 ".

**Example 2:**

**Input:** logs = \[ "a1 9 2 3 1 ", "g1 act car ", "zo4 4 7 ", "ab1 off key dog ", "a8 act zoo "\]
**Output:** \[ "g1 act car ", "a8 act zoo ", "ab1 off key dog ", "a1 9 2 3 1 ", "zo4 4 7 "\]

**Constraints:**

*   `1 <= logs.length <= 100`
*   `3 <= logs[i].length <= 100`
*   All the tokens of `logs[i]` are separated by a **single** space.
*   `logs[i]` is guaranteed to have an identifier and at least one word after the identifier.

## A solution in Java

```java
import java.util.Stack;

class StockSpanner {
    private final Stack<Integer> indexStack;
    private final List<Integer> prices;

    public StockSpanner() {
        indexStack = new Stack<>();
        prices = new ArrayList<>();
    }

    public int next(int price) {
        while (!indexStack.isEmpty() && prices.get(indexStack.peek()) <= price) {
            indexStack.pop();
        }
        int span = indexStack.isEmpty() ? prices.size() + 1 : prices.size() - indexStack.peek();
        indexStack.push(prices.size());
        prices.add(price);
        return span;
    }
}
```
The algorithm uses a stack to keep track of indices of the prices. Each time the `next` function runs, we compare the current day's price with the top element of the stack (i.e, the previous maximum price or largest contiguous price index).

If the new price is greater than the top element, we pop it from the stack and continually do so until we reach an empty stack, or we find a price greater than the new price.

Then, we calculate the span by checking if the stack is empty. If it is, we add the length of the prices array and 1. If it's not empty, we subtract the top index from the length of the prices array.

Next, we push the current index to the stack and append the current day's price to the prices list/array.

This algorithm efficiently calculates the stock span for the current day by efficiently utilizing the stack and iterating only when necessary.

## A solution in C++

```cpp
#include <vector>
#include <stack>

class StockSpanner {
public:
    std::vector<int> prices;
    std::stack<int> index_stack;

    StockSpanner() {}

    int next(int price) {
        while (!index_stack.empty() && prices[index_stack.top()] <= price) {
            index_stack.pop();
        }
        int span = index_stack.empty() ? prices.size() + 1 : prices.size() - index_stack.top();
        index_stack.push(prices.size());
        prices.push_back(price);
        return span;
    }
};
```
The algorithm uses a stack to keep track of indices of the prices. Each time the `next` function runs, we compare the current day's price with the top element of the stack (i.e, the previous maximum price or largest contiguous price index).

If the new price is greater than the top element, we pop it from the stack and continually do so until we reach an empty stack, or we find a price greater than the new price.

Then, we calculate the span by checking if the stack is empty. If it is, we add the length of the prices array and 1. If it's not empty, we subtract the top index from the length of the prices array.

Next, we push the current index to the stack and append the current day's price to the prices list/array.

This algorithm efficiently calculates the stock span for the current day by efficiently utilizing the stack and iterating only when necessary.

## A solution in Python

```python
class StockSpanner:

    def __init__(self):
        self.prices = []
        self.index_stack = []

    def next(self, price: int) -> int:
        while self.index_stack and self.prices[self.index_stack[-1]] <= price:
            self.index_stack.pop()
        span = len(self.prices) + 1 if not self.index_stack else len(self.prices) - self.index_stack[-1]
        self.index_stack.append(len(self.prices))
        self.prices.append(price)
        return span
```
The algorithm uses a stack to keep track of indices of the prices. Each time the `next` function runs, we compare the current day's price with the top element of the stack (i.e, the previous maximum price or largest contiguous price index).

If the new price is greater than the top element, we pop it from the stack and continually do so until we reach an empty stack, or we find a price greater than the new price.

Then, we calculate the span by checking if the stack is empty. If it is, we add the length of the prices array and 1. If it's not empty, we subtract the top index from the length of the prices array.

Next, we push the current index to the stack and append the current day's price to the prices list/array.

This algorithm efficiently calculates the stock span for the current day by efficiently utilizing the stack and iterating only when necessary.

## A solution in Javascript

```javascript
class StockSpanner {
    constructor() {
        this.prices = [];
        this.indexStack = [];
    }

    next(price) {
        while (this.indexStack.length > 0 && this.prices[this.indexStack[this.indexStack.length - 1]] <= price) {
            this.indexStack.pop();
        }
        const span = this.indexStack.length === 0 ? this.prices.length + 1 : this.prices.length - this.indexStack[this.indexStack.length - 1];
        this.indexStack.push(this.prices.length);
        this.prices.push(price);
        return span;
    }
}
```
The algorithm uses a stack to keep track of indices of the prices. Each time the `next` function runs, we compare the current day's price with the top element of the stack (i.e, the previous maximum price or largest contiguous price index).

If the new price is greater than the top element, we pop it from the stack and continually do so until we reach an empty stack, or we find a price greater than the new price.

Then, we calculate the span by checking if the stack is empty. If it is, we add the length of the prices array and 1. If it's not empty, we subtract the top index from the length of the prices array.

Next, we push the current index to the stack and append the current day's price to the prices list/array.

This algorithm efficiently calculates the stock span for the current day by efficiently utilizing the stack and iterating only when necessary.


# Range Sum of BST

- slug: range-sum-of-bst
- difficulty: Easy

Given the `root` node of a binary search tree and two integers `low` and `high`, return _the sum of values of all nodes with a value in the **inclusive** range_ `[low, high]`.

**Example 1:**

**Input:** root = \[10,5,15,3,7,null,18\], low = 7, high = 15
**Output:** 32
**Explanation:** Nodes 7, 10, and 15 are in the range \[7, 15\]. 7 + 10 + 15 = 32.

**Example 2:**

**Input:** root = \[10,5,15,3,7,13,18,1,null,6\], low = 6, high = 10
**Output:** 23
**Explanation:** Nodes 6, 7, and 10 are in the range \[6, 10\]. 6 + 7 + 10 = 23.

**Constraints:**

*   The number of nodes in the tree is in the range `[1, 2 * 104]`.
*   `1 <= Node.val <= 105`
*   `1 <= low <= high <= 105`
*   All `Node.val` are **unique**.

## A solution in Java

```java
import java.util.Arrays;

public int numDigitsLessThanN(int[] digits, int n) {
    int ans = 0, factor = 1;
    String nStr = Integer.toString(n);
    for (int i = nStr.length() - 1; i >= 0; --i) {
        ans += (Arrays.binarySearch(digits, nStr.charAt(i) - '0') + 1) * factor;
        factor *= digits.length;
    }
    return ans;
}
```
1. Initialize the answer as 0 and a factor as 1.
2. Convert n into a string so that we can traverse each digit easily.
3. Iterate over the digits of n from right to left.
4. For each digit, find the number of digits less than or equal to the current digit of n using binary search, and add this number multiplied by the current factor to the answer.
5. Multiply the factor by the number of given digits for every iteration to account for the combinations of smaller digits.
6. Return the answer after all iterations.

## A solution in C++

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

int num_digits_less_than_n(vector<int>& digits, int n) {
    int ans = 0, factor = 1;
    string n_str = to_string(n);
    for (int i = n_str.size() - 1; i >= 0; --i) {
        ans += (upper_bound(digits.begin(), digits.end(), n_str[i] - '0') - digits.begin()) * factor;
        factor *= digits.size();
    }
    return ans;
}
```
1. Initialize the answer as 0 and a factor as 1.
2. Convert n into a string so that we can traverse each digit easily.
3. Iterate over the digits of n from right to left.
4. For each digit, find the number of digits less than or equal to the current digit of n using binary search, and add this number multiplied by the current factor to the answer.
5. Multiply the factor by the number of given digits for every iteration to account for the combinations of smaller digits.
6. Return the answer after all iterations.

## A solution in Python

```python
from bisect import bisect_right

def num_digits_less_than_n(digits: List[int], n: int) -> int:
    ans = 0
    factor = 1
    n_str = str(n)
    for i in range(len(n_str) - 1, -1, -1):
        ans += bisect_right(digits, int(n_str[i])) * factor
        factor *= len(digits)
    return ans
```
1. Initialize the answer as 0 and a factor as 1.
2. Convert n into a string so that we can traverse each digit easily.
3. Iterate over the digits of n from right to left.
4. For each digit, find the number of digits less than or equal to the current digit of n using binary search, and add this number multiplied by the current factor to the answer.
5. Multiply the factor by the number of given digits for every iteration to account for the combinations of smaller digits.
6. Return the answer after all iterations.

## A solution in Javascript

```javascript
function numDigitsLessThanN(digits, n) {
    let ans = 0, factor = 1;
    let nStr = String(n);
    for (let i = nStr.length - 1; i >= 0; --i) {
        ans += (upperBound(digits, nStr.charCodeAt(i) - 48)) * factor;
        factor *= digits.length;
    }
    return ans;
}

function upperBound(arr, target) {
    let low = 0, high = arr.length;
    while (low < high) {
        let mid = Math.floor((low + high) / 2);
        if (arr[mid] > target) high = mid;
        else low = mid + 1;
    }
    return low;
}
```
1. Initialize the answer as 0 and a factor as 1.
2. Convert n into a string so that we can traverse each digit easily.
3. Iterate over the digits of n from right to left.
4. For each digit, find the number of digits less than or equal to the current digit of n using binary search, and add this number multiplied by the current factor to the answer.
5. Multiply the factor by the number of given digits for every iteration to account for the combinations of smaller digits.
6. Return the answer after all iterations.