# Delete Columns to Make Sorted II

- slug: delete-columns-to-make-sorted-ii
- difficulty: Medium

You are given an array of `n` strings `strs`, all of the same length.

We may choose any deletion indices, and we delete all the characters in those indices for each string.

For example, if we have `strs = [ "abcdef ", "uvwxyz "]` and deletion indices `{0, 2, 3}`, then the final array after deletions is `[ "bef ", "vyz "]`.

Suppose we chose a set of deletion indices `answer` such that after deletions, the final array has its elements in **lexicographic** order (i.e., `strs[0] <= strs[1] <= strs[2] <= ... <= strs[n - 1]`). Return _the minimum possible value of_ `answer.length`.

**Example 1:**

**Input:** strs = \[ "ca ", "bb ", "ac "\]
**Output:** 1
**Explanation:**
After deleting the first column, strs = \[ "a ",  "b ",  "c "\].
Now strs is in lexicographic order (ie. strs\[0\] <= strs\[1\] <= strs\[2\]).
We require at least 1 deletion since initially strs was not in lexicographic order, so the answer is 1.

**Example 2:**

**Input:** strs = \[ "xc ", "yb ", "za "\]
**Output:** 0
**Explanation:**
strs is already in lexicographic order, so we do not need to delete anything.
Note that the rows of strs are not necessarily in lexicographic order:
i.e., it is NOT necessarily true that (strs\[0\]\[0\] <= strs\[0\]\[1\] <= ...)

**Example 3:**

**Input:** strs = \[ "zyx ", "wvu ", "tsr "\]
**Output:** 3
**Explanation:** We have to delete every column.

**Constraints:**

*   `n == strs.length`
*   `1 <= n <= 100`
*   `1 <= strs[i].length <= 100`
*   `strs[i]` consists of lowercase English letters.

## A solution in Java

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

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

class CBTInserter {
    TreeNode root;
    Queue<TreeNode> q;

    public CBTInserter(TreeNode root) {
        this.root = root;
        q = new LinkedList<>();
        q.add(root);
        while (true) {
            TreeNode node = q.peek();
            if (node.left == null || node.right == null) break;
            q.add(node.left);
            q.add(node.right);
            q.poll();
        }
    }

    public int insert(int v) {
        TreeNode newNode = new TreeNode(v);
        TreeNode parentNode = q.peek();
        if (parentNode.left == null) {
            parentNode.left = newNode;
        } else {
            parentNode.right = newNode;
            q.add(parentNode.left);
            q.add(parentNode.right);
            q.poll();
        }
        return parentNode.val;
    }

    public TreeNode get_root() {
        return root;
    }
}
```
The algorithm starts by initializing a queue with the given root node. At each step, it checks if the front node from the queue has an empty left or right child. If so, the algorithm breaks from the loop as it found the first node with an empty child.

To insert a new node, it creates a new node with the provided value and checks if the left child of the front node from the queue is empty. If so, it assigns the new node as the left child. Otherwise, it assigns the new node as the right child, push both left and right children of the front node to the queue, and removes the front node from the queue. It returns the value of the parent node.

The get_root method returns the root of the tree.

## A solution in C++

```cpp
#include <queue>

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

class CBTInserter {
public:
    TreeNode* root;
    std::queue<TreeNode*> q;

    CBTInserter(TreeNode* root) {
        this->root = root;
        q.push(root);
        while (!q.empty()) {
            TreeNode* node = q.front();
            if (!node->left || !node->right) break;
            q.push(node->left);
            q.push(node->right);
            q.pop();
        }
    }

    int insert(int v) {
        TreeNode* newNode = new TreeNode(v);
        TreeNode* parentNode = q.front();
        if (!parentNode->left) {
            parentNode->left = newNode;
        } else {
            parentNode->right = newNode;
            q.push(parentNode->left);
            q.push(parentNode->right);
            q.pop();
        }
        return parentNode->val;
    }

    TreeNode* get_root() {
        return root;
    }
};
```
The algorithm starts by initializing a queue with the given root node. At each step, it checks if the front node from the queue has an empty left or right child. If so, the algorithm breaks from the loop as it found the first node with an empty child.

To insert a new node, it creates a new node with the provided value and checks if the left child of the front node from the queue is empty. If so, it assigns the new node as the left child. Otherwise, it assigns the new node as the right child, push both left and right children of the front node to the queue, and removes the front node from the queue. It returns the value of the parent node.

The get_root method returns the root of the tree.

## A solution in Python

```python
from collections import deque

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

class CBTInserter:
    def __init__(self, root: TreeNode):
        self.root = root
        self.q = deque([root])
        while True:
            node = self.q[0]
            if not node.left or not node.right:
                break
            self.q.append(node.left)
            self.q.append(node.right)
            self.q.popleft()

    def insert(self, v: int) -> int:
        newNode = TreeNode(v)
        parentNode = self.q[0]
        if not parentNode.left:
            parentNode.left = newNode
        else:
            parentNode.right = newNode
            self.q.append(parentNode.left)
            self.q.append(parentNode.right)
            self.q.popleft()
        return parentNode.val

    def get_root(self) -> TreeNode:
        return self.root
```
The algorithm starts by initializing a queue with the given root node. At each step, it checks if the front node from the queue has an empty left or right child. If so, the algorithm breaks from the loop as it found the first node with an empty child.

To insert a new node, it creates a new node with the provided value and checks if the left child of the front node from the queue is empty. If so, it assigns the new node as the left child. Otherwise, it assigns the new node as the right child, push both left and right children of the front node to the queue, and removes the front node from the queue. It returns the value of the parent node.

The get_root method returns the root of the tree.

## A solution in Javascript

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

class CBTInserter {
    constructor(root) {
        this.root = root;
        this.q = [root];
        while (true) {
            let node = this.q[0];
            if (!node.left || !node.right) break;
            this.q.push(node.left);
            this.q.push(node.right);
            this.q.shift();
        }
    }

    insert(v) {
        const newNode = new TreeNode(v);
        const parentNode = this.q[0];
        if (!parentNode.left) {
            parentNode.left = newNode;
        } else {
            parentNode.right = newNode;
            this.q.push(parentNode.left);
            this.q.push(parentNode.right);
            this.q.shift();
        }
        return parentNode.val;
    }

    get_root() {
        return this.root;
    }
}
```
The algorithm starts by initializing a queue with the given root node. At each step, it checks if the front node from the queue has an empty left or right child. If so, the algorithm breaks from the loop as it found the first node with an empty child.

To insert a new node, it creates a new node with the provided value and checks if the left child of the front node from the queue is empty. If so, it assigns the new node as the left child. Otherwise, it assigns the new node as the right child, push both left and right children of the front node to the queue, and removes the front node from the queue. It returns the value of the parent node.

The get_root method returns the root of the tree.


# Tallest Billboard

- slug: tallest-billboard
- difficulty: Hard

You are installing a billboard and want it to have the largest height. The billboard will have two steel supports, one on each side. Each steel support must be an equal height.

You are given a collection of `rods` that can be welded together. For example, if you have rods of lengths `1`, `2`, and `3`, you can weld them together to make a support of length `6`.

Return _the largest possible height of your billboard installation_. If you cannot support the billboard, return `0`.

**Example 1:**

**Input:** rods = \[1,2,3,6\]
**Output:** 6
**Explanation:** We have two disjoint subsets {1,2,3} and {6}, which have the same sum = 6.

**Example 2:**

**Input:** rods = \[1,2,3,4,5,6\]
**Output:** 10
**Explanation:** We have two disjoint subsets {2,3,5} and {4,6}, which have the same sum = 10.

**Example 3:**

**Input:** rods = \[1,2\]
**Output:** 0
**Explanation:** The billboard cannot be supported, so we return 0.

**Constraints:**

*   `1 <= rods.length <= 20`
*   `1 <= rods[i] <= 1000`
*   `sum(rods[i]) <= 5000`

## A solution in Java

```java
public int numMusicPlaylists(int n, int goal, int k) {
    long MOD = 1000000007;
    long[][] dp = new long[goal + 1][n + 1];
    dp[0][0] = 1;
    for (int i = 1; i <= goal; i++) {
        for (int j = 1; j <= n; j++) {
            dp[i][j] = (dp[i - 1][j - 1] * (n - (j - 1)) % MOD + dp[i - 1][j] * Math.max(0, j - k) % MOD) % MOD;
        }
    }
    return (int) dp[goal][n];
}
```
Here, we use a Dynamic Programming approach to solve the problem. We first create a 2D array dp where dp[i][j] represents the number of playlists of length i formed using j different songs. We initialize dp[0][0] to 1.

Then, we loop through each cell of the dp array from length 1 to goal and from song 1 to n. For each cell, we do the following:
1. Add a new song to the playlist. The number of ways to do this is (n - (j - 1)).
2. Add an existing song to the playlist, with the condition that the song is not played in the last k positions. The number of ways to do this is max(0, j - k).

We add both of these to update the value of dp[i][j] and calculate the result modulo 109 + 7. Eventually, we return the value in dp[goal][n] which is the number of possible playlists of length goal formed using n different songs.

## A solution in C++

```cpp
#include <vector>
#define MOD 1000000007

int numMusicPlaylists(int n, int goal, int k) {
    std::vector<std::vector<long long>> dp(goal + 1, std::vector<long long>(n + 1, 0));
    dp[0][0] = 1;
    for (int i = 1; i <= goal; i++) {
        for (int j = 1; j <= n; j++) {
            dp[i][j] = ((dp[i - 1][j - 1] * (n - (j - 1))) % MOD + (dp[i - 1][j] * std::max(0, j - k)) % MOD) % MOD;
        }
    }
    return dp[goal][n];
}
```
Here, we use a Dynamic Programming approach to solve the problem. We first create a 2D array dp where dp[i][j] represents the number of playlists of length i formed using j different songs. We initialize dp[0][0] to 1.

Then, we loop through each cell of the dp array from length 1 to goal and from song 1 to n. For each cell, we do the following:
1. Add a new song to the playlist. The number of ways to do this is (n - (j - 1)).
2. Add an existing song to the playlist, with the condition that the song is not played in the last k positions. The number of ways to do this is max(0, j - k).

We add both of these to update the value of dp[i][j] and calculate the result modulo 109 + 7. Eventually, we return the value in dp[goal][n] which is the number of possible playlists of length goal formed using n different songs.

## A solution in Python

```python
def numMusicPlaylists(n, goal, k):
    MOD = 1000000007
    dp = [[0] * (n + 1) for _ in range(goal + 1)]
    dp[0][0] = 1
    for i in range(1, goal + 1):
        for j in range(1, n + 1):
            dp[i][j] = (dp[i - 1][j - 1] * (n - (j - 1)) % MOD + dp[i - 1][j] * max(0, j - k) % MOD) % MOD
    return dp[goal][n]
```
Here, we use a Dynamic Programming approach to solve the problem. We first create a 2D array dp where dp[i][j] represents the number of playlists of length i formed using j different songs. We initialize dp[0][0] to 1.

Then, we loop through each cell of the dp array from length 1 to goal and from song 1 to n. For each cell, we do the following:
1. Add a new song to the playlist. The number of ways to do this is (n - (j - 1)).
2. Add an existing song to the playlist, with the condition that the song is not played in the last k positions. The number of ways to do this is max(0, j - k).

We add both of these to update the value of dp[i][j] and calculate the result modulo 109 + 7. Eventually, we return the value in dp[goal][n] which is the number of possible playlists of length goal formed using n different songs.

## A solution in Javascript

```javascript
function numMusicPlaylists(n, goal, k) {
    const MOD = 1_000_000_007;
    const dp = Array.from({ length: goal + 1 }, () => Array.from({ length: n + 1 }, () => 0));
    dp[0][0] = 1;
    for (let i = 1; i <= goal; i++) {
        for (let j = 1; j <= n; j++) {
            dp[i][j] = ((dp[i - 1][j - 1] * (n - (j - 1))) % MOD + (dp[i - 1][j] * Math.max(0, j - k)) % MOD) % MOD;
        }
    }
    return dp[goal][n];
}
```
Here, we use a Dynamic Programming approach to solve the problem. We first create a 2D array dp where dp[i][j] represents the number of playlists of length i formed using j different songs. We initialize dp[0][0] to 1.

Then, we loop through each cell of the dp array from length 1 to goal and from song 1 to n. For each cell, we do the following:
1. Add a new song to the playlist. The number of ways to do this is (n - (j - 1)).
2. Add an existing song to the playlist, with the condition that the song is not played in the last k positions. The number of ways to do this is max(0, j - k).

We add both of these to update the value of dp[i][j] and calculate the result modulo 109 + 7. Eventually, we return the value in dp[goal][n] which is the number of possible playlists of length goal formed using n different songs.


# Prison Cells After N Days

- slug: prison-cells-after-n-days
- difficulty: Medium

There are `8` prison cells in a row and each cell is either occupied or vacant.

Each day, whether the cell is occupied or vacant changes according to the following rules:

*   If a cell has two adjacent neighbors that are both occupied or both vacant, then the cell becomes occupied.
*   Otherwise, it becomes vacant.

**Note** that because the prison is a row, the first and the last cells in the row can't have two adjacent neighbors.

You are given an integer array `cells` where `cells[i] == 1` if the `ith` cell is occupied and `cells[i] == 0` if the `ith` cell is vacant, and you are given an integer `n`.

Return the state of the prison after `n` days (i.e., `n` such changes described above).

**Example 1:**

**Input:** cells = \[0,1,0,1,1,0,0,1\], n = 7
**Output:** \[0,0,1,1,0,0,0,0\]
**Explanation:** The following table summarizes the state of the prison on each day:
Day 0: \[0, 1, 0, 1, 1, 0, 0, 1\]
Day 1: \[0, 1, 1, 0, 0, 0, 0, 0\]
Day 2: \[0, 0, 0, 0, 1, 1, 1, 0\]
Day 3: \[0, 1, 1, 0, 0, 1, 0, 0\]
Day 4: \[0, 0, 0, 0, 0, 1, 0, 0\]
Day 5: \[0, 1, 1, 1, 0, 1, 0, 0\]
Day 6: \[0, 0, 1, 0, 1, 1, 0, 0\]
Day 7: \[0, 0, 1, 1, 0, 0, 0, 0\]

**Example 2:**

**Input:** cells = \[1,0,0,1,0,0,1,0\], n = 1000000000
**Output:** \[0,0,1,1,1,1,1,0\]

**Constraints:**

*   `cells.length == 8`
*   `cells[i]` is either `0` or `1`.
*   `1 <= n <= 109`

## A solution in Java

```java
public int minAddToMakeValid(String s) {
    int result = 0, balance = 0;
    for (char c : s.toCharArray()) {
        balance += (c == '(') ? 1 : -1;
        if (balance == -1) {
            result++;
            balance++;
        }
    }
    return result + balance;
}
```
The algorithm iterates through the string `s`, maintaining a `balance` variable. If an opening parenthesis is encountered, the balance is incremented, and if a closing parenthesis is encountered, the balance is decremented. If the balance becomes -1, this means there is an unmatched closing parenthesis. In this case, we increment `result` (the minimum number of moves required to make the string valid) and adjust the balance. At the end, any remaining balance indicates unmatched opening parentheses, so we add this to `result`.

Complexity: O(n) where n is the length of the input string

## A solution in C++

```cpp
int minAddToMakeValid(string s) {
    int result = 0, balance = 0;
    for (char c : s) {
        balance += (c == '(') ? 1 : -1;
        if (balance == -1) {
            result++;
            balance++;
        }
    }
    return result + balance;
}
```
The algorithm iterates through the string `s`, maintaining a `balance` variable. If an opening parenthesis is encountered, the balance is incremented, and if a closing parenthesis is encountered, the balance is decremented. If the balance becomes -1, this means there is an unmatched closing parenthesis. In this case, we increment `result` (the minimum number of moves required to make the string valid) and adjust the balance. At the end, any remaining balance indicates unmatched opening parentheses, so we add this to `result`.

Complexity: O(n) where n is the length of the input string

## A solution in Python

```python
def minAddToMakeValid(s: str) -> int:
    result = balance = 0
    for c in s:
        balance += 1 if c == '(' else -1
        if balance == -1:
            result += 1
            balance += 1
    return result + balance
```
The algorithm iterates through the string `s`, maintaining a `balance` variable. If an opening parenthesis is encountered, the balance is incremented, and if a closing parenthesis is encountered, the balance is decremented. If the balance becomes -1, this means there is an unmatched closing parenthesis. In this case, we increment `result` (the minimum number of moves required to make the string valid) and adjust the balance. At the end, any remaining balance indicates unmatched opening parentheses, so we add this to `result`.

Complexity: O(n) where n is the length of the input string

## A solution in Javascript

```javascript
function minAddToMakeValid(s) {
    let result = 0, balance = 0;
    for (let c of s) {
        balance += (c === '(') ? 1 : -1;
        if (balance === -1) {
            result++;
            balance++;
        }
    }
    return result + balance;
}
```
The algorithm iterates through the string `s`, maintaining a `balance` variable. If an opening parenthesis is encountered, the balance is incremented, and if a closing parenthesis is encountered, the balance is decremented. If the balance becomes -1, this means there is an unmatched closing parenthesis. In this case, we increment `result` (the minimum number of moves required to make the string valid) and adjust the balance. At the end, any remaining balance indicates unmatched opening parentheses, so we add this to `result`.

Complexity: O(n) where n is the length of the input string


# Check Completeness of a Binary Tree

- slug: check-completeness-of-a-binary-tree
- difficulty: Medium

Given the `root` of a binary tree, determine if it is a _complete binary tree_.

In a **[complete binary tree](http://en.wikipedia.org/wiki/Binary_tree#Types_of_binary_trees)**, every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between `1` and `2h` nodes inclusive at the last level `h`.

**Example 1:**

**Input:** root = \[1,2,3,4,5,6\]
**Output:** true
**Explanation:** Every level before the last is full (ie. levels with node-values {1} and {2, 3}), and all nodes in the last level ({4, 5, 6}) are as far left as possible.

**Example 2:**

**Input:** root = \[1,2,3,4,5,null,7\]
**Output:** false
**Explanation:** The node with value 7 isn't as far left as possible.

**Constraints:**

*   The number of nodes in the tree is in the range `[1, 100]`.
*   `1 <= Node.val <= 1000`

## A solution in Java

```java
public int[] sortArrayByParityII(int[] nums) {
    int j = 1;
    for (int i = 0; i < nums.length; i += 2) {
        if (nums[i] % 2 != 0) {
            while (nums[j] % 2 != 0) {
                j += 2;
            }
            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
        }
    }
    return nums;
}
```
Iterate through the elements of the input array with a step of 2, starting at index 0 (even indices). If the current element is odd, find the nearest odd-indexed element that is even (variable j), and then swap the elements at these indices. This ensures that the even-indexed elements will be even and the odd indexed elements will be odd, satisfying the problem requirements. The time complexity of this algorithm is O(n).

## A solution in C++

```cpp
vector<int> sortArrayByParityII(vector<int>& nums) {
    int j = 1;
    for (int i = 0; i < nums.size(); i += 2) {
        if (nums[i] % 2) {
            while (nums[j] % 2) {
                j += 2;
            }
            swap(nums[i], nums[j]);
        }
    }
    return nums;
}
```
Iterate through the elements of the input array with a step of 2, starting at index 0 (even indices). If the current element is odd, find the nearest odd-indexed element that is even (variable j), and then swap the elements at these indices. This ensures that the even-indexed elements will be even and the odd indexed elements will be odd, satisfying the problem requirements. The time complexity of this algorithm is O(n).

## A solution in Python

```python
def sortArrayByParityII(nums):
    j = 1
    for i in range(0, len(nums), 2):
        if nums[i] % 2:
            while nums[j] % 2:
                j += 2
            nums[i], nums[j] = nums[j], nums[i]
    return nums
```
Iterate through the elements of the input array with a step of 2, starting at index 0 (even indices). If the current element is odd, find the nearest odd-indexed element that is even (variable j), and then swap the elements at these indices. This ensures that the even-indexed elements will be even and the odd indexed elements will be odd, satisfying the problem requirements. The time complexity of this algorithm is O(n).

## A solution in Javascript

```javascript
function sortArrayByParityII(nums) {
    let j = 1;
    for (let i = 0; i < nums.length; i += 2) {
        if (nums[i] % 2 !== 0) {
            while (nums[j] % 2 !== 0) {
                j += 2;
            }
            [nums[i], nums[j]] = [nums[j], nums[i]];
        }
    }
    return nums;
}
```
Iterate through the elements of the input array with a step of 2, starting at index 0 (even indices). If the current element is odd, find the nearest odd-indexed element that is even (variable j), and then swap the elements at these indices. This ensures that the even-indexed elements will be even and the odd indexed elements will be odd, satisfying the problem requirements. The time complexity of this algorithm is O(n).


# Regions Cut By Slashes

- slug: regions-cut-by-slashes
- difficulty: Medium

An `n x n` grid is composed of `1 x 1` squares where each `1 x 1` square consists of a `'/'`, `'\'`, or blank space `' '`. These characters divide the square into contiguous regions.

Given the grid `grid` represented as a string array, return _the number of regions_.

Note that backslash characters are escaped, so a `'\'` is represented as `'\\'`.

**Example 1:**

**Input:** grid = \[ " / ", "/  "\]
**Output:** 2

**Example 2:**

**Input:** grid = \[ " / ", "   "\]
**Output:** 1

**Example 3:**

**Input:** grid = \[ "/\\\\ ", "\\/ "\]
**Output:** 5
**Explanation:** Recall that because \\ characters are escaped,  "\\/ " refers to /, and  "/\\\\ " refers to /\\.

**Constraints:**

*   `n == grid.length == grid[i].length`
*   `1 <= n <= 30`
*   `grid[i][j]` is either `'/'`, `'\'`, or `' '`.

## A solution in Java

```java
import java.util.Arrays;

public int threeSumMulti(int[] arr, int target) {
    int MOD = 1000000007;
    long ans = 0;

    Arrays.sort(arr);
    int n = arr.length;

    for (int i = 0; i < n - 2; ++i) {
        int j = i + 1, k = n - 1;
        while (j < k) {
            int sum = arr[i] + arr[j] + arr[k];
            if (sum > target) {
                k--;
            } else if (sum < target) {
                j++;
            } else {
                if (arr[j] != arr[k]) {
                    int left_count = 1, right_count = 1;

                    while (j < n-1 && arr[j] == arr[j + 1]){
                        left_count++;
                        j++;
                    }
                    while (k > 0 && arr[k] == arr[k - 1]){
                        right_count++;
                        k--;
                    }

                    ans += (long) left_count * right_count;
                    ans %= MOD;
                    j++; k--;
                } else {
                    ans += (long) (k - j + 1) * (k - j) / 2;
                    ans %= MOD;
                    break;
                }
            }
        }
    }

    return (int) ans;
}
```
1. Sort the array.
2. Iterate through the array using 3 pointers (i, j, k) with i starting from the first element, j starting from the second, and k starting from the last one. Make sure i < j < k.
3. Find the sum of elements pointed by i, j and k. If the sum is greater than the target, decrement k. If the sum is less than the target, increment j.
4. Calculate the number of combinations when the sum is equal to the target. Then, update the pointers as required.
5. Continue until i < j < k is not satisfied.
6. Return the result modulo 10^9 + 7.

## A solution in C++

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

int threeSumMulti(std::vector<int>& arr, int target) {
    const int MOD = 1000000007;
    long long ans = 0;

    sort(arr.begin(), arr.end());
    int n = arr.size();

    for (int i = 0; i < n - 2; ++i) {
        int j = i + 1, k = n - 1;
        while (j < k) {
            int sum = arr[i] + arr[j] + arr[k];
            if (sum > target) {
                k--;
            } else if (sum < target) {
                j++;
            } else {
                if (arr[j] != arr[k]) {
                    int left_count = 1, right_count = 1;

                    while (arr[j] == arr[j + 1]){
                        left_count++;
                        j++;
                    }
                    while (arr[k] == arr[k - 1]){
                        right_count++;
                        k--;
                    }

                    ans += left_count * right_count;
                    ans %= MOD;
                    j++, k--;
                } else {
                    ans += (long long)(k - j + 1) * (k - j) / 2;
                    ans %= MOD;
                    break;
                }
            }
        }
    }

    return ans;
}
```
1. Sort the array.
2. Iterate through the array using 3 pointers (i, j, k) with i starting from the first element, j starting from the second, and k starting from the last one. Make sure i < j < k.
3. Find the sum of elements pointed by i, j and k. If the sum is greater than the target, decrement k. If the sum is less than the target, increment j.
4. Calculate the number of combinations when the sum is equal to the target. Then, update the pointers as required.
5. Continue until i < j < k is not satisfied.
6. Return the result modulo 10^9 + 7.

## A solution in Python

```python
def threeSumMulti(arr, target):
    MOD = 1000000007
    ans = 0

    arr.sort()
    n = len(arr)

    for i in range(n - 2):
        j, k = i + 1, n - 1
        while j < k:
            s = arr[i] + arr[j] + arr[k]
            if s > target:
                k -= 1
            elif s < target:
                j += 1
            else:
                if arr[j] != arr[k]:
                    left_count = right_count = 1

                    while j < n - 1 and arr[j] == arr[j + 1]:
                        left_count += 1
                        j += 1

                    while k > 0 and arr[k] == arr[k - 1]:
                        right_count += 1
                        k -= 1

                    ans += left_count * right_count
                    ans %= MOD
                    j += 1
                    k -= 1
                else:
                    ans += (k - j + 1) * (k - j) // 2
                    ans %= MOD
                    break

    return ans
```
1. Sort the array.
2. Iterate through the array using 3 pointers (i, j, k) with i starting from the first element, j starting from the second, and k starting from the last one. Make sure i < j < k.
3. Find the sum of elements pointed by i, j and k. If the sum is greater than the target, decrement k. If the sum is less than the target, increment j.
4. Calculate the number of combinations when the sum is equal to the target. Then, update the pointers as required.
5. Continue until i < j < k is not satisfied.
6. Return the result modulo 10^9 + 7.

## A solution in Javascript

```javascript
function threeSumMulti(arr, target) {
    const MOD = 1000000007;
    let ans = 0;

    arr.sort((a, b) => a - b);
    const n = arr.length;

    for (let i = 0; i < n - 2; ++i) {
        let j = i + 1, k = n - 1;
        while (j < k) {
            const sum = arr[i] + arr[j] + arr[k];
            if (sum > target) {
                k--;
            } else if (sum < target) {
                j++;
            } else {
                if (arr[j] !== arr[k]) {
                    let left_count = 1, right_count = 1;

                    while (j < n - 1 && arr[j] === arr[j + 1]){
                        left_count++;
                        j++;
                    }
                    while (k > 0 && arr[k] === arr[k - 1]){
                        right_count++;
                        k--;
                    }

                    ans += left_count * right_count;
                    ans %= MOD;
                    j++; k--;
                } else {
                    ans += (k - j + 1) * (k - j) / 2;
                    ans %= MOD;
                    break;
                }
            }
        }
    }

    return ans;
}
```
1. Sort the array.
2. Iterate through the array using 3 pointers (i, j, k) with i starting from the first element, j starting from the second, and k starting from the last one. Make sure i < j < k.
3. Find the sum of elements pointed by i, j and k. If the sum is greater than the target, decrement k. If the sum is less than the target, increment j.
4. Calculate the number of combinations when the sum is equal to the target. Then, update the pointers as required.
5. Continue until i < j < k is not satisfied.
6. Return the result modulo 10^9 + 7.


# Delete Columns to Make Sorted III

- slug: delete-columns-to-make-sorted-iii
- difficulty: Hard

You are given an array of `n` strings `strs`, all of the same length.

We may choose any deletion indices, and we delete all the characters in those indices for each string.

For example, if we have `strs = [ "abcdef ", "uvwxyz "]` and deletion indices `{0, 2, 3}`, then the final array after deletions is `[ "bef ", "vyz "]`.

Suppose we chose a set of deletion indices `answer` such that after deletions, the final array has **every string (row) in lexicographic** order. (i.e., `(strs[0][0] <= strs[0][1] <= ... <= strs[0][strs[0].length - 1])`, and `(strs[1][0] <= strs[1][1] <= ... <= strs[1][strs[1].length - 1])`, and so on). Return _the minimum possible value of_ `answer.length`.

**Example 1:**

**Input:** strs = \[ "babca ", "bbazb "\]
**Output:** 3
**Explanation:** After deleting columns 0, 1, and 4, the final array is strs = \[ "bc ",  "az "\].
Both these rows are individually in lexicographic order (ie. strs\[0\]\[0\] <= strs\[0\]\[1\] and strs\[1\]\[0\] <= strs\[1\]\[1\]).
Note that strs\[0\] > strs\[1\] - the array strs is not necessarily in lexicographic order.

**Example 2:**

**Input:** strs = \[ "edcba "\]
**Output:** 4
**Explanation:** If we delete less than 4 columns, the only row will not be lexicographically sorted.

**Example 3:**

**Input:** strs = \[ "ghi ", "def ", "abc "\]
**Output:** 0
**Explanation:** All rows are already lexicographically sorted.

**Constraints:**

*   `n == strs.length`
*   `1 <= n <= 100`
*   `1 <= strs[i].length <= 100`
*   `strs[i]` consists of lowercase English letters.

## A solution in Java

```java
import java.util.*;

class Solution {
    public int minMalwareSpread(int[][] graph, int[] initial) {
        int n = graph.length;
        Arrays.sort(initial);

        Set<Integer> malware = new HashSet<>();
        for (int i : initial) {
            malware.add(i);
        }

        int minNode = initial[0], minSpread = n + 1;
        for (int node : initial) {
            Queue<Integer> q = new LinkedList<>();
            boolean[] visited = new boolean[n];

            for (int otherNode : initial) {
                if (node != otherNode) {
                    q.offer(otherNode);
                    visited[otherNode] = true;
                }
            }

            while (!q.isEmpty()) {
                int cur = q.poll();
                for (int next = 0; next < n; ++next) {
                    if (graph[cur][next] == 1 && !visited[next] && !malware.contains(next)) {
                        visited[next] = true;
                        q.offer(next);
                    }
                }
            }

            int spread = 0;
            for (boolean v : visited) {
                spread += v ? 1 : 0;
            }

            if (spread < minSpread) {
                minNode = node;
                minSpread = spread;
            }
        }

        return minNode;
    }
}
```
The algorithm starts by sorting the node indices of the initial malware-infected nodes in ascending order. Then, it initializes a set called `malware` for efficient look-up of malware-infected nodes. We also initialize variables to store the node index that, when removed, minimizes the number of infected nodes (i.e., `minNode`) and the minimum number of infected nodes across all node removals (i.e., `minSpread`). Next, we iterate through each malware-infected node and simulate the spread of malware after removing the node from the initial set of infected nodes. During each iteration/simulation, we maintain a queue (FIFO) `q` that stores the currently traversed nodes and a `visited` array to keep track of previously traversed nodes. While there are still nodes to traverse, we dequeue a node `cur` from `q` and enqueue all unvisited, non-infected neighboring nodes. After the traversal, we calculate the total number of infected nodes (`spread`) and update `minNode` accordingly. Finally, we return `minNode` as the node that, if removed, would minimize M(initial).

## A solution in C++

```cpp
#include <vector>
#include <unordered_set>
#include <queue>

int minMalwareSpread(std::vector<std::vector<int>>& graph, std::vector<int>& initial) {
    int n = graph.size();
    std::sort(initial.begin(), initial.end());

    std::unordered_set<int> malware(initial.begin(), initial.end());

    int minNode = initial[0], minSpread = n + 1;
    for (int node : initial) {
        std::queue<int> q;
        std::vector<bool> visited(n, false);

        for (int otherNode : initial) {
            if (node != otherNode) {
                q.push(otherNode);
                visited[otherNode] = true;
            }
        }

        while (!q.empty()) {
            int cur = q.front(); q.pop();
            for (int next = 0; next < n; ++next) {
                if (graph[cur][next] == 1 && !visited[next] && !malware.count(next)) {
                    visited[next] = true;
                    q.push(next);
                }
            }
        }

        int spread = 0;
        for (bool v : visited) {
            spread += v;
        }

        if (spread < minSpread) {
            minNode = node;
            minSpread = spread;
        }
    }

    return minNode;
}
```
The algorithm starts by sorting the node indices of the initial malware-infected nodes in ascending order. Then, it initializes a set called `malware` for efficient look-up of malware-infected nodes. We also initialize variables to store the node index that, when removed, minimizes the number of infected nodes (i.e., `minNode`) and the minimum number of infected nodes across all node removals (i.e., `minSpread`). Next, we iterate through each malware-infected node and simulate the spread of malware after removing the node from the initial set of infected nodes. During each iteration/simulation, we maintain a queue (FIFO) `q` that stores the currently traversed nodes and a `visited` array to keep track of previously traversed nodes. While there are still nodes to traverse, we dequeue a node `cur` from `q` and enqueue all unvisited, non-infected neighboring nodes. After the traversal, we calculate the total number of infected nodes (`spread`) and update `minNode` accordingly. Finally, we return `minNode` as the node that, if removed, would minimize M(initial).

## A solution in Python

```python
from collections import deque

def minMalwareSpread(graph, initial):
    n = len(graph)
    initial.sort()

    malware = set(initial)

    minNode = initial[0]
    minSpread = n + 1

    for node in initial:
        q = deque(otherNode for otherNode in initial if node != otherNode)
        visited = [node != otherNode and otherNode in malware for otherNode in range(n)]

        while q:
            cur = q.popleft()
            for next, isConnected in enumerate(graph[cur]):
                if isConnected and not visited[next] and next not in malware:
                    visited[next] = True
                    q.append(next)

        spread = sum(visited)

        if spread < minSpread:
            minNode = node
            minSpread = spread

    return minNode
```
The algorithm starts by sorting the node indices of the initial malware-infected nodes in ascending order. Then, it initializes a set called `malware` for efficient look-up of malware-infected nodes. We also initialize variables to store the node index that, when removed, minimizes the number of infected nodes (i.e., `minNode`) and the minimum number of infected nodes across all node removals (i.e., `minSpread`). Next, we iterate through each malware-infected node and simulate the spread of malware after removing the node from the initial set of infected nodes. During each iteration/simulation, we maintain a queue (FIFO) `q` that stores the currently traversed nodes and a `visited` array to keep track of previously traversed nodes. While there are still nodes to traverse, we dequeue a node `cur` from `q` and enqueue all unvisited, non-infected neighboring nodes. After the traversal, we calculate the total number of infected nodes (`spread`) and update `minNode` accordingly. Finally, we return `minNode` as the node that, if removed, would minimize M(initial).

## A solution in Javascript

```javascript
function minMalwareSpread(graph, initial) {
    const n = graph.length;
    initial.sort((a, b) => a - b);

    const malware = new Set(initial);

    let minNode = initial[0];
    let minSpread = n + 1;

    for (const node of initial) {
        const q = [];
        const visited = new Array(n).fill(false);

        for (const otherNode of initial) {
            if (node !== otherNode) {
                q.push(otherNode);
                visited[otherNode] = true;
            }
        }

        while (q.length) {
            const cur = q.shift();
            for (let next = 0; next < n; ++next) {
                if (graph[cur][next] === 1 && !visited[next] && !malware.has(next)) {
                    visited[next] = true;
                    q.push(next);
                }
            }
        }

        const spread = visited.reduce((acc, v) => acc + (v ? 1 : 0), 0);

        if (spread < minSpread) {
            minNode = node;
            minSpread = spread;
        }
    }

    return minNode;
}
```
The algorithm starts by sorting the node indices of the initial malware-infected nodes in ascending order. Then, it initializes a set called `malware` for efficient look-up of malware-infected nodes. We also initialize variables to store the node index that, when removed, minimizes the number of infected nodes (i.e., `minNode`) and the minimum number of infected nodes across all node removals (i.e., `minSpread`). Next, we iterate through each malware-infected node and simulate the spread of malware after removing the node from the initial set of infected nodes. During each iteration/simulation, we maintain a queue (FIFO) `q` that stores the currently traversed nodes and a `visited` array to keep track of previously traversed nodes. While there are still nodes to traverse, we dequeue a node `cur` from `q` and enqueue all unvisited, non-infected neighboring nodes. After the traversal, we calculate the total number of infected nodes (`spread`) and update `minNode` accordingly. Finally, we return `minNode` as the node that, if removed, would minimize M(initial).


# N-Repeated Element in Size 2N Array

- slug: n-repeated-element-in-size-2n-array
- difficulty: Easy

You are given an integer array `nums` with the following properties:

*   `nums.length == 2 * n`.
*   `nums` contains `n + 1` **unique** elements.
*   Exactly one element of `nums` is repeated `n` times.

Return _the element that is repeated_ `n` _times_.

**Example 1:**

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

**Example 2:**

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

**Example 3:**

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

**Constraints:**

*   `2 <= n <= 5000`
*   `nums.length == 2 * n`
*   `0 <= nums[i] <= 104`
*   `nums` contains `n + 1` **unique** elements and one of them is repeated exactly `n` times.

## A solution in Java

```java
boolean isLongPressedName(String name, String typed) {
    int i = 0, j = 0;
    while (j < typed.length()) {
        if (i < name.length() && name.charAt(i) == typed.charAt(j)) {
            i++;
        } else if (j == 0 || typed.charAt(j) != typed.charAt(j - 1)) {
            return false;
        }
        j++;
    }
    return i == name.length();
}
```
We initialize two pointers i and j, pointing to the current characters in the `name` and `typed` strings. We iterate through the `typed` string using the pointer j, and check the following conditions in each iteration:

1. If the current characters at positions i and j are the same, we increment both pointers i and j.
2. If the current character in the `typed` string (j) does not match the character at position j - 1, it means that there is no long press, and we return False since it cannot be a valid typing.

After the loop, we check if the pointer i reached the end of the `name` string. If it did, it means that all characters in the `name` string were found at the `typed` string with some characters possibly being long pressed. If not, it implies that the `typed` string is not a valid typing of the `name` string, and we return False.

## A solution in C++

```cpp
bool isLongPressedName(string name, string typed) {
    int i = 0, j = 0;
    while (j < typed.length()) {
        if (i < name.length() && name[i] == typed[j]) {
            i++;
        } else if (j == 0 || typed[j] != typed[j - 1]) {
            return false;
        }
        j++;
    }
    return i == name.length();
}
```
We initialize two pointers i and j, pointing to the current characters in the `name` and `typed` strings. We iterate through the `typed` string using the pointer j, and check the following conditions in each iteration:

1. If the current characters at positions i and j are the same, we increment both pointers i and j.
2. If the current character in the `typed` string (j) does not match the character at position j - 1, it means that there is no long press, and we return False since it cannot be a valid typing.

After the loop, we check if the pointer i reached the end of the `name` string. If it did, it means that all characters in the `name` string were found at the `typed` string with some characters possibly being long pressed. If not, it implies that the `typed` string is not a valid typing of the `name` string, and we return False.

## A solution in Python

```python
def isLongPressedName(name: str, typed: str) -> bool:
    i, j = 0, 0
    while j < len(typed):
        if i < len(name) and name[i] == typed[j]:
            i += 1
        elif j == 0 or typed[j] != typed[j - 1]:
            return False
        j += 1
    return i == len(name)
```
We initialize two pointers i and j, pointing to the current characters in the `name` and `typed` strings. We iterate through the `typed` string using the pointer j, and check the following conditions in each iteration:

1. If the current characters at positions i and j are the same, we increment both pointers i and j.
2. If the current character in the `typed` string (j) does not match the character at position j - 1, it means that there is no long press, and we return False since it cannot be a valid typing.

After the loop, we check if the pointer i reached the end of the `name` string. If it did, it means that all characters in the `name` string were found at the `typed` string with some characters possibly being long pressed. If not, it implies that the `typed` string is not a valid typing of the `name` string, and we return False.

## A solution in Javascript

```javascript
function isLongPressedName(name, typed) {
    let i = 0, j = 0;
    while (j < typed.length) {
        if (i < name.length && name[i] === typed[j]) {
            i++;
        } else if (j === 0 || typed[j] !== typed[j - 1]) {
            return false;
        }
        j++;
    }
    return i === name.length;
}
```
We initialize two pointers i and j, pointing to the current characters in the `name` and `typed` strings. We iterate through the `typed` string using the pointer j, and check the following conditions in each iteration:

1. If the current characters at positions i and j are the same, we increment both pointers i and j.
2. If the current character in the `typed` string (j) does not match the character at position j - 1, it means that there is no long press, and we return False since it cannot be a valid typing.

After the loop, we check if the pointer i reached the end of the `name` string. If it did, it means that all characters in the `name` string were found at the `typed` string with some characters possibly being long pressed. If not, it implies that the `typed` string is not a valid typing of the `name` string, and we return False.


# Maximum Width Ramp

- slug: maximum-width-ramp
- difficulty: Medium

A **ramp** in an integer array `nums` is a pair `(i, j)` for which `i < j` and `nums[i] <= nums[j]`. The **width** of such a ramp is `j - i`.

Given an integer array `nums`, return _the maximum width of a **ramp** in_ `nums`. If there is no **ramp** in `nums`, return `0`.

**Example 1:**

**Input:** nums = \[6,0,8,2,1,5\]
**Output:** 4
**Explanation:** The maximum width ramp is achieved at (i, j) = (1, 5): nums\[1\] = 0 and nums\[5\] = 5.

**Example 2:**

**Input:** nums = \[9,8,1,0,1,9,4,0,4,1\]
**Output:** 7
**Explanation:** The maximum width ramp is achieved at (i, j) = (2, 9): nums\[2\] = 1 and nums\[9\] = 1.

**Constraints:**

*   `2 <= nums.length <= 5 * 104`
*   `0 <= nums[i] <= 5 * 104`

## A solution in Java

```java
public int minFlipsMonoIncr(String s) {
    int flipCount = 0, oneCount = 0;
    for (char c : s.toCharArray()) {
        if (c == '1') {
            oneCount++;
        } else {
            flipCount = Math.min(flipCount + 1, oneCount);
        }
    }
    return flipCount;
}
```
We start by initializing two variables, flipCount and oneCount, both set to 0. We iterate through the binary string `s`. If the current character `c` is a 1, we increment `oneCount`. If the current character is a 0, we increment `flipCount` by 1 and then set its value to be the minimum between the updated `flipCount` and `oneCount`. By doing this, we are effectively choosing between two possibilities — flipping the current 0 to 1 or flipping all previous 1's to 0. We return the final `flipCount` when we have processed the whole string, which is the minimum number of flips needed to make the binary string monotone increasing.

## A solution in C++

```cpp
int minFlipsMonoIncr(string s) {
    int flipCount = 0, oneCount = 0;
    for (char c : s) {
        if (c == '1') {
            oneCount++;
        } else {
            flipCount = min(flipCount + 1, oneCount);
        }
    }
    return flipCount;
}
```
We start by initializing two variables, flipCount and oneCount, both set to 0. We iterate through the binary string `s`. If the current character `c` is a 1, we increment `oneCount`. If the current character is a 0, we increment `flipCount` by 1 and then set its value to be the minimum between the updated `flipCount` and `oneCount`. By doing this, we are effectively choosing between two possibilities — flipping the current 0 to 1 or flipping all previous 1's to 0. We return the final `flipCount` when we have processed the whole string, which is the minimum number of flips needed to make the binary string monotone increasing.

## A solution in Python

```python
def minFlipsMonoIncr(s: str) -> int:
    flipCount, oneCount = 0, 0
    for c in s:
        if c == '1':
            oneCount += 1
        else:
            flipCount = min(flipCount + 1, oneCount)
    return flipCount
```
We start by initializing two variables, flipCount and oneCount, both set to 0. We iterate through the binary string `s`. If the current character `c` is a 1, we increment `oneCount`. If the current character is a 0, we increment `flipCount` by 1 and then set its value to be the minimum between the updated `flipCount` and `oneCount`. By doing this, we are effectively choosing between two possibilities — flipping the current 0 to 1 or flipping all previous 1's to 0. We return the final `flipCount` when we have processed the whole string, which is the minimum number of flips needed to make the binary string monotone increasing.

## A solution in Javascript

```javascript
function minFlipsMonoIncr(s) {
    let flipCount = 0, oneCount = 0;
    for (let c of s) {
        if (c === '1') {
            oneCount++;
        } else {
            flipCount = Math.min(flipCount + 1, oneCount);
        }
    }
    return flipCount;
}
```
We start by initializing two variables, flipCount and oneCount, both set to 0. We iterate through the binary string `s`. If the current character `c` is a 1, we increment `oneCount`. If the current character is a 0, we increment `flipCount` by 1 and then set its value to be the minimum between the updated `flipCount` and `oneCount`. By doing this, we are effectively choosing between two possibilities — flipping the current 0 to 1 or flipping all previous 1's to 0. We return the final `flipCount` when we have processed the whole string, which is the minimum number of flips needed to make the binary string monotone increasing.


# Minimum Area Rectangle II

- slug: minimum-area-rectangle-ii
- difficulty: Medium

You are given an array of points in the **X-Y** plane `points` where `points[i] = [xi, yi]`.

Return _the minimum area of any rectangle formed from these points, with sides **not necessarily parallel** to the X and Y axes_. If there is not any such rectangle, return `0`.

Answers within `10-5` of the actual answer will be accepted.

**Example 1:**

**Input:** points = \[\[1,2\],\[2,1\],\[1,0\],\[0,1\]\]
**Output:** 2.00000
**Explanation:** The minimum area rectangle occurs at \[1,2\],\[2,1\],\[1,0\],\[0,1\], with an area of 2.

**Example 2:**

**Input:** points = \[\[0,1\],\[2,1\],\[1,1\],\[1,0\],\[2,0\]\]
**Output:** 1.00000
**Explanation:** The minimum area rectangle occurs at \[1,0\],\[1,1\],\[2,1\],\[2,0\], with an area of 1.

**Example 3:**

**Input:** points = \[\[0,3\],\[1,2\],\[3,1\],\[1,3\],\[2,1\]\]
**Output:** 0
**Explanation:** There is no possible rectangle to form from these points.

**Constraints:**

*   `1 <= points.length <= 50`
*   `points[i].length == 2`
*   `0 <= xi, yi <= 4 * 104`
*   All the given points are **unique**.

## A solution in Java

```java
import java.util.Arrays;

public int[] findSameBinaryValueParts(int[] arr) {
    int ones = 0;
    for (int n : arr) ones += n;

    if (ones % 3 != 0) return new int[]{-1, -1};

    int target = ones / 3;
    if (target == 0) return new int[]{0, arr.length - 2};

    int count = 0, i = -1, j = -1;
    ones = 0;
    for (int idx = 0; idx < arr.length; ++idx) {
        if (arr[idx] == 1) {
            ones++;
            if (ones == target + 1) count++;
            if (count == 1 && i == -1) i = idx;
            if (count == 2 && j == -1) j = idx;
            if (count == 3) break;
        }
    }

    return new int[]{i, j};
}
```
The algorithm starts by counting the total number of ones in the input array. If the number of ones is not divisible by 3, it's impossible to divide the array into three equal binary values, and the algorithm returns `[-1, -1]`. If the number of ones is 0, it means the whole array consists of only zeros, and the algorithm returns `[0, len(array) - 2]`.

Then, the target number of ones in each part is calculated by dividing the total ones by 3. The algorithm initializes `i` and `j` indices with `-1`. It iterates through the array while keeping track of the ones count in each part. When the number of ones exceeds the target value (`ones == target + 1`), it increments the parts count. The algorithm sets the `i` index when it finds the first part and the `j` index when it finds the second part. When the third part is found, the algorithm breaks out of the loop and returns the found indices `[i, j]`.

The time complexity of the algorithm is O(n), where n is the length of the input array, and the space complexity is O(1).

## A solution in C++

```cpp
#include <vector>

std::vector<int> find_same_binary_value_parts(const std::vector<int>& arr) {
    int ones = 0;
    for (int n : arr) ones += n;

    if (ones % 3 != 0) return {-1, -1};

    int target = ones / 3;
    if (target == 0) return {0, static_cast<int>(arr.size()) - 2};

    int count = 0, i = -1, j = -1;
    ones = 0;
    for (int idx = 0; idx < arr.size(); ++idx) {
        if (arr[idx] == 1) {
            ones++;
            if (ones == target + 1) count++;
            if (count == 1 && i == -1) i = idx;
            if (count == 2 && j == -1) j = idx;
            if (count == 3) break;
        }
    }

    return {i, j};
}
```
The algorithm starts by counting the total number of ones in the input array. If the number of ones is not divisible by 3, it's impossible to divide the array into three equal binary values, and the algorithm returns `[-1, -1]`. If the number of ones is 0, it means the whole array consists of only zeros, and the algorithm returns `[0, len(array) - 2]`.

Then, the target number of ones in each part is calculated by dividing the total ones by 3. The algorithm initializes `i` and `j` indices with `-1`. It iterates through the array while keeping track of the ones count in each part. When the number of ones exceeds the target value (`ones == target + 1`), it increments the parts count. The algorithm sets the `i` index when it finds the first part and the `j` index when it finds the second part. When the third part is found, the algorithm breaks out of the loop and returns the found indices `[i, j]`.

The time complexity of the algorithm is O(n), where n is the length of the input array, and the space complexity is O(1).

## A solution in Python

```python
def find_same_binary_value_parts(arr):
    ones = sum(arr)

    if ones % 3 != 0:
        return [-1, -1]

    target = ones // 3
    if target == 0:
        return [0, len(arr) - 2]

    count = 0
    i = j = -1
    ones = 0
    for idx, n in enumerate(arr):
        if n == 1:
            ones += 1
            if ones == target + 1:
                count += 1
            if count == 1 and i == -1:
                i = idx
            if count == 2 and j == -1:
                j = idx
            if count == 3:
                break

    return [i, j]
```
The algorithm starts by counting the total number of ones in the input array. If the number of ones is not divisible by 3, it's impossible to divide the array into three equal binary values, and the algorithm returns `[-1, -1]`. If the number of ones is 0, it means the whole array consists of only zeros, and the algorithm returns `[0, len(array) - 2]`.

Then, the target number of ones in each part is calculated by dividing the total ones by 3. The algorithm initializes `i` and `j` indices with `-1`. It iterates through the array while keeping track of the ones count in each part. When the number of ones exceeds the target value (`ones == target + 1`), it increments the parts count. The algorithm sets the `i` index when it finds the first part and the `j` index when it finds the second part. When the third part is found, the algorithm breaks out of the loop and returns the found indices `[i, j]`.

The time complexity of the algorithm is O(n), where n is the length of the input array, and the space complexity is O(1).

## A solution in Javascript

```javascript
function findSameBinaryValueParts(arr) {
    let ones = arr.reduce((sum, n) => sum + n, 0);

    if (ones % 3 !== 0) return [-1, -1];

    let target = Math.floor(ones / 3);
    if (target === 0) return [0, arr.length - 2];

    let count = 0, i = -1, j = -1;
    ones = 0;
    for (let idx = 0; idx < arr.length; ++idx) {
        if (arr[idx] === 1) {
            ones++;
            if (ones === target + 1) count++;
            if (count === 1 && i === -1) i = idx;
            if (count === 2 && j === -1) j = idx;
            if (count === 3) break;
        }
    }

    return [i, j];
}
```
The algorithm starts by counting the total number of ones in the input array. If the number of ones is not divisible by 3, it's impossible to divide the array into three equal binary values, and the algorithm returns `[-1, -1]`. If the number of ones is 0, it means the whole array consists of only zeros, and the algorithm returns `[0, len(array) - 2]`.

Then, the target number of ones in each part is calculated by dividing the total ones by 3. The algorithm initializes `i` and `j` indices with `-1`. It iterates through the array while keeping track of the ones count in each part. When the number of ones exceeds the target value (`ones == target + 1`), it increments the parts count. The algorithm sets the `i` index when it finds the first part and the `j` index when it finds the second part. When the third part is found, the algorithm breaks out of the loop and returns the found indices `[i, j]`.

The time complexity of the algorithm is O(n), where n is the length of the input array, and the space complexity is O(1).


# Least Operators to Express Number

- slug: least-operators-to-express-number
- difficulty: Hard

Given a single positive integer `x`, we will write an expression of the form `x (op1) x (op2) x (op3) x ...` where each operator `op1`, `op2`, etc. is either addition, subtraction, multiplication, or division (`+`, `-`, `*`, or `/)`. For example, with `x = 3`, we might write `3 * 3 / 3 + 3 - 3` which is a value of 3.

When writing such an expression, we adhere to the following conventions:

*   The division operator (`/`) returns rational numbers.
*   There are no parentheses placed anywhere.
*   We use the usual order of operations: multiplication and division happen before addition and subtraction.
*   It is not allowed to use the unary negation operator (`-`). For example, "`x - x` " is a valid expression as it only uses subtraction, but "`-x + x` " is not because it uses negation.

We would like to write an expression with the least number of operators such that the expression equals the given `target`. Return the least number of operators used.

**Example 1:**

**Input:** x = 3, target = 19
**Output:** 5
**Explanation:** 3 \* 3 + 3 \* 3 + 3 / 3.
The expression contains 5 operations.

**Example 2:**

**Input:** x = 5, target = 501
**Output:** 8
**Explanation:** 5 \* 5 \* 5 \* 5 - 5 \* 5 \* 5 + 5 / 5.
The expression contains 8 operations.

**Example 3:**

**Input:** x = 100, target = 100000000
**Output:** 3
**Explanation:** 100 \* 100 \* 100 \* 100.
The expression contains 3 operations.

**Constraints:**

*   `2 <= x <= 100`
*   `1 <= target <= 2 * 108`

## A solution in Java

```java
import java.util.*;

class Solution {
    public int minMalwareSpread(int[][] graph, int[] initial) {
        int n = graph.length, res = 0, minSize = Integer.MAX_VALUE;
        int[] color = new int[n];
        Arrays.fill(color, -1);
        int colors = 0;

        for (int i = 0; i < n; ++i) {
            if (color[i] == -1) {
                Queue<Integer> q = new LinkedList<>();
                q.offer(i);
                color[i] = colors;

                while (!q.isEmpty()) {
                    int t = q.poll();
                    for (int j = 0; j < n; ++j) {
                        if (graph[t][j] == 1 && color[j] == -1) {
                            q.offer(j);
                            color[j] = colors;
                        }
                    }
                }
                ++colors;
            }
        }

        int[] area = new int[colors], count = new int[colors];
        Set<Integer> initiallyInfected = new HashSet<>();
        for (int i : initial) {
            initiallyInfected.add(i);
        }
        for (int i = 0; i < n; ++i) {
            ++area[color[i]];
            if (initiallyInfected.contains(i)) {
                ++count[color[i]];
            }
        }

        for (int i : initial) {
            if (count[color[i]] == 1) {
                if (area[color[i]] < minSize) {
                    minSize = area[color[i]];
                    res = i;
                } else if (area[color[i]] == minSize && i < res) {
                    res = i;
                }
            }
        }

        return res;
    }
}
```
Initially, we mark all nodes with a unique color in such a way that adjacent nodes have the same color, so that we can track how many uninfected nodes are connected to every infected node in the initial set. We use BFS to do the coloring operation. Then, we calculate the number of nodes for each unique color and calculate the count of nodes in the initial set that share the same color.

Finally, we iterate through every node in the initial list, and if that node's color has a count of 1, meaning it is the only infected node in its group, we check if it minimizes the number of nodes infected post-removal. If so, the result is updated to the current node. The result is the node that, if removed, would minimize M(initial). If there are multiple such nodes, the one with the smallest index is returned.

## A solution in C++

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

int minMalwareSpread(vector<vector<int>>& graph, vector<int>& initial) {
    int n = graph.size(), res = 0, minSize = INT_MAX;
    vector<int> color(n, -1);
    int colors = 0;

    for (int i = 0; i < n; ++i) {
        if (color[i] == -1) {
            queue<int> q;
            q.push(i);
            color[i] = colors;

            while (!q.empty()) {
                int t = q.front(); q.pop();
                for (int j = 0; j < n; ++j) {
                    if (graph[t][j] == 1 && color[j] == -1) {
                        q.push(j);
                        color[j] = colors;
                    }
                }
            }
            ++colors;
        }
    }

    vector<int> area(colors, 0), count(colors, 0);
    set<int> initiallyInfected(initial.begin(), initial.end());
    for (int i = 0; i < n; ++i) {
        ++area[color[i]];
        if (initiallyInfected.count(i)) {
            ++count[color[i]];
        }
    }

    for (int i : initial) {
        if (count[color[i]] == 1) {
            if (area[color[i]] < minSize) {
                minSize = area[color[i]];
                res = i;
            } else if (area[color[i]] == minSize && i < res) {
                res = i;
            }
        }
    }

    return res;
}
```
Initially, we mark all nodes with a unique color in such a way that adjacent nodes have the same color, so that we can track how many uninfected nodes are connected to every infected node in the initial set. We use BFS to do the coloring operation. Then, we calculate the number of nodes for each unique color and calculate the count of nodes in the initial set that share the same color.

Finally, we iterate through every node in the initial list, and if that node's color has a count of 1, meaning it is the only infected node in its group, we check if it minimizes the number of nodes infected post-removal. If so, the result is updated to the current node. The result is the node that, if removed, would minimize M(initial). If there are multiple such nodes, the one with the smallest index is returned.

## A solution in Python

```python
from collections import deque
from typing import List

def minMalwareSpread(graph: List[List[int]], initial: List[int]) -> int:
    n = len(graph)
    color = [-1] * n
    colors = 0

    for i in range(n):
        if color[i] == -1:
            q = deque([i])
            color[i] = colors

            while q:
                t = q.popleft()
                for j in range(n):
                    if graph[t][j] == 1 and color[j] == -1:
                        q.append(j)
                        color[j] = colors

            colors += 1

    area = [0] * colors
    count = [0] * colors
    initially_infected = set(initial)
    for i in range(n):
        area[color[i]] += 1
        if i in initially_infected:
            count[color[i]] += 1

    res = min(initial)
    min_size = n + 1
    for i in initial:
        if count[color[i]] == 1:
            if area[color[i]] < min_size:
                min_size = area[color[i]]
                res = i
            elif area[color[i]] == min_size and i < res:
                res = i

    return res
```
Initially, we mark all nodes with a unique color in such a way that adjacent nodes have the same color, so that we can track how many uninfected nodes are connected to every infected node in the initial set. We use BFS to do the coloring operation. Then, we calculate the number of nodes for each unique color and calculate the count of nodes in the initial set that share the same color.

Finally, we iterate through every node in the initial list, and if that node's color has a count of 1, meaning it is the only infected node in its group, we check if it minimizes the number of nodes infected post-removal. If so, the result is updated to the current node. The result is the node that, if removed, would minimize M(initial). If there are multiple such nodes, the one with the smallest index is returned.

## A solution in Javascript

```javascript
function minMalwareSpread(graph, initial) {
    const n = graph.length;
    const color = new Array(n).fill(-1);
    let colors = 0;

    for (let i = 0; i < n; ++i) {
        if (color[i] === -1) {
            const q = [i];
            color[i] = colors;

            while (q.length) {
                const t = q.shift();
                for (let j = 0; j < n; ++j) {
                    if (graph[t][j] === 1 && color[j] === -1) {
                        q.push(j);
                        color[j] = colors;
                    }
                }
            }
            ++colors;
        }
    }

    const area = new Array(colors).fill(0);
    const count = new Array(colors).fill(0);
    const initiallyInfected = new Set(initial);

    for (let i = 0; i < n; ++i) {
        ++area[color[i]];
        if (initiallyInfected.has(i)) {
            ++count[color[i]];
        }
    }

    let res = initial[0];
    let minSize = n + 1;
    for (const i of initial) {
        if (count[color[i]] === 1) {
            if (area[color[i]] < minSize) {
                minSize = area[color[i]];
                res = i;
            } else if (area[color[i]] === minSize && i < res) {
                res = i;
            }
        }
    }

    return res;
}
```
Initially, we mark all nodes with a unique color in such a way that adjacent nodes have the same color, so that we can track how many uninfected nodes are connected to every infected node in the initial set. We use BFS to do the coloring operation. Then, we calculate the number of nodes for each unique color and calculate the count of nodes in the initial set that share the same color.

Finally, we iterate through every node in the initial list, and if that node's color has a count of 1, meaning it is the only infected node in its group, we check if it minimizes the number of nodes infected post-removal. If so, the result is updated to the current node. The result is the node that, if removed, would minimize M(initial). If there are multiple such nodes, the one with the smallest index is returned.


# Univalued Binary Tree

- slug: univalued-binary-tree
- difficulty: Easy

A binary tree is **uni-valued** if every node in the tree has the same value.

Given the `root` of a binary tree, return `true` _if the given tree is **uni-valued**, or_ `false` _otherwise._

**Example 1:**

**Input:** root = \[1,1,1,1,1,null,1\]
**Output:** true

**Example 2:**

**Input:** root = \[2,2,2,5,2\]
**Output:** false

**Constraints:**

*   The number of nodes in the tree is in the range `[1, 100]`.
*   `0 <= Node.val < 100`

## A solution in Java

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

public int numUniqueEmails(String[] emails) {
    Set<String> unique_emails = new HashSet<>();

    for (String email : emails) {
        String[] parts = email.split("@");
        String local_name = parts[0], domain_name = parts[1];

        local_name = local_name.replaceAll("\\+", "@").split("@")[0];
        local_name = local_name.replaceAll("\\.", "");

        unique_emails.add(local_name + "@" + domain_name);
    }

    return unique_emails.size();
}
```
The algorithm iterates through each email in the input array/list. For each email, the local name and domain name are separated based on the '@' sign. Next, the '+' sign is considered, and everything after the first '+' sign is ignored in the local name. Then, all the '.' characters in the local name are removed. Finally, the processed local name and domain name are combined and added to a set, which will hold unique email addresses. After processing all the email addresses, the size of the set represents the number of unique email addresses that actually receive mails.

## A solution in C++

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

int numUniqueEmails(std::vector<std::string>& emails) {
    std::set<std::string> unique_emails;

    for (auto& email : emails) {
        std::string local_name, domain_name;
        bool at_sign_found = false, plus_sign_found = false;

        for (char c : email) {
            if (!at_sign_found) {
                if (c == '+') plus_sign_found = true;
                else if (c == '@') at_sign_found = true;
                else if (!plus_sign_found && c != '.') local_name += c;
            }
            else domain_name += c;
        }

        unique_emails.insert(local_name + "@" + domain_name);
    }

    return unique_emails.size();
}
```
The algorithm iterates through each email in the input array/list. For each email, the local name and domain name are separated based on the '@' sign. Next, the '+' sign is considered, and everything after the first '+' sign is ignored in the local name. Then, all the '.' characters in the local name are removed. Finally, the processed local name and domain name are combined and added to a set, which will hold unique email addresses. After processing all the email addresses, the size of the set represents the number of unique email addresses that actually receive mails.

## A solution in Python

```python
def num_unique_emails(emails):
    unique_emails = set()

    for email in emails:
        local_name, domain_name = email.split("@")
        local_name = local_name.split("+")[0]
        local_name = local_name.replace(".", "")

        unique_emails.add(local_name + "@" + domain_name)

    return len(unique_emails)
```
The algorithm iterates through each email in the input array/list. For each email, the local name and domain name are separated based on the '@' sign. Next, the '+' sign is considered, and everything after the first '+' sign is ignored in the local name. Then, all the '.' characters in the local name are removed. Finally, the processed local name and domain name are combined and added to a set, which will hold unique email addresses. After processing all the email addresses, the size of the set represents the number of unique email addresses that actually receive mails.

## A solution in Javascript

```javascript
function numUniqueEmails(emails) {
    let unique_emails = new Set();

    emails.forEach((email) => {
        let [local_name, domain_name] = email.split("@");
        local_name = local_name.split("+")[0];
        local_name = local_name.replace(/\./g, "");

        unique_emails.add(local_name + "@" + domain_name);
    });

    return unique_emails.size;
}
```
The algorithm iterates through each email in the input array/list. For each email, the local name and domain name are separated based on the '@' sign. Next, the '+' sign is considered, and everything after the first '+' sign is ignored in the local name. Then, all the '.' characters in the local name are removed. Finally, the processed local name and domain name are combined and added to a set, which will hold unique email addresses. After processing all the email addresses, the size of the set represents the number of unique email addresses that actually receive mails.


# Vowel Spellchecker

- slug: vowel-spellchecker
- difficulty: Medium

Given a `wordlist`, we want to implement a spellchecker that converts a query word into a correct word.

For a given `query` word, the spell checker handles two categories of spelling mistakes:

*   Capitalization: If the query matches a word in the wordlist (**case-insensitive**), then the query word is returned with the same case as the case in the wordlist.
    *   Example: `wordlist = [ "yellow "]`, `query = "YellOw "`: `correct = "yellow "`
    *   Example: `wordlist = [ "Yellow "]`, `query = "yellow "`: `correct = "Yellow "`
    *   Example: `wordlist = [ "yellow "]`, `query = "yellow "`: `correct = "yellow "`
*   Vowel Errors: If after replacing the vowels `('a', 'e', 'i', 'o', 'u')` of the query word with any vowel individually, it matches a word in the wordlist (**case-insensitive**), then the query word is returned with the same case as the match in the wordlist.
    *   Example: `wordlist = [ "YellOw "]`, `query = "yollow "`: `correct = "YellOw "`
    *   Example: `wordlist = [ "YellOw "]`, `query = "yeellow "`: `correct = " "` (no match)
    *   Example: `wordlist = [ "YellOw "]`, `query = "yllw "`: `correct = " "` (no match)

In addition, the spell checker operates under the following precedence rules:

*   When the query exactly matches a word in the wordlist (**case-sensitive**), you should return the same word back.
*   When the query matches a word up to capitlization, you should return the first such match in the wordlist.
*   When the query matches a word up to vowel errors, you should return the first such match in the wordlist.
*   If the query has no matches in the wordlist, you should return the empty string.

Given some `queries`, return a list of words `answer`, where `answer[i]` is the correct word for `query = queries[i]`.

**Example 1:**

**Input:** wordlist = \["KiTe","kite","hare","Hare"\], queries = \["kite","Kite","KiTe","Hare","HARE","Hear","hear","keti","keet","keto"\]
**Output:** \["kite","KiTe","KiTe","Hare","hare","","","KiTe","","KiTe"\]

**Example 2:**

**Input:** wordlist = \["yellow"\], queries = \["YellOw"\]
**Output:** \["yellow"\]

**Constraints:**

*   `1 <= wordlist.length, queries.length <= 5000`
*   `1 <= wordlist[i].length, queries[i].length <= 7`
*   `wordlist[i]` and `queries[i]` consist only of only English letters.

## A solution in Java

```java
import java.util.HashMap;

public int numSubarraysWithSum(int[] nums, int goal) {
    HashMap<Integer, Integer> prefixSumCount = new HashMap<>();
    prefixSumCount.put(0, 1);
    int sum = 0, result = 0;

    for (int num : nums) {
        sum += num;
        result += prefixSumCount.getOrDefault(sum - goal, 0);
        prefixSumCount.put(sum, prefixSumCount.getOrDefault(sum, 0) + 1);
    }

    return result;
}
```
The algorithm uses the prefix sum technique with a hash map to store the count of each prefix sum. It iterates through the given binary array, adding each element to the cumulative sum. For each cumulative sum, the algorithm checks how many prefix sums are equal to the current cumulative sum minus the given goal. The algorithm then adds this count to the result.

After iterating through the entire array, the result will be the number of non-empty subarrays with a sum equal to the given goal.

## A solution in C++

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

int numSubarraysWithSum(std::vector<int>& nums, int goal) {
    std::unordered_map<int, int> prefix_sum_count = {{0, 1}};
    int sum = 0, result = 0;

    for (const auto& num : nums) {
        sum += num;
        result += prefix_sum_count[sum - goal];
        prefix_sum_count[sum]++;
    }

    return result;
}
```
The algorithm uses the prefix sum technique with a hash map to store the count of each prefix sum. It iterates through the given binary array, adding each element to the cumulative sum. For each cumulative sum, the algorithm checks how many prefix sums are equal to the current cumulative sum minus the given goal. The algorithm then adds this count to the result.

After iterating through the entire array, the result will be the number of non-empty subarrays with a sum equal to the given goal.

## A solution in Python

```python
def num_subarrays_with_sum(nums, goal):
    from collections import defaultdict
    prefix_sum_count = defaultdict(int)
    prefix_sum_count[0] = 1
    cumulative_sum, result = 0, 0

    for num in nums:
        cumulative_sum += num
        result += prefix_sum_count[cumulative_sum - goal]
        prefix_sum_count[cumulative_sum] += 1

    return result
```
The algorithm uses the prefix sum technique with a hash map to store the count of each prefix sum. It iterates through the given binary array, adding each element to the cumulative sum. For each cumulative sum, the algorithm checks how many prefix sums are equal to the current cumulative sum minus the given goal. The algorithm then adds this count to the result.

After iterating through the entire array, the result will be the number of non-empty subarrays with a sum equal to the given goal.

## A solution in Javascript

```javascript
function numSubarraysWithSum(nums, goal) {
    const prefixSumCount = {0: 1};
    let sum = 0, result = 0;

    for (const num of nums) {
        sum += num;
        result += (prefixSumCount[sum - goal] || 0);
        prefixSumCount[sum] = (prefixSumCount[sum] || 0) + 1;
    }

    return result;
}
```
The algorithm uses the prefix sum technique with a hash map to store the count of each prefix sum. It iterates through the given binary array, adding each element to the cumulative sum. For each cumulative sum, the algorithm checks how many prefix sums are equal to the current cumulative sum minus the given goal. The algorithm then adds this count to the result.

After iterating through the entire array, the result will be the number of non-empty subarrays with a sum equal to the given goal.


# Numbers With Same Consecutive Differences

- slug: numbers-with-same-consecutive-differences
- difficulty: Medium

Given two integers n and k, return _an array of all the integers of length_ `n` _where the difference between every two consecutive digits is_ `k`. You may return the answer in **any order**.

Note that the integers should not have leading zeros. Integers as `02` and `043` are not allowed.

**Example 1:**

**Input:** n = 3, k = 7
**Output:** \[181,292,707,818,929\]
**Explanation:** Note that 070 is not a valid number, because it has leading zeroes.

**Example 2:**

**Input:** n = 2, k = 1
**Output:** \[10,12,21,23,32,34,43,45,54,56,65,67,76,78,87,89,98\]

**Constraints:**

*   `2 <= n <= 9`
*   `0 <= k <= 9`

## A solution in Java

```java
public int minFallingPathSum(int[][] matrix) {
    int n = matrix.length;
    for (int i = 1; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            int min_val = matrix[i - 1][j];
            if (j > 0) min_val = Math.min(min_val, matrix[i - 1][j - 1]);
            if (j < n - 1) min_val = Math.min(min_val, matrix[i - 1][j + 1]);
            matrix[i][j] += min_val;
        }
    }
    return Arrays.stream(matrix[n - 1]).min().getAsInt();
}
```
In this dynamic programming algorithm, we start by iterating over every element in the matrix (except the first row). For each element (i, j), we find the minimum value from the row above (i.e., i-1), considering the left [i-1][j-1], top [i-1][j], and right [i-1][j+1] positions (if they exist). We add the minimum value to the current element, iteratively updating the sum of each falling path as we go down the matrix. Once we reach the last row, we find the minimum element in this row, which represents the minimum sum of any falling path.

This algorithm has a time complexity of O(n^2), as it iterates over the n x n matrix once.

## A solution in C++

```cpp
int minFallingPathSum(vector<vector<int>>& matrix) {
    int n = matrix.size();
    for (int i = 1; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            int min_val = matrix[i - 1][j];
            if (j > 0) min_val = min(min_val, matrix[i - 1][j - 1]);
            if (j < n - 1) min_val = min(min_val, matrix[i - 1][j + 1]);
            matrix[i][j] += min_val;
        }
    }
    return *min_element(matrix.back().begin(), matrix.back().end());
}
```
In this dynamic programming algorithm, we start by iterating over every element in the matrix (except the first row). For each element (i, j), we find the minimum value from the row above (i.e., i-1), considering the left [i-1][j-1], top [i-1][j], and right [i-1][j+1] positions (if they exist). We add the minimum value to the current element, iteratively updating the sum of each falling path as we go down the matrix. Once we reach the last row, we find the minimum element in this row, which represents the minimum sum of any falling path.

This algorithm has a time complexity of O(n^2), as it iterates over the n x n matrix once.

## A solution in Python

```python
def minFallingPathSum(matrix):
    n = len(matrix)
    for i in range(1, n):
        for j in range(n):
            min_val = matrix[i - 1][j]
            if j > 0: min_val = min(min_val, matrix[i - 1][j - 1])
            if j < n - 1: min_val = min(min_val, matrix[i - 1][j + 1])
            matrix[i][j] += min_val
    return min(matrix[-1])
```
In this dynamic programming algorithm, we start by iterating over every element in the matrix (except the first row). For each element (i, j), we find the minimum value from the row above (i.e., i-1), considering the left [i-1][j-1], top [i-1][j], and right [i-1][j+1] positions (if they exist). We add the minimum value to the current element, iteratively updating the sum of each falling path as we go down the matrix. Once we reach the last row, we find the minimum element in this row, which represents the minimum sum of any falling path.

This algorithm has a time complexity of O(n^2), as it iterates over the n x n matrix once.

## A solution in Javascript

```javascript
function minFallingPathSum(matrix) {
    let n = matrix.length;
    for (let i = 1; i < n; ++i) {
        for (let j = 0; j < n; ++j) {
            let min_val = matrix[i - 1][j];
            if (j > 0) min_val = Math.min(min_val, matrix[i - 1][j - 1]);
            if (j < n - 1) min_val = Math.min(min_val, matrix[i - 1][j + 1]);
            matrix[i][j] += min_val;
        }
    }
    return Math.min(...matrix[n - 1]);
}
```
In this dynamic programming algorithm, we start by iterating over every element in the matrix (except the first row). For each element (i, j), we find the minimum value from the row above (i.e., i-1), considering the left [i-1][j-1], top [i-1][j], and right [i-1][j+1] positions (if they exist). We add the minimum value to the current element, iteratively updating the sum of each falling path as we go down the matrix. Once we reach the last row, we find the minimum element in this row, which represents the minimum sum of any falling path.

This algorithm has a time complexity of O(n^2), as it iterates over the n x n matrix once.


# Binary Tree Cameras

- slug: binary-tree-cameras
- difficulty: Hard

You are given the `root` of a binary tree. We install cameras on the tree nodes where each camera at a node can monitor its parent, itself, and its immediate children.

Return _the minimum number of cameras needed to monitor all nodes of the tree_.

**Example 1:**

**Input:** root = \[0,0,null,0,0\]
**Output:** 1
**Explanation:** One camera is enough to monitor all nodes if placed as shown.

**Example 2:**

**Input:** root = \[0,0,null,0,null,0,null,null,0\]
**Output:** 2
**Explanation:** At least two cameras are needed to monitor all nodes of the tree. The above image shows one of the valid configurations of camera placement.

**Constraints:**

*   The number of nodes in the tree is in the range `[1, 1000]`.
*   `Node.val == 0`

## A solution in Java

```java
public int[] beautifulArray(int n) {
    List<Integer> result = new ArrayList<>();
    result.add(1);
    while (result.size() < n) {
        List<Integer> temp = new ArrayList<>();
        for (int i : result) {
            if (i * 2 - 1 <= n)
                temp.add(i * 2 - 1);
        }
        for (int i : result) {
            if (i * 2 <= n)
                temp.add(i * 2);
        }
        result = temp;
    }
    return result.stream().mapToInt(i->i).toArray();
}
```
The algorithm starts with an array containing just the number 1. It then generates a new array by iterating through the current array and checking if the element value multiplied by 2 minus 1 and the element value multiplied by 2 are both less than or equal to n. If they are, these two new numbers are added to a temporary array. The current array now becomes the temporary array. This process continues until the size of the current array is equal to the integer n.

The resulting array is a beautiful array because it satisfies the conditions of the question. This approach works as the operations in the algorithm ensure that elements in the odd positions and even positions will always be less than or equal to n, thus maintaining the desired intervals between elements.

## A solution in C++

```cpp
vector<int> beautifulArray(int n) {
    vector<int> result = {1};
    while (result.size() < n) {
        vector<int> temp;
        for (int i : result) {
            if (i * 2 - 1 <= n)
                temp.push_back(i * 2 - 1);
        }
        for (int i : result) {
            if (i * 2 <= n)
                temp.push_back(i * 2);
        }
        result = temp;
    }
    return result;
}
```
The algorithm starts with an array containing just the number 1. It then generates a new array by iterating through the current array and checking if the element value multiplied by 2 minus 1 and the element value multiplied by 2 are both less than or equal to n. If they are, these two new numbers are added to a temporary array. The current array now becomes the temporary array. This process continues until the size of the current array is equal to the integer n.

The resulting array is a beautiful array because it satisfies the conditions of the question. This approach works as the operations in the algorithm ensure that elements in the odd positions and even positions will always be less than or equal to n, thus maintaining the desired intervals between elements.

## A solution in Python

```python
def beautifulArray(n: int) -> List[int]:
    result = [1]
    while len(result) < n:
        temp = []
        for i in result:
            if i * 2 - 1 <= n:
                temp.append(i * 2 - 1)
        for i in result:
            if i * 2 <= n:
                temp.append(i * 2)
        result = temp
    return result
```
The algorithm starts with an array containing just the number 1. It then generates a new array by iterating through the current array and checking if the element value multiplied by 2 minus 1 and the element value multiplied by 2 are both less than or equal to n. If they are, these two new numbers are added to a temporary array. The current array now becomes the temporary array. This process continues until the size of the current array is equal to the integer n.

The resulting array is a beautiful array because it satisfies the conditions of the question. This approach works as the operations in the algorithm ensure that elements in the odd positions and even positions will always be less than or equal to n, thus maintaining the desired intervals between elements.

## A solution in Javascript

```javascript
function beautifulArray(n) {
    let result = [1];
    while (result.length < n) {
        let temp = [];
        for (let i of result) {
            if (i * 2 - 1 <= n)
                temp.push(i * 2 - 1);
        }
        for (let i of result) {
            if (i * 2 <= n)
                temp.push(i * 2);
        }
        result = temp;
    }
    return result;
}
```
The algorithm starts with an array containing just the number 1. It then generates a new array by iterating through the current array and checking if the element value multiplied by 2 minus 1 and the element value multiplied by 2 are both less than or equal to n. If they are, these two new numbers are added to a temporary array. The current array now becomes the temporary array. This process continues until the size of the current array is equal to the integer n.

The resulting array is a beautiful array because it satisfies the conditions of the question. This approach works as the operations in the algorithm ensure that elements in the odd positions and even positions will always be less than or equal to n, thus maintaining the desired intervals between elements.


# Pancake Sorting

- slug: pancake-sorting
- difficulty: Medium

Given an array of integers `arr`, sort the array by performing a series of **pancake flips**.

In one pancake flip we do the following steps:

*   Choose an integer `k` where `1 <= k <= arr.length`.
*   Reverse the sub-array `arr[0...k-1]` (**0-indexed**).

For example, if `arr = [3,2,1,4]` and we performed a pancake flip choosing `k = 3`, we reverse the sub-array `[3,2,1]`, so `arr = [1,2,3,4]` after the pancake flip at `k = 3`.

Return _an array of the_ `k`_\-values corresponding to a sequence of pancake flips that sort_ `arr`. Any valid answer that sorts the array within `10 * arr.length` flips will be judged as correct.

**Example 1:**

**Input:** arr = \[3,2,4,1\]
**Output:** \[4,2,4,3\]
**Explanation:**
We perform 4 pancake flips, with k values 4, 2, 4, and 3.
Starting state: arr = \[3, 2, 4, 1\]
After 1st flip (k = 4): arr = \[1, 4, 2, 3\]
After 2nd flip (k = 2): arr = \[4, 1, 2, 3\]
After 3rd flip (k = 4): arr = \[3, 2, 1, 4\]
After 4th flip (k = 3): arr = \[1, 2, 3, 4\], which is sorted.

**Example 2:**

**Input:** arr = \[1,2,3\]
**Output:** \[\]
**Explanation:** The input is already sorted, so there is no need to flip anything.
Note that other answers, such as \[3, 3\], would also be accepted.

**Constraints:**

*   `1 <= arr.length <= 100`
*   `1 <= arr[i] <= arr.length`
*   All integers in `arr` are unique (i.e. `arr` is a permutation of the integers from `1` to `arr.length`).

## A solution in Java

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

class RecentCounter {
    Queue<Integer> requests;

    public RecentCounter() {
        requests = new LinkedList<>();
    }

    public int ping(int t) {
        requests.add(t);
        while (requests.peek() < t - 3000) {
            requests.poll();
        }
        return requests.size();
    }
}
```
The algorithm for the RecentCounter class uses a data structure known as a Queue (in C++ and Java, `deque` is used) to store request timestamps.

The core steps of the algorithm include:
1. Initialize an empty Queue (or deque) to store request timestamps.
2. When `ping` is called process it with the timestamp `t`:
   a. Add `t` to the end of the request timestamps queue.
   b. Remove all requests from the front of the queue that have a timestamp less than `t - 3000`, because these are not considered recent requests.
3. Finally, return the length of the queue, which represents the number of recent requests within the time frame.

This algorithm efficiently processes the requests in O(1) time complexity for each request since all operations on the deque or queue take constant time, although it can be O(n) in the worst case where n is the number of ping calls, the better average case makes it a good choice.

## A solution in C++

```cpp
#include <deque>

class RecentCounter {
public:
    std::deque<int> requests;

    RecentCounter() { }

    int ping(int t) {
        requests.push_back(t);
        while (requests.front() < t - 3000) {
            requests.pop_front();
        }
        return requests.size();
    }
};
```
The algorithm for the RecentCounter class uses a data structure known as a Queue (in C++ and Java, `deque` is used) to store request timestamps.

The core steps of the algorithm include:
1. Initialize an empty Queue (or deque) to store request timestamps.
2. When `ping` is called process it with the timestamp `t`:
   a. Add `t` to the end of the request timestamps queue.
   b. Remove all requests from the front of the queue that have a timestamp less than `t - 3000`, because these are not considered recent requests.
3. Finally, return the length of the queue, which represents the number of recent requests within the time frame.

This algorithm efficiently processes the requests in O(1) time complexity for each request since all operations on the deque or queue take constant time, although it can be O(n) in the worst case where n is the number of ping calls, the better average case makes it a good choice.

## A solution in Python

```python
from collections import deque

class RecentCounter:
    def __init__(self):
        self.requests = deque()

    def ping(self, t: int) -> int:
        self.requests.append(t)
        while self.requests[0] < t - 3000:
            self.requests.popleft()
        return len(self.requests)
```
The algorithm for the RecentCounter class uses a data structure known as a Queue (in C++ and Java, `deque` is used) to store request timestamps.

The core steps of the algorithm include:
1. Initialize an empty Queue (or deque) to store request timestamps.
2. When `ping` is called process it with the timestamp `t`:
   a. Add `t` to the end of the request timestamps queue.
   b. Remove all requests from the front of the queue that have a timestamp less than `t - 3000`, because these are not considered recent requests.
3. Finally, return the length of the queue, which represents the number of recent requests within the time frame.

This algorithm efficiently processes the requests in O(1) time complexity for each request since all operations on the deque or queue take constant time, although it can be O(n) in the worst case where n is the number of ping calls, the better average case makes it a good choice.

## A solution in Javascript

```javascript
class RecentCounter {
    constructor() {
        this.requests = [];
    }

    ping(t) {
        this.requests.push(t);
        while (this.requests[0] < t - 3000) {
            this.requests.shift();
        }
        return this.requests.length;
    }
}
```
The algorithm for the RecentCounter class uses a data structure known as a Queue (in C++ and Java, `deque` is used) to store request timestamps.

The core steps of the algorithm include:
1. Initialize an empty Queue (or deque) to store request timestamps.
2. When `ping` is called process it with the timestamp `t`:
   a. Add `t` to the end of the request timestamps queue.
   b. Remove all requests from the front of the queue that have a timestamp less than `t - 3000`, because these are not considered recent requests.
3. Finally, return the length of the queue, which represents the number of recent requests within the time frame.

This algorithm efficiently processes the requests in O(1) time complexity for each request since all operations on the deque or queue take constant time, although it can be O(n) in the worst case where n is the number of ping calls, the better average case makes it a good choice.