# Find Servers That Handled Most Number of Requests

- slug: find-servers-that-handled-most-number-of-requests
- difficulty: Hard

You have `k` servers numbered from `0` to `k-1` that are being used to handle multiple requests simultaneously. Each server has infinite computational capacity but **cannot handle more than one request at a time**. The requests are assigned to servers according to a specific algorithm:

*   The `ith` (0-indexed) request arrives.
*   If all servers are busy, the request is dropped (not handled at all).
*   If the `(i % k)th` server is available, assign the request to that server.
*   Otherwise, assign the request to the next available server (wrapping around the list of servers and starting from 0 if necessary). For example, if the `ith` server is busy, try to assign the request to the `(i+1)th` server, then the `(i+2)th` server, and so on.

You are given a **strictly increasing** array `arrival` of positive integers, where `arrival[i]` represents the arrival time of the `ith` request, and another array `load`, where `load[i]` represents the load of the `ith` request (the time it takes to complete). Your goal is to find the **busiest server(s)**. A server is considered **busiest** if it handled the most number of requests successfully among all the servers.

Return _a list containing the IDs (0-indexed) of the **busiest server(s)**_. You may return the IDs in any order.

**Example 1:**

**Input:** k = 3, arrival = \[1,2,3,4,5\], load = \[5,2,3,3,3\]
**Output:** \[1\]
**Explanation:**
All of the servers start out available.
The first 3 requests are handled by the first 3 servers in order.
Request 3 comes in. Server 0 is busy, so it's assigned to the next available server, which is 1.
Request 4 comes in. It cannot be handled since all servers are busy, so it is dropped.
Servers 0 and 2 handled one request each, while server 1 handled two requests. Hence server 1 is the busiest server.

**Example 2:**

**Input:** k = 3, arrival = \[1,2,3,4\], load = \[1,2,1,2\]
**Output:** \[0\]
**Explanation:**
The first 3 requests are handled by first 3 servers.
Request 3 comes in. It is handled by server 0 since the server is available.
Server 0 handled two requests, while servers 1 and 2 handled one request each. Hence server 0 is the busiest server.

**Example 3:**

**Input:** k = 3, arrival = \[1,2,3\], load = \[10,12,11\]
**Output:** \[0,1,2\]
**Explanation:** Each server handles a single request, so they are all considered the busiest.

**Constraints:**

*   `1 <= k <= 105`
*   `1 <= arrival.length, load.length <= 105`
*   `arrival.length == load.length`
*   `1 <= arrival[i], load[i] <= 109`
*   `arrival` is **strictly increasing**.

## A solution in Java

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

public List<Integer> busiestServers(int k, int[] arrival, int[] load) {
    int[] server_status = new int[k];
    int[] server_request_count = new int[k];

    for (int i = 0; i < arrival.length; i++) {
        int index = i % k;
        for (int j = 0; j < k; j++) {
            if (server_status[index] <= arrival[i]) {
                server_status[index] = arrival[i] + load[i];
                server_request_count[index]++;
                break;
            }
            index = (index + 1) % k;
        }
    }

    int max_requests = 0;
    for (int count : server_request_count) {
        max_requests = Math.max(max_requests, count);
    }
    List<Integer> busiest_servers = new ArrayList<>();
    for (int i = 0; i < k; i++) {
        if (server_request_count[i] == max_requests) {
            busiest_servers.add(i);
        }
    }
    return busiest_servers;
}
```
The algorithm works as follows:

1. Initialize two arrays: `server_status` and `server_request_count` with lengths `k`. The `server_status` array will store the end time for the committed requests, initially set to -1 (available). The `server_request_count` array will store the number of requests processed by each server, initially set to 0.

2. For each request `i`, calculate the index `index = i % k` and check all servers `k` times (in circular manner) to find an available server.

3. If a server with an end time less than or equal to the current arrival time is found, update the server's end time with the request's end time (`arrival[i] + load[i]`) and increment the server's request count.

4. Once all requests have been processed, find the busiest server(s) by finding the maximum value in the `server_request_count` array and creating a list of indices (server IDs) that match the maximum value.

5. Return the list of busiest server IDs.

*Note: The algorithm's time complexity is O(n * k) where n is the number of requests and k is the number of servers.*

## A solution in C++

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

vector<int> busiestServers(int k, vector<int>& arrival, vector<int>& load) {
    vector<int> server_status(k, -1); // -1 means available
    vector<int> server_request_count(k, 0);

    for (int i = 0; i < arrival.size(); i++) {
        int index = i % k;
        for (int j = 0; j < k; j++) {
            if (server_status[index] <= arrival[i]) {
                server_status[index] = arrival[i] + load[i];
                server_request_count[index]++;
                break;
            }
            index = (index + 1) % k;
        }
    }

    int max_requests = *max_element(server_request_count.begin(), server_request_count.end());
    vector<int> busiest_servers;
    for (int i = 0; i < k; i++) {
        if (server_request_count[i] == max_requests) {
            busiest_servers.push_back(i);
        }
    }
    return busiest_servers;
}
```
The algorithm works as follows:

1. Initialize two arrays: `server_status` and `server_request_count` with lengths `k`. The `server_status` array will store the end time for the committed requests, initially set to -1 (available). The `server_request_count` array will store the number of requests processed by each server, initially set to 0.

2. For each request `i`, calculate the index `index = i % k` and check all servers `k` times (in circular manner) to find an available server.

3. If a server with an end time less than or equal to the current arrival time is found, update the server's end time with the request's end time (`arrival[i] + load[i]`) and increment the server's request count.

4. Once all requests have been processed, find the busiest server(s) by finding the maximum value in the `server_request_count` array and creating a list of indices (server IDs) that match the maximum value.

5. Return the list of busiest server IDs.

*Note: The algorithm's time complexity is O(n * k) where n is the number of requests and k is the number of servers.*

## A solution in Python

```python
def busiestServers(k, arrival, load):
    server_status = [-1] * k
    server_request_count = [0] * k

    for i in range(len(arrival)):
        index = i % k
        for _ in range(k):
            if server_status[index] <= arrival[i]:
                server_status[index] = arrival[i] + load[i]
                server_request_count[index] += 1
                break
            index = (index + 1) % k

    max_requests = max(server_request_count)
    return [i for i in range(k) if server_request_count[i] == max_requests]
```
The algorithm works as follows:

1. Initialize two arrays: `server_status` and `server_request_count` with lengths `k`. The `server_status` array will store the end time for the committed requests, initially set to -1 (available). The `server_request_count` array will store the number of requests processed by each server, initially set to 0.

2. For each request `i`, calculate the index `index = i % k` and check all servers `k` times (in circular manner) to find an available server.

3. If a server with an end time less than or equal to the current arrival time is found, update the server's end time with the request's end time (`arrival[i] + load[i]`) and increment the server's request count.

4. Once all requests have been processed, find the busiest server(s) by finding the maximum value in the `server_request_count` array and creating a list of indices (server IDs) that match the maximum value.

5. Return the list of busiest server IDs.

*Note: The algorithm's time complexity is O(n * k) where n is the number of requests and k is the number of servers.*

## A solution in Javascript

```javascript
function busiestServers(k, arrival, load) {
    let server_status = new Array(k).fill(-1);
    let server_request_count = new Array(k).fill(0);

    for (let i = 0; i < arrival.length; i++) {
        let index = i % k;
        for (let j = 0; j < k; j++) {
            if (server_status[index] <= arrival[i]) {
                server_status[index] = arrival[i] + load[i];
                server_request_count[index]++;
                break;
            }
            index = (index + 1) % k;
        }
    }

    let max_requests = Math.max(...server_request_count);
    let busiest_servers = [];
    for (let i = 0; i < k; i++) {
        if (server_request_count[i] === max_requests) {
            busiest_servers.push(i);
        }
    }
    return busiest_servers;
}
```
The algorithm works as follows:

1. Initialize two arrays: `server_status` and `server_request_count` with lengths `k`. The `server_status` array will store the end time for the committed requests, initially set to -1 (available). The `server_request_count` array will store the number of requests processed by each server, initially set to 0.

2. For each request `i`, calculate the index `index = i % k` and check all servers `k` times (in circular manner) to find an available server.

3. If a server with an end time less than or equal to the current arrival time is found, update the server's end time with the request's end time (`arrival[i] + load[i]`) and increment the server's request count.

4. Once all requests have been processed, find the busiest server(s) by finding the maximum value in the `server_request_count` array and creating a list of indices (server IDs) that match the maximum value.

5. Return the list of busiest server IDs.

*Note: The algorithm's time complexity is O(n * k) where n is the number of requests and k is the number of servers.*


# Special Array With X Elements Greater Than or Equal X

- slug: special-array-with-x-elements-greater-than-or-equal-x
- difficulty: Easy

You are given an array `nums` of non-negative integers. `nums` is considered **special** if there exists a number `x` such that there are **exactly** `x` numbers in `nums` that are **greater than or equal to** `x`.

Notice that `x` **does not** have to be an element in `nums`.

Return `x` _if the array is **special**, otherwise, return_ `-1`. It can be proven that if `nums` is special, the value for `x` is **unique**.

**Example 1:**

**Input:** nums = \[3,5\]
**Output:** 2
**Explanation:** There are 2 values (3 and 5) that are greater than or equal to 2.

**Example 2:**

**Input:** nums = \[0,0\]
**Output:** -1
**Explanation:** No numbers fit the criteria for x.
If x = 0, there should be 0 numbers >= x, but there are 2.
If x = 1, there should be 1 number >= x, but there are 0.
If x = 2, there should be 2 numbers >= x, but there are 0.
x cannot be greater since there are only 2 numbers in nums.

**Example 3:**

**Input:** nums = \[0,4,3,0,4\]
**Output:** 3
**Explanation:** There are 3 values that are greater than or equal to 3.

**Constraints:**

*   `1 <= nums.length <= 100`
*   `0 <= nums[i] <= 1000`

## A solution in Java

```java
public int specialArray(int[] nums) {
    int max_val = Arrays.stream(nums).max().orElse(0);
    for (int x = 1; x <= max_val; ++x) {
        int count = 0;
        for (int num : nums) {
            if (num >= x) count++;
        }
        if (count == x) return x;
    }
    return -1;
}
```
1. Find the maximum value in the input array `nums`.
2. Iterate through the range `[1, max_val]` (both inclusive) and for each value of `x`, count the elements greater than or equal to `x` in the input array.
3. If the count of such elements is equal to `x`, return `x`.
4. If no such `x` is found, return `-1`.

## A solution in C++

```cpp
int specialArray(vector<int>& nums) {
    int max_val = *max_element(nums.begin(), nums.end());
    for (int x = 1; x <= max_val; ++x) {
        int count = 0;
        for (int num : nums) {
            if (num >= x) count++;
        }
        if (count == x) return x;
    }
    return -1;
}
```
1. Find the maximum value in the input array `nums`.
2. Iterate through the range `[1, max_val]` (both inclusive) and for each value of `x`, count the elements greater than or equal to `x` in the input array.
3. If the count of such elements is equal to `x`, return `x`.
4. If no such `x` is found, return `-1`.

## A solution in Python

```python
def specialArray(nums):
    max_val = max(nums)
    for x in range(1, max_val + 1):
        count = sum([1 for num in nums if num >= x])
        if count == x:
            return x
    return -1
```
1. Find the maximum value in the input array `nums`.
2. Iterate through the range `[1, max_val]` (both inclusive) and for each value of `x`, count the elements greater than or equal to `x` in the input array.
3. If the count of such elements is equal to `x`, return `x`.
4. If no such `x` is found, return `-1`.

## A solution in Javascript

```javascript
function specialArray(nums) {
    let max_val = Math.max(...nums);
    for (let x = 1; x <= max_val; ++x) {
        let count = 0;
        for (let num of nums) {
            if (num >= x) count++;
        }
        if (count === x) return x;
    }
    return -1;
}
```
1. Find the maximum value in the input array `nums`.
2. Iterate through the range `[1, max_val]` (both inclusive) and for each value of `x`, count the elements greater than or equal to `x` in the input array.
3. If the count of such elements is equal to `x`, return `x`.
4. If no such `x` is found, return `-1`.


# Even Odd Tree

- slug: even-odd-tree
- difficulty: Medium

A binary tree is named **Even-Odd** if it meets the following conditions:

*   The root of the binary tree is at level index `0`, its children are at level index `1`, their children are at level index `2`, etc.
*   For every **even-indexed** level, all nodes at the level have **odd** integer values in **strictly increasing** order (from left to right).
*   For every **odd-indexed** level, all nodes at the level have **even** integer values in **strictly decreasing** order (from left to right).

Given the `root` of a binary tree, _return_ `true` _if the binary tree is **Even-Odd**, otherwise return_ `false`_._

**Example 1:**

**Input:** root = \[1,10,4,3,null,7,9,12,8,6,null,null,2\]
**Output:** true
**Explanation:** The node values on each level are:
Level 0: \[1\]
Level 1: \[10,4\]
Level 2: \[3,7,9\]
Level 3: \[12,8,6,2\]
Since levels 0 and 2 are all odd and increasing and levels 1 and 3 are all even and decreasing, the tree is Even-Odd.

**Example 2:**

**Input:** root = \[5,4,2,3,3,7\]
**Output:** false
**Explanation:** The node values on each level are:
Level 0: \[5\]
Level 1: \[4,2\]
Level 2: \[3,3,7\]
Node values in level 2 must be in strictly increasing order, so the tree is not Even-Odd.

**Example 3:**

**Input:** root = \[5,9,1,3,5,7\]
**Output:** false
**Explanation:** Node values in the level 1 should be even integers.

**Constraints:**

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

## A solution in Java

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

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

public boolean isEvenOddTree(TreeNode root) {
    if (root == null) return false;

    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    int level = 0;

    while (!queue.isEmpty()) {
        int size = queue.size();
        int prevVal = (level % 2 == 0) ? 0 : 1000001;

        for (int i = 0; i < size; ++i) {
            TreeNode curr = queue.poll();

            if ((level % 2 == 0 && (curr.val % 2 == 0 || curr.val <= prevVal)) ||
                (level % 2 != 0 && (curr.val % 2 != 0 || curr.val >= prevVal))) {
                return false;
            }

            prevVal = curr.val;

            if (curr.left != null) queue.offer(curr.left);
            if (curr.right != null) queue.offer(curr.right);
        }

        level++;
    }

    return true;
}
```
The algorithm starts by checking whether the tree contains any elements, i.e. the root node, and returns `false` if it does not. It then initializes a queue (deque in Python) and a `level` variable.

The queue is filled with the current level of tree nodes starting at the root node. On each level, the corresponding size of the queue is calculated. Then, for every node in the current level, we compare the node values with the previous values to see if they meet the conditions in the problem statement. If the conditions are not met, we return `false`. As we traverse the tree nodes, we add the left and right child nodes of the current node to the queue if they exist.

Finally, we increment the `level` variable for each level of nodes. If the tree is traversed without finding an improper node, we return `true`.

The time complexity is O(n), where n is the number of nodes, while the space complexity is O(n) due to the use of a queue to store nodes at each level.

## A solution in C++

```cpp
#include <queue>

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
};

bool isEvenOddTree(TreeNode* root) {
    if (!root) return false;

    queue<TreeNode*> q;
    q.push(root);
    int level = 0;

    while (!q.empty()) {
        int size = q.size();
        int prevVal = (level % 2 == 0) ? 0 : 1e6 + 1;

        for (int i = 0; i < size; ++i) {
            TreeNode* curr = q.front();
            q.pop();

            if ((level % 2 == 0 && (curr->val % 2 == 0 || curr->val <= prevVal)) ||
                (level % 2 != 0 && (curr->val % 2 != 0 || curr->val >= prevVal))) {
                return false;
            }

            prevVal = curr->val;

            if (curr->left) q.push(curr->left);
            if (curr->right) q.push(curr->right);
        }

        level++;
    }

    return true;
}
```
The algorithm starts by checking whether the tree contains any elements, i.e. the root node, and returns `false` if it does not. It then initializes a queue (deque in Python) and a `level` variable.

The queue is filled with the current level of tree nodes starting at the root node. On each level, the corresponding size of the queue is calculated. Then, for every node in the current level, we compare the node values with the previous values to see if they meet the conditions in the problem statement. If the conditions are not met, we return `false`. As we traverse the tree nodes, we add the left and right child nodes of the current node to the queue if they exist.

Finally, we increment the `level` variable for each level of nodes. If the tree is traversed without finding an improper node, we return `true`.

The time complexity is O(n), where n is the number of nodes, while the space complexity is O(n) due to the use of a queue to store nodes at each level.

## A solution in Python

```python
from collections import deque

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

def is_even_odd_tree(root):
    if not root:
        return False

    q = deque([root])
    level = 0

    while q:
        size = len(q)
        prev_val = 0 if level % 2 == 0 else 10**6 + 1

        for _ in range(size):
            curr = q.popleft()

            if ((level % 2 == 0 and (curr.val % 2 == 0 or curr.val <= prev_val)) or
                (level % 2 != 0 and (curr.val % 2 != 0 or curr.val >= prev_val))):
                return False

            prev_val = curr.val

            if curr.left:
                q.append(curr.left)
            if curr.right:
                q.append(curr.right)

        level += 1

    return True
```
The algorithm starts by checking whether the tree contains any elements, i.e. the root node, and returns `false` if it does not. It then initializes a queue (deque in Python) and a `level` variable.

The queue is filled with the current level of tree nodes starting at the root node. On each level, the corresponding size of the queue is calculated. Then, for every node in the current level, we compare the node values with the previous values to see if they meet the conditions in the problem statement. If the conditions are not met, we return `false`. As we traverse the tree nodes, we add the left and right child nodes of the current node to the queue if they exist.

Finally, we increment the `level` variable for each level of nodes. If the tree is traversed without finding an improper node, we return `true`.

The time complexity is O(n), where n is the number of nodes, while the space complexity is O(n) due to the use of a queue to store nodes at each level.

## A solution in Javascript

```javascript
function TreeNode(val, left, right) {
    this.val = (val === undefined ? 0 : val);
    this.left = (left === undefined ? null : left);
    this.right = (right === undefined ? null : right);
}

function isEvenOddTree(root) {
    if (!root) return false;

    const q = [root];
    let level = 0;

    while (q.length > 0) {
        const size = q.length;
        let prevVal = (level % 2 === 0) ? 0 : 1000001;

        for (let i = 0; i < size; ++i) {
            const curr = q.shift();

            if ((level % 2 === 0 && (curr.val % 2 === 0 || curr.val <= prevVal)) ||
                (level % 2 !== 0 && (curr.val % 2 !== 0 || curr.val >= prevVal))) {
                return false;
            }

            prevVal = curr.val;

            if (curr.left !== null) q.push(curr.left);
            if (curr.right !== null) q.push(curr.right);
        }

        level++;
    }

    return true;
}
```
The algorithm starts by checking whether the tree contains any elements, i.e. the root node, and returns `false` if it does not. It then initializes a queue (deque in Python) and a `level` variable.

The queue is filled with the current level of tree nodes starting at the root node. On each level, the corresponding size of the queue is calculated. Then, for every node in the current level, we compare the node values with the previous values to see if they meet the conditions in the problem statement. If the conditions are not met, we return `false`. As we traverse the tree nodes, we add the left and right child nodes of the current node to the queue if they exist.

Finally, we increment the `level` variable for each level of nodes. If the tree is traversed without finding an improper node, we return `true`.

The time complexity is O(n), where n is the number of nodes, while the space complexity is O(n) due to the use of a queue to store nodes at each level.


# Maximum Number of Visible Points

- slug: maximum-number-of-visible-points
- difficulty: Hard

You are given an array `points`, an integer `angle`, and your `location`, where `location = [posx, posy]` and `points[i] = [xi, yi]` both denote **integral coordinates** on the X-Y plane.

Initially, you are facing directly east from your position. You **cannot move** from your position, but you can **rotate**. In other words, `posx` and `posy` cannot be changed. Your field of view in **degrees** is represented by `angle`, determining how wide you can see from any given view direction. Let `d` be the amount in degrees that you rotate counterclockwise. Then, your field of view is the **inclusive** range of angles `[d - angle/2, d + angle/2]`.

Your browser does not support the video tag or this video format.

You can **see** some set of points if, for each point, the **angle** formed by the point, your position, and the immediate east direction from your position is **in your field of view**.

There can be multiple points at one coordinate. There may be points at your location, and you can always see these points regardless of your rotation. Points do not obstruct your vision to other points.

Return _the maximum number of points you can see_.

**Example 1:**

**Input:** points = \[\[2,1\],\[2,2\],\[3,3\]\], angle = 90, location = \[1,1\]
**Output:** 3
**Explanation:** The shaded region represents your field of view. All points can be made visible in your field of view, including \[3,3\] even though \[2,2\] is in front and in the same line of sight.

**Example 2:**

**Input:** points = \[\[2,1\],\[2,2\],\[3,4\],\[1,1\]\], angle = 90, location = \[1,1\]
**Output:** 4
**Explanation:** All points can be made visible in your field of view, including the one at your location.

**Example 3:**

**Input:** points = \[\[1,0\],\[2,1\]\], angle = 13, location = \[1,1\]
**Output:** 1
**Explanation:** You can only see one of the two points, as shown above.

**Constraints:**

*   `1 <= points.length <= 105`
*   `points[i].length == 2`
*   `location.length == 2`
*   `0 <= angle < 360`
*   `0 <= posx, posy, xi, yi <= 100`

## A solution in Java

```java
public int xorOperation(int n, int start) {
    int xorResult = 0;
    for (int i = 0; i < n; i++) {
        xorResult ^= (start + 2 * i);
    }
    return xorResult;
}
```
1. Initialize an integer variable `xor_result` to store the result of bitwise XOR operations and set it to 0.
2. Iterate through the range of 0 to n (excluding n).
3. For each iteration, calculate the value of `start + 2 * i` with the current value of `i`. Perform a bitwise XOR operation between the `xor_result` and the calculated value.
4. After the iteration, return the final value of `xor_result` which contains the result of bitwise XOR of all elements of the `nums` array.

## A solution in C++

```cpp
int xorOperation(int n, int start) {
    int xor_result = 0;
    for (int i = 0; i < n; ++i) {
        xor_result ^= (start + 2 * i);
    }
    return xor_result;
}
```
1. Initialize an integer variable `xor_result` to store the result of bitwise XOR operations and set it to 0.
2. Iterate through the range of 0 to n (excluding n).
3. For each iteration, calculate the value of `start + 2 * i` with the current value of `i`. Perform a bitwise XOR operation between the `xor_result` and the calculated value.
4. After the iteration, return the final value of `xor_result` which contains the result of bitwise XOR of all elements of the `nums` array.

## A solution in Python

```python
def xor_operation(n, start):
    xor_result = 0
    for i in range(n):
        xor_result ^= (start + 2 * i)
    return xor_result
```
1. Initialize an integer variable `xor_result` to store the result of bitwise XOR operations and set it to 0.
2. Iterate through the range of 0 to n (excluding n).
3. For each iteration, calculate the value of `start + 2 * i` with the current value of `i`. Perform a bitwise XOR operation between the `xor_result` and the calculated value.
4. After the iteration, return the final value of `xor_result` which contains the result of bitwise XOR of all elements of the `nums` array.

## A solution in Javascript

```javascript
function xorOperation(n, start) {
    let xorResult = 0;
    for (let i = 0; i < n; i++) {
        xorResult ^= (start + 2 * i);
    }
    return xorResult;
}
```
1. Initialize an integer variable `xor_result` to store the result of bitwise XOR operations and set it to 0.
2. Iterate through the range of 0 to n (excluding n).
3. For each iteration, calculate the value of `start + 2 * i` with the current value of `i`. Perform a bitwise XOR operation between the `xor_result` and the calculated value.
4. After the iteration, return the final value of `xor_result` which contains the result of bitwise XOR of all elements of the `nums` array.


# Minimum One Bit Operations to Make Integers Zero

- slug: minimum-one-bit-operations-to-make-integers-zero
- difficulty: Hard

Given an integer `n`, you must transform it into `0` using the following operations any number of times:

*   Change the rightmost (`0th`) bit in the binary representation of `n`.
*   Change the `ith` bit in the binary representation of `n` if the `(i-1)th` bit is set to `1` and the `(i-2)th` through `0th` bits are set to `0`.

Return _the minimum number of operations to transform_ `n` _into_ `0`_._

**Example 1:**

**Input:** n = 3
**Output:** 2
**Explanation:** The binary representation of 3 is  "11 ".
 "11 " ->  "01 " with the 2nd operation since the 0th bit is 1.
 "01 " ->  "00 " with the 1st operation.

**Example 2:**

**Input:** n = 6
**Output:** 4
**Explanation:** The binary representation of 6 is  "110 ".
 "110 " ->  "010 " with the 2nd operation since the 1st bit is 1 and 0th through 0th bits are 0.
 "010 " ->  "011 " with the 1st operation.
 "011 " ->  "001 " with the 2nd operation since the 0th bit is 1.
 "001 " ->  "000 " with the 1st operation.

**Constraints:**

*   `0 <= n <= 109`

## A solution in Java

```java
import java.util.*;

public String[] getFolderNames(String[] names) {
    HashMap<String, Integer> nameCount = new HashMap<String, Integer>();
    String[] ans = new String[names.length];

    for (int i = 0; i < names.length; i++) {
        String name = names[i];
        if (nameCount.get(name) == null) {
            ans[i] = name;
            nameCount.put(name, 1);
        } else {
            int k = nameCount.get(name);
            String newName = "";
            while (nameCount.get(name + "(" + k + ")") != null) {
                k++;
            }
            newName = name + "(" + k + ")";
            ans[i] = newName;
            nameCount.put(newName, 1);
            nameCount.put(name, k + 1);
        }
    }

    return ans;
}
```
The algorithm holds an unordered_map (hash_map in Java, dictionary in Python, object in JS) named `nameCount` that stores the count of each name used. For each name in the `names` array, it checks if the name exists in `nameCount`. If not, it puts the name in the resulting array `ans` and initializes its count in `nameCount` by 1. If the name is already in `nameCount`, the algorithm creates a candidate name by adding the current count value in the form of (k), then checks if this name is also in the `nameCount`. If so, it increases the count (k) until finding a unique name. The new name is added to the result array, and its count value is set to 1 in `nameCount`, and the count value in (k+1) is updated. Finally, the function returns the `ans` array containing the unique folder names.

## A solution in C++

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

std::vector<std::string> getFolderNames(std::vector<std::string> &names) {
    std::unordered_map<std::string, int> nameCount;
    std::vector<std::string> ans;

    for (const auto &name : names) {
        if (nameCount[name] == 0) {
            ans.push_back(name);
            nameCount[name] = 1;
        } else {
            int k = nameCount[name];
            while (nameCount[name + "(" + std::to_string(k) + ")"] != 0) {
                k++;
            }
            ans.push_back(name + "(" + std::to_string(k) + ")");
            nameCount[name + "(" + std::to_string(k) + ")"] = 1;
            nameCount[name] = k + 1;
        }
    }

    return ans;
}
```
The algorithm holds an unordered_map (hash_map in Java, dictionary in Python, object in JS) named `nameCount` that stores the count of each name used. For each name in the `names` array, it checks if the name exists in `nameCount`. If not, it puts the name in the resulting array `ans` and initializes its count in `nameCount` by 1. If the name is already in `nameCount`, the algorithm creates a candidate name by adding the current count value in the form of (k), then checks if this name is also in the `nameCount`. If so, it increases the count (k) until finding a unique name. The new name is added to the result array, and its count value is set to 1 in `nameCount`, and the count value in (k+1) is updated. Finally, the function returns the `ans` array containing the unique folder names.

## A solution in Python

```python
def get_folder_names(names):
    name_count = {}
    ans = []

    for name in names:
        if name not in name_count:
            ans.append(name)
            name_count[name] = 1
        else:
            k = name_count[name]
            new_name = f"{name}({k})"
            while new_name in name_count:
                k += 1
                new_name = f"{name}({k})"
            ans.append(new_name)
            name_count[new_name] = 1
            name_count[name] = k + 1

    return ans
```
The algorithm holds an unordered_map (hash_map in Java, dictionary in Python, object in JS) named `nameCount` that stores the count of each name used. For each name in the `names` array, it checks if the name exists in `nameCount`. If not, it puts the name in the resulting array `ans` and initializes its count in `nameCount` by 1. If the name is already in `nameCount`, the algorithm creates a candidate name by adding the current count value in the form of (k), then checks if this name is also in the `nameCount`. If so, it increases the count (k) until finding a unique name. The new name is added to the result array, and its count value is set to 1 in `nameCount`, and the count value in (k+1) is updated. Finally, the function returns the `ans` array containing the unique folder names.

## A solution in Javascript

```javascript
function getFolderNames(names) {
    const nameCount = {};
    const ans = [];

    for (let name of names) {
        if (nameCount[name] === undefined) {
            ans.push(name);
            nameCount[name] = 1;
        } else {
            let k = nameCount[name];
            let newName = `${name}(${k})`;
            while (nameCount[newName] !== undefined) {
                k++;
                newName = `${name}(${k})`;
            }
            ans.push(newName);
            nameCount[newName] = 1;
            nameCount[name] = k + 1;
        }
    }

    return ans;
}
```
The algorithm holds an unordered_map (hash_map in Java, dictionary in Python, object in JS) named `nameCount` that stores the count of each name used. For each name in the `names` array, it checks if the name exists in `nameCount`. If not, it puts the name in the resulting array `ans` and initializes its count in `nameCount` by 1. If the name is already in `nameCount`, the algorithm creates a candidate name by adding the current count value in the form of (k), then checks if this name is also in the `nameCount`. If so, it increases the count (k) until finding a unique name. The new name is added to the result array, and its count value is set to 1 in `nameCount`, and the count value in (k+1) is updated. Finally, the function returns the `ans` array containing the unique folder names.


# Check If Two Expression Trees are Equivalent

- slug: check-if-two-expression-trees-are-equivalent
- difficulty: Medium

A **[binary expression tree](https://en.wikipedia.org/wiki/Binary_expression_tree)** is a kind of binary tree used to represent arithmetic expressions. Each node of a binary expression tree has either zero or two children. Leaf nodes (nodes with 0 children) correspond to operands (variables), and internal nodes (nodes with two children) correspond to the operators. In this problem, we only consider the `'+'` operator (i.e. addition).

You are given the roots of two binary expression trees, `root1` and `root2`. Return `true` _if the two binary expression trees are equivalent_. Otherwise, return `false`.

Two binary expression trees are equivalent if they **evaluate to the same value** regardless of what the variables are set to.

**Example 1:**

**Input:** root1 = \[x\], root2 = \[x\]
**Output:** true

**Example 2:**

**Input:** root1 = \[+,a,+,null,null,b,c\], root2 = \[+,+,a,b,c\]
**Output:** true
**Explaination:** `a + (b + c) == (b + c) + a`

**Example 3:**

**Input:** root1 = \[+,a,+,null,null,b,c\], root2 = \[+,+,a,b,d\]
**Output:** false
**Explaination:** `a + (b + c) != (b + d) + a`

**Constraints:**

*   The number of nodes in both trees are equal, odd and, in the range `[1, 4999]`.
*   `Node.val` is `'+'` or a lower-case English letter.
*   It's **guaranteed** that the tree given is a valid binary expression tree.

**Follow up:** What will you change in your solution if the tree also supports the `'-'` operator (i.e. subtraction)?

## A solution in Java

```java
import java.util.*;

class Solution {
    public int[] avoidFlood(int[] rains) {
        int[] res = new int[rains.length];
        Arrays.fill(res, -1);
        Map<Integer, Integer> filledLakes = new HashMap<>();
        TreeSet<Integer> dryDays = new TreeSet<>();

        for (int i = 0; i < rains.length; i++) {
            if (rains[i] == 0) {
                dryDays.add(i);
            } else {
                int lake = rains[i];
                if (filledLakes.containsKey(lake)) {
                    Integer day = dryDays.ceiling(filledLakes.get(lake));
                    if (day == null) return new int[0];
                    res[day] = lake;
                    dryDays.remove(day);
                }
                filledLakes.put(lake, i);
            }
        }

        for (int day : dryDays) {
            res[day] = 1;
        }

        return res;
    }
}
```
1. Initialize a result array with the same length as rains, filled with -1. Create a map for filled lakes and a set for dry days.
2. Loop through rains array:
   - If the rain amount is 0, add the current day to dry days set.
   - Otherwise, check if the lake is already filled:
     - If it is, find a dry day after the lake was filled last time. If no valid dry day is found, return an empty array.
     - Update the result array with the current lake number on the found dry day, then remove this day from the dry days set.
   - Update the filled lakes map with the current day.
3. Loop through the remaining dry days and set the result array with 1 on those days.
4. Return the result array.

## A solution in C++

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

std::vector<int> avoidFlood(std::vector<int>& rains) {
    std::vector<int> res(rains.size(), -1);
    std::unordered_map<int, int> filled_lakes;
    std::set<int> dry_days;

    for (int i = 0; i < rains.size(); ++i) {
        if (rains[i] == 0) {
            dry_days.insert(i);
        } else {
            int lake = rains[i];
            if (filled_lakes.count(lake)) {
                auto it = dry_days.lower_bound(filled_lakes[lake]);
                if (it == dry_days.end()) return {};
                res[*it] = lake;
                dry_days.erase(it);
            }
            filled_lakes[lake] = i;
        }
    }

    for (int day : dry_days) {
        res[day] = 1;
    }

    return res;
}
```
1. Initialize a result array with the same length as rains, filled with -1. Create a map for filled lakes and a set for dry days.
2. Loop through rains array:
   - If the rain amount is 0, add the current day to dry days set.
   - Otherwise, check if the lake is already filled:
     - If it is, find a dry day after the lake was filled last time. If no valid dry day is found, return an empty array.
     - Update the result array with the current lake number on the found dry day, then remove this day from the dry days set.
   - Update the filled lakes map with the current day.
3. Loop through the remaining dry days and set the result array with 1 on those days.
4. Return the result array.

## A solution in Python

```python
from sortedcontainers import SortedSet

def avoidFlood(rains: List[int]) -> List[int]:
    res = [-1] * len(rains)
    filled_lakes = {}
    dry_days = SortedSet()

    for i, lake in enumerate(rains):
        if lake == 0:
            dry_days.add(i)
        else:
            if lake in filled_lakes:
                day = dry_days.ceiling(filled_lakes[lake])
                if day is None:
                    return []
                res[day] = lake
                dry_days.remove(day)
            filled_lakes[lake] = i

    for day in dry_days:
        res[day] = 1

    return res
```
1. Initialize a result array with the same length as rains, filled with -1. Create a map for filled lakes and a set for dry days.
2. Loop through rains array:
   - If the rain amount is 0, add the current day to dry days set.
   - Otherwise, check if the lake is already filled:
     - If it is, find a dry day after the lake was filled last time. If no valid dry day is found, return an empty array.
     - Update the result array with the current lake number on the found dry day, then remove this day from the dry days set.
   - Update the filled lakes map with the current day.
3. Loop through the remaining dry days and set the result array with 1 on those days.
4. Return the result array.

## A solution in Javascript

```javascript
function avoidFlood(rains) {
    const res = new Array(rains.length).fill(-1);
    const filledLakes = new Map();
    const dryDays = new Set();

    for (let i = 0; i < rains.length; i++) {
        if (rains[i] === 0) {
            dryDays.add(i);
        } else {
            const lake = rains[i];
            if (filledLakes.has(lake)) {
                const day = [...dryDays].find(d => d > filledLakes.get(lake));
                if (day === undefined) return [];
                res[day] = lake;
                dryDays.delete(day);
            }
            filledLakes.set(lake, i);
        }
    }

    for (const day of dryDays) {
        res[day] = 1;
    }

    return res;
}
```
1. Initialize a result array with the same length as rains, filled with -1. Create a map for filled lakes and a set for dry days.
2. Loop through rains array:
   - If the rain amount is 0, add the current day to dry days set.
   - Otherwise, check if the lake is already filled:
     - If it is, find a dry day after the lake was filled last time. If no valid dry day is found, return an empty array.
     - Update the result array with the current lake number on the found dry day, then remove this day from the dry days set.
   - Update the filled lakes map with the current day.
3. Loop through the remaining dry days and set the result array with 1 on those days.
4. Return the result array.


# Maximum Nesting Depth of the Parentheses

- slug: maximum-nesting-depth-of-the-parentheses
- difficulty: Easy

A string is a **valid parentheses string** (denoted **VPS**) if it meets one of the following:

*   It is an empty string `" "`, or a single character not equal to `"( "` or `") "`,
*   It can be written as `AB` (`A` concatenated with `B`), where `A` and `B` are **VPS**'s, or
*   It can be written as `(A)`, where `A` is a **VPS**.

We can similarly define the **nesting depth** `depth(S)` of any VPS `S` as follows:

*   `depth( " ") = 0`
*   `depth(C) = 0`, where `C` is a string with a single character not equal to `"( "` or `") "`.
*   `depth(A + B) = max(depth(A), depth(B))`, where `A` and `B` are **VPS**'s.
*   `depth( "( " + A + ") ") = 1 + depth(A)`, where `A` is a **VPS**.

For example, `" "`, `"()() "`, and `"()(()()) "` are **VPS**'s (with nesting depths 0, 1, and 2), and `")( "` and `"(() "` are not **VPS**'s.

Given a **VPS** represented as string `s`, return _the **nesting depth** of_ `s`.

**Example 1:**

**Input:** s =  "(1+(2\*3)+((8)/4))+1 "
**Output:** 3
**Explanation:** Digit 8 is inside of 3 nested parentheses in the string.

**Example 2:**

**Input:** s =  "(1)+((2))+(((3))) "
**Output:** 3

**Constraints:**

*   `1 <= s.length <= 100`
*   `s` consists of digits `0-9` and characters `'+'`, `'-'`, `'*'`, `'/'`, `'('`, and `')'`.
*   It is guaranteed that parentheses expression `s` is a **VPS**.

## A solution in Java

```java
public int maxDepth(String s) {
    int depth = 0, maxDepth = 0;

    for (char c : s.toCharArray()) {
        if (c == '(') {
            depth++;
            maxDepth = Math.max(depth, maxDepth);
        } else if (c == ')') {
            depth--;
        }
    }

    return maxDepth;
}
```
Iterate through the string `s`. When an opening parenthesis '(' is encountered, increment the `depth` value, update the `max_depth` with the maximum between the current `max_depth` and the `depth`. In contrast, when a closing parenthesis ')' is encountered, decrement the `depth`. The `max_depth` will be the nesting depth of the given valid parentheses string.

## A solution in C++

```cpp
int maxDepth(std::string s) {
    int depth = 0, max_depth = 0;

    for (char c : s) {
        if (c == '(') {
            depth++;
            max_depth = std::max(depth, max_depth);
        } else if (c == ')') {
            depth--;
        }
    }

    return max_depth;
}
```
Iterate through the string `s`. When an opening parenthesis '(' is encountered, increment the `depth` value, update the `max_depth` with the maximum between the current `max_depth` and the `depth`. In contrast, when a closing parenthesis ')' is encountered, decrement the `depth`. The `max_depth` will be the nesting depth of the given valid parentheses string.

## A solution in Python

```python
def maxDepth(s: str) -> int:
    depth = 0
    max_depth = 0

    for c in s:
        if c == '(':
            depth += 1
            max_depth = max(depth, max_depth)
        elif c == ')':
            depth -= 1

    return max_depth
```
Iterate through the string `s`. When an opening parenthesis '(' is encountered, increment the `depth` value, update the `max_depth` with the maximum between the current `max_depth` and the `depth`. In contrast, when a closing parenthesis ')' is encountered, decrement the `depth`. The `max_depth` will be the nesting depth of the given valid parentheses string.

## A solution in Javascript

```javascript
function maxDepth(s) {
    let depth = 0, maxDepth = 0;

    for (const c of s) {
        if (c === '(') {
            depth++;
            maxDepth = Math.max(depth, maxDepth);
        } else if (c === ')') {
            depth--;
        }
    }

    return maxDepth;
}
```
Iterate through the string `s`. When an opening parenthesis '(' is encountered, increment the `depth` value, update the `max_depth` with the maximum between the current `max_depth` and the `depth`. In contrast, when a closing parenthesis ')' is encountered, decrement the `depth`. The `max_depth` will be the nesting depth of the given valid parentheses string.


# Maximal Network Rank

- slug: maximal-network-rank
- difficulty: Medium

There is an infrastructure of `n` cities with some number of `roads` connecting these cities. Each `roads[i] = [ai, bi]` indicates that there is a bidirectional road between cities `ai` and `bi`.

The **network rank** of **two different cities** is defined as the total number of **directly** connected roads to **either** city. If a road is directly connected to both cities, it is only counted **once**.

The **maximal network rank** of the infrastructure is the **maximum network rank** of all pairs of different cities.

Given the integer `n` and the array `roads`, return _the **maximal network rank** of the entire infrastructure_.

**Example 1:**

**Input:** n = 4, roads = \[\[0,1\],\[0,3\],\[1,2\],\[1,3\]\]
**Output:** 4
**Explanation:** The network rank of cities 0 and 1 is 4 as there are 4 roads that are connected to either 0 or 1. The road between 0 and 1 is only counted once.

**Example 2:**

**Input:** n = 5, roads = \[\[0,1\],\[0,3\],\[1,2\],\[1,3\],\[2,3\],\[2,4\]\]
**Output:** 5
**Explanation:** There are 5 roads that are connected to cities 1 or 2.

**Example 3:**

**Input:** n = 8, roads = \[\[0,1\],\[1,2\],\[2,3\],\[2,4\],\[5,6\],\[5,7\]\]
**Output:** 5
**Explanation:** The network rank of 2 and 5 is 5. Notice that all the cities do not have to be connected.

**Constraints:**

*   `2 <= n <= 100`
*   `0 <= roads.length <= n * (n - 1) / 2`
*   `roads[i].length == 2`
*   `0 <= ai, bi <= n-1`
*   `ai != bi`
*   Each pair of cities has **at most one** road connecting them.

## A solution in Java

```java
public int rangeSum(int[] nums, int n, int left, int right) {
    int MOD = (int)1e9 + 7;
    int[] sums = new int[n * (n + 1) / 2];
    int index = 0;
    for (int i = 0; i < n; ++i) {
        int sum = 0;
        for (int j = i; j < n; ++j) {
            sum += nums[j];
            sums[index++] = sum;
        }
    }
    Arrays.sort(sums);
    int result = 0;
    for (int i = left - 1; i < right; ++i) {
        result = (result + sums[i]) % MOD;
    }
    return result;
}
```
The algorithm implemented for this problem does the following:

1. Create a variable `MOD` holding the value 1e9 + 7;
2. Create a vector, array or list called `sums` which will store the sum of all non-empty continuous subarrays;
3. Iterate through `nums`, and for each position `i`, create another loop from `i` to `n - 1`, adding the elements to create the sum of the current subarray and appending or inserting it into `sums`.
4. Sort `sums` in non-decreasing order using `sort()` or `Arrays.sort()`. For Python and Javascript, you might need to implement a compare function;
5. Iterate through `sums` from index `left - 1` to `right - 1`, accumulating the desired subarray sums in variable `result`. Make sure to apply the modulo operation to the result in each addition;
6. Return the result.

## A solution in C++

```cpp
int rangeSum(vector<int>& nums, int n, int left, int right) {
    const int MOD = 1e9 + 7;
    vector<int> sums(n * (n + 1) / 2);
    int index = 0;
    for (int i = 0; i < n; ++i) {
        int sum = 0;
        for (int j = i; j < n; ++j) {
            sum += nums[j];
            sums[index++] = sum;
        }
    }
    sort(sums.begin(), sums.end());
    int result = 0;
    for (int i = left - 1; i < right; ++i) {
        result = (result + sums[i]) % MOD;
    }
    return result;
}
```
The algorithm implemented for this problem does the following:

1. Create a variable `MOD` holding the value 1e9 + 7;
2. Create a vector, array or list called `sums` which will store the sum of all non-empty continuous subarrays;
3. Iterate through `nums`, and for each position `i`, create another loop from `i` to `n - 1`, adding the elements to create the sum of the current subarray and appending or inserting it into `sums`.
4. Sort `sums` in non-decreasing order using `sort()` or `Arrays.sort()`. For Python and Javascript, you might need to implement a compare function;
5. Iterate through `sums` from index `left - 1` to `right - 1`, accumulating the desired subarray sums in variable `result`. Make sure to apply the modulo operation to the result in each addition;
6. Return the result.

## A solution in Python

```python
def range_sum(nums, n, left, right):
    MOD = 10**9 + 7
    sums = []
    for i in range(n):
        sum = 0
        for j in range(i, n):
            sum += nums[j]
            sums.append(sum)
    sums.sort()
    result = 0
    for i in range(left-1, right):
        result = (result + sums[i]) % MOD
    return result
```
The algorithm implemented for this problem does the following:

1. Create a variable `MOD` holding the value 1e9 + 7;
2. Create a vector, array or list called `sums` which will store the sum of all non-empty continuous subarrays;
3. Iterate through `nums`, and for each position `i`, create another loop from `i` to `n - 1`, adding the elements to create the sum of the current subarray and appending or inserting it into `sums`.
4. Sort `sums` in non-decreasing order using `sort()` or `Arrays.sort()`. For Python and Javascript, you might need to implement a compare function;
5. Iterate through `sums` from index `left - 1` to `right - 1`, accumulating the desired subarray sums in variable `result`. Make sure to apply the modulo operation to the result in each addition;
6. Return the result.

## A solution in Javascript

```javascript
function rangeSum(nums, n, left, right) {
    const MOD = 10**9 + 7;
    let sums = [];
    for (let i = 0; i < n; ++i) {
        let sum = 0;
        for (let j = i; j < n; ++j) {
            sum += nums[j];
            sums.push(sum);
        }
    }
    sums.sort((a, b) => a - b);
    let result = 0;
    for (let i = left - 1; i < right; ++i) {
        result = (result + sums[i]) % MOD;
    }
    return result;
}
```
The algorithm implemented for this problem does the following:

1. Create a variable `MOD` holding the value 1e9 + 7;
2. Create a vector, array or list called `sums` which will store the sum of all non-empty continuous subarrays;
3. Iterate through `nums`, and for each position `i`, create another loop from `i` to `n - 1`, adding the elements to create the sum of the current subarray and appending or inserting it into `sums`.
4. Sort `sums` in non-decreasing order using `sort()` or `Arrays.sort()`. For Python and Javascript, you might need to implement a compare function;
5. Iterate through `sums` from index `left - 1` to `right - 1`, accumulating the desired subarray sums in variable `result`. Make sure to apply the modulo operation to the result in each addition;
6. Return the result.


# Split Two Strings to Make Palindrome

- slug: split-two-strings-to-make-palindrome
- difficulty: Medium

You are given two strings `a` and `b` of the same length. Choose an index and split both strings **at the same index**, splitting `a` into two strings: `aprefix` and `asuffix` where `a = aprefix + asuffix`, and splitting `b` into two strings: `bprefix` and `bsuffix` where `b = bprefix + bsuffix`. Check if `aprefix + bsuffix` or `bprefix + asuffix` forms a palindrome.

When you split a string `s` into `sprefix` and `ssuffix`, either `ssuffix` or `sprefix` is allowed to be empty. For example, if `s = "abc "`, then `" " + "abc "`, `"a " + "bc "`, `"ab " + "c "` , and `"abc " + " "` are valid splits.

Return `true` _if it is possible to form_ _a palindrome string, otherwise return_ `false`.

**Notice** that `x + y` denotes the concatenation of strings `x` and `y`.

**Example 1:**

**Input:** a =  "x ", b =  "y "
**Output:** true
**Explaination:** If either a or b are palindromes the answer is true since you can split in the following way:
aprefix =  " ", asuffix =  "x "
bprefix =  " ", bsuffix =  "y "
Then, aprefix + bsuffix =  " " +  "y " =  "y ", which is a palindrome.

**Example 2:**

**Input:** a =  "xbdef ", b =  "xecab "
**Output:** false

**Example 3:**

**Input:** a =  "ulacfd ", b =  "jizalu "
**Output:** true
**Explaination:** Split them at index 3:
aprefix =  "ula ", asuffix =  "cfd "
bprefix =  "jiz ", bsuffix =  "alu "
Then, aprefix + bsuffix =  "ula " +  "alu " =  "ulaalu ", which is a palindrome.

**Constraints:**

*   `1 <= a.length, b.length <= 105`
*   `a.length == b.length`
*   `a` and `b` consist of lowercase English letters

## A solution in Java

```java
import java.util.Arrays;

public int minDifference(int[] nums) {
    int size = nums.length;
    if (size < 5) return 0;

    Arrays.sort(nums);

    return Math.min(Math.min(nums[size-1] - nums[3], nums[size-2] - nums[2]), Math.min(nums[size-3] - nums[1], nums[size-4] - nums[0]));
}
```
1. First, we check if the array size is less than 5. If yes, we can make all elements equal in at most 3 moves, so the minimum difference will be 0.
2. Sort the given array.
3. We need to change at most 3 smallest or largest elements. We have four combinations of this. We could change:
    - 3 largest elements (1 smallest)
    - 2 largest elements and 1 smallest element (2 smallest)
    - 1 largest element and 2 smallest elements (3 smallest)
    - 3 smallest elements (4 smallest)
4. Calculate the difference for all four combinations and return the minimum difference.

## A solution in C++

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

int min_difference(std::vector<int>& nums) {
    int size = nums.size();
    if (size < 5) return 0;

    std::sort(nums.begin(), nums.end());

    return std::min({nums[size-1] - nums[3], nums[size-2] - nums[2], nums[size-3] - nums[1], nums[size-4] - nums[0]});
}
```
1. First, we check if the array size is less than 5. If yes, we can make all elements equal in at most 3 moves, so the minimum difference will be 0.
2. Sort the given array.
3. We need to change at most 3 smallest or largest elements. We have four combinations of this. We could change:
    - 3 largest elements (1 smallest)
    - 2 largest elements and 1 smallest element (2 smallest)
    - 1 largest element and 2 smallest elements (3 smallest)
    - 3 smallest elements (4 smallest)
4. Calculate the difference for all four combinations and return the minimum difference.

## A solution in Python

```python
def min_difference(nums):
    size = len(nums)
    if size < 5:
        return 0

    nums.sort()

    return min(nums[-1] - nums[3], nums[-2] - nums[2], nums[-3] - nums[1], nums[-4] - nums[0])
```
1. First, we check if the array size is less than 5. If yes, we can make all elements equal in at most 3 moves, so the minimum difference will be 0.
2. Sort the given array.
3. We need to change at most 3 smallest or largest elements. We have four combinations of this. We could change:
    - 3 largest elements (1 smallest)
    - 2 largest elements and 1 smallest element (2 smallest)
    - 1 largest element and 2 smallest elements (3 smallest)
    - 3 smallest elements (4 smallest)
4. Calculate the difference for all four combinations and return the minimum difference.

## A solution in Javascript

```javascript
function minDifference(nums) {
    let size = nums.length;
    if (size < 5) return 0;

    nums.sort((a, b) => a - b);

    return Math.min(nums[size-1] - nums[3], nums[size-2] - nums[2], nums[size-3] - nums[1], nums[size-4] - nums[0]);
}
```
1. First, we check if the array size is less than 5. If yes, we can make all elements equal in at most 3 moves, so the minimum difference will be 0.
2. Sort the given array.
3. We need to change at most 3 smallest or largest elements. We have four combinations of this. We could change:
    - 3 largest elements (1 smallest)
    - 2 largest elements and 1 smallest element (2 smallest)
    - 1 largest element and 2 smallest elements (3 smallest)
    - 3 smallest elements (4 smallest)
4. Calculate the difference for all four combinations and return the minimum difference.


# Count Subtrees With Max Distance Between Cities

- slug: count-subtrees-with-max-distance-between-cities
- difficulty: Hard

There are `n` cities numbered from `1` to `n`. You are given an array `edges` of size `n-1`, where `edges[i] = [ui, vi]` represents a bidirectional edge between cities `ui` and `vi`. There exists a unique path between each pair of cities. In other words, the cities form a **tree**.

A **subtree** is a subset of cities where every city is reachable from every other city in the subset, where the path between each pair passes through only the cities from the subset. Two subtrees are different if there is a city in one subtree that is not present in the other.

For each `d` from `1` to `n-1`, find the number of subtrees in which the **maximum distance** between any two cities in the subtree is equal to `d`.

Return _an array of size_ `n-1` _where the_ `dth` _element **(1-indexed)** is the number of subtrees in which the **maximum distance** between any two cities is equal to_ `d`.

**Notice** that the **distance** between the two cities is the number of edges in the path between them.

**Example 1:**

**Input:** n = 4, edges = \[\[1,2\],\[2,3\],\[2,4\]\]
**Output:** \[3,4,0\]
**Explanation:**
The subtrees with subsets {1,2}, {2,3} and {2,4} have a max distance of 1.
The subtrees with subsets {1,2,3}, {1,2,4}, {2,3,4} and {1,2,3,4} have a max distance of 2.
No subtree has two nodes where the max distance between them is 3.

**Example 2:**

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

**Example 3:**

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

**Constraints:**

*   `2 <= n <= 15`
*   `edges.length == n-1`
*   `edges[i].length == 2`
*   `1 <= ui, vi <= n`
*   All pairs `(ui, vi)` are distinct.

## A solution in Java

```java
public boolean winnerSquareGame(int n) {
    boolean[] dp = new boolean[n + 1];
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j * j <= i; j++) {
            if (!dp[i - j * j]) {
                dp[i] = true;
                break;
            }
        }
    }
    return dp[n];
}
```
We use dynamic programming to solve this problem. We create a boolean array `dp` of size `(n + 1)` to store if the current player can win with the remaining stones at position `i`. Each entry `dp[i]` is set to `false` initially.

We iterate through all possible numbers of stones from `1` to `n`. For each stone `i`, we iterate through all possible square numbers `j` less than or equal to `i`. Inside the inner loop, we check if the current player, when playing optimally, can win using the stones `i - j*j`. If the current player cannot win (`dp[i - j * j]` is false), it means the current player can win using the square number `j` and we set `dp[i]` to `true`.

The result for Alice winning the game is the value of `dp[n]`.

## A solution in C++

```cpp
bool winnerSquareGame(int n) {
    vector<bool> dp(n + 1, false);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j * j <= i; ++j) {
            if (!dp[i - j * j]) {
                dp[i] = true;
                break;
            }
        }
    }
    return dp[n];
}
```
We use dynamic programming to solve this problem. We create a boolean array `dp` of size `(n + 1)` to store if the current player can win with the remaining stones at position `i`. Each entry `dp[i]` is set to `false` initially.

We iterate through all possible numbers of stones from `1` to `n`. For each stone `i`, we iterate through all possible square numbers `j` less than or equal to `i`. Inside the inner loop, we check if the current player, when playing optimally, can win using the stones `i - j*j`. If the current player cannot win (`dp[i - j * j]` is false), it means the current player can win using the square number `j` and we set `dp[i]` to `true`.

The result for Alice winning the game is the value of `dp[n]`.

## A solution in Python

```python
def winnerSquareGame(n: int) -> bool:
    dp = [False] * (n + 1)
    for i in range(1, n + 1):
        j = 1
        while j * j <= i:
            if not dp[i - j * j]:
                dp[i] = True
                break
            j += 1
    return dp[n]
```
We use dynamic programming to solve this problem. We create a boolean array `dp` of size `(n + 1)` to store if the current player can win with the remaining stones at position `i`. Each entry `dp[i]` is set to `false` initially.

We iterate through all possible numbers of stones from `1` to `n`. For each stone `i`, we iterate through all possible square numbers `j` less than or equal to `i`. Inside the inner loop, we check if the current player, when playing optimally, can win using the stones `i - j*j`. If the current player cannot win (`dp[i - j * j]` is false), it means the current player can win using the square number `j` and we set `dp[i]` to `true`.

The result for Alice winning the game is the value of `dp[n]`.

## A solution in Javascript

```javascript
function winnerSquareGame(n) {
    const dp = new Array(n + 1).fill(false);
    for (let i = 1; i <= n; i++) {
        for (let j = 1; j * j <= i; j++) {
            if (!dp[i - j * j]) {
                dp[i] = true;
                break;
            }
        }
    }
    return dp[n];
}
```
We use dynamic programming to solve this problem. We create a boolean array `dp` of size `(n + 1)` to store if the current player can win with the remaining stones at position `i`. Each entry `dp[i]` is set to `false` initially.

We iterate through all possible numbers of stones from `1` to `n`. For each stone `i`, we iterate through all possible square numbers `j` less than or equal to `i`. Inside the inner loop, we check if the current player, when playing optimally, can win using the stones `i - j*j`. If the current player cannot win (`dp[i - j * j]` is false), it means the current player can win using the square number `j` and we set `dp[i]` to `true`.

The result for Alice winning the game is the value of `dp[n]`.


# Maximum Font to Fit a Sentence in a Screen

- slug: maximum-font-to-fit-a-sentence-in-a-screen
- difficulty: Medium

You are given a string `text`. We want to display `text` on a screen of width `w` and height `h`. You can choose any font size from array `fonts`, which contains the available font sizes **in ascending order**.

You can use the `FontInfo` interface to get the width and height of any character at any available font size.

The `FontInfo` interface is defined as such:

interface FontInfo {
  // Returns the width of character ch on the screen using font size fontSize.
  // O(1) per call
  public int getWidth(int fontSize, char ch);

  // Returns the height of any character on the screen using font size fontSize.
  // O(1) per call
  public int getHeight(int fontSize);
}

The calculated width of `text` for some `fontSize` is the **sum** of every `getWidth(fontSize, text[i])` call for each `0 <= i < text.length` (**0-indexed**). The calculated height of `text` for some `fontSize` is `getHeight(fontSize)`. Note that `text` is displayed on a **single line**.

It is guaranteed that `FontInfo` will return the same value if you call `getHeight` or `getWidth` with the same parameters.

It is also guaranteed that for any font size `fontSize` and any character `ch`:

*   `getHeight(fontSize) <= getHeight(fontSize+1)`
*   `getWidth(fontSize, ch) <= getWidth(fontSize+1, ch)`

Return _the maximum font size you can use to display_ `text` _on the screen_. If `text` cannot fit on the display with any font size, return `-1`.

**Example 1:**

**Input:** text =  "helloworld ", w = 80, h = 20, fonts = \[6,8,10,12,14,16,18,24,36\]
**Output:** 6

**Example 2:**

**Input:** text =  "leetcode ", w = 1000, h = 50, fonts = \[1,2,4\]
**Output:** 4

**Example 3:**

**Input:** text =  "easyquestion ", w = 100, h = 100, fonts = \[10,15,20,25\]
**Output:** -1

**Constraints:**

*   `1 <= text.length <= 50000`
*   `text` contains only lowercase English letters.
*   `1 <= w <= 107`
*   `1 <= h <= 104`
*   `1 <= fonts.length <= 105`
*   `1 <= fonts[i] <= 105`
*   `fonts` is sorted in ascending order and does not contain duplicates.

## A solution in Java

```java
int maxFontSize(String text, int w, int h, int[] fonts, FontInfo fontInfo) {
    int left = 0, right = fonts.length - 1, mid, ans = -1;
    while (left <= right) {
        mid = left + (right - left) / 2;
        int fontSize = fonts[mid];
        int width = 0, height = fontInfo.getHeight(fontSize);
        for (char ch : text.toCharArray())
            width += fontInfo.getWidth(fontSize, ch);
        if (width <= w && height <= h) {
            ans = fontSize;
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return ans;
}
```
First, use a binary search to find the maximum valid font size in the `fonts` array since it is sorted in ascending order. The binary search is effective because we are searching for the maximum value of the fonts.

When we are at the mid position on each iteration, we check whether the current font size can fit the entire text in the screen. To do this, we calculate the width and height of the entire text using the font size.

If the current font size meets the width and height requirement, we update the left pointer and store the current font size as the answer. Otherwise, we move the right pointer to the left.

After the binary search finishes, the answer will be the maximum font size that can fit the entire text within the width and height of the screen. If no font size fits on the screen, the answer will remain -1.

## A solution in C++

```cpp
int maxFontSize(string text, int w, int h, vector<int>& fonts, FontInfo fontInfo) {
    int left = 0, right = fonts.size() - 1, mid, ans = -1;
    while (left <= right) {
        mid = left + (right - left) / 2;
        int fontSize = fonts[mid];
        int width = 0, height = fontInfo.getHeight(fontSize);
        for (char ch : text)
            width += fontInfo.getWidth(fontSize, ch);
        if (width <= w && height <= h) {
            ans = fontSize;
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return ans;
}
```
First, use a binary search to find the maximum valid font size in the `fonts` array since it is sorted in ascending order. The binary search is effective because we are searching for the maximum value of the fonts.

When we are at the mid position on each iteration, we check whether the current font size can fit the entire text in the screen. To do this, we calculate the width and height of the entire text using the font size.

If the current font size meets the width and height requirement, we update the left pointer and store the current font size as the answer. Otherwise, we move the right pointer to the left.

After the binary search finishes, the answer will be the maximum font size that can fit the entire text within the width and height of the screen. If no font size fits on the screen, the answer will remain -1.

## A solution in Python

```python
def max_font_size(text: str, w: int, h: int, fonts: List[int], font_info) -> int:
    left, right, ans = 0, len(fonts) - 1, -1
    while left <= right:
        mid = left + (right - left) // 2
        font_size = fonts[mid]
        width, height = sum(font_info.getWidth(font_size, ch) for ch in text), font_info.getHeight(font_size)
        if width <= w and height <= h:
            ans = font_size
            left = mid + 1
        else:
            right = mid - 1
    return ans
```
First, use a binary search to find the maximum valid font size in the `fonts` array since it is sorted in ascending order. The binary search is effective because we are searching for the maximum value of the fonts.

When we are at the mid position on each iteration, we check whether the current font size can fit the entire text in the screen. To do this, we calculate the width and height of the entire text using the font size.

If the current font size meets the width and height requirement, we update the left pointer and store the current font size as the answer. Otherwise, we move the right pointer to the left.

After the binary search finishes, the answer will be the maximum font size that can fit the entire text within the width and height of the screen. If no font size fits on the screen, the answer will remain -1.

## A solution in Javascript

```javascript
function maxFontSize(text, w, h, fonts, fontInfo) {
    let left = 0, right = fonts.length - 1, mid, ans = -1;
    while (left <= right) {
        mid = left + ((right - left) / 2) | 0;
        let fontSize = fonts[mid];
        let width = 0, height = fontInfo.getHeight(fontSize);
        for (let ch of text)
            width += fontInfo.getWidth(fontSize, ch);
        if (width <= w && height <= h) {
            ans = fontSize;
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return ans;
}
```
First, use a binary search to find the maximum valid font size in the `fonts` array since it is sorted in ascending order. The binary search is effective because we are searching for the maximum value of the fonts.

When we are at the mid position on each iteration, we check whether the current font size can fit the entire text in the screen. To do this, we calculate the width and height of the entire text using the font size.

If the current font size meets the width and height requirement, we update the left pointer and store the current font size as the answer. Otherwise, we move the right pointer to the left.

After the binary search finishes, the answer will be the maximum font size that can fit the entire text within the width and height of the screen. If no font size fits on the screen, the answer will remain -1.


# Mean of Array After Removing Some Elements

- slug: mean-of-array-after-removing-some-elements
- difficulty: Easy

Given an integer array `arr`, return _the mean of the remaining integers after removing the smallest `5%` and the largest `5%` of the elements._

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

**Example 1:**

**Input:** arr = \[1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3\]
**Output:** 2.00000
**Explanation:** After erasing the minimum and the maximum values of this array, all elements are equal to 2, so the mean is 2.

**Example 2:**

**Input:** arr = \[6,2,7,5,1,2,0,3,10,2,5,0,5,5,0,8,7,6,8,0\]
**Output:** 4.00000

**Example 3:**

**Input:** arr = \[6,0,7,0,7,5,7,8,3,4,0,7,8,1,6,8,1,1,2,4,8,1,9,5,4,3,8,5,10,8,6,6,1,0,6,10,8,2,3,4\]
**Output:** 4.77778

**Constraints:**

*   `20 <= arr.length <= 1000`
*   `arr.length` **is a multiple** of `20`.
*   `0 <= arr[i] <= 105`

## A solution in Java

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

public boolean isPathCrossing(String path) {
    Set<String> visited = new HashSet<>();
    int x = 0, y = 0;
    visited.add(x + "," + y);
    for (char dir : path.toCharArray()) {
        if (dir == 'N') y++;
        else if (dir == 'S') y--;
        else if (dir == 'E') x++;
        else if (dir == 'W') x--;
        String location = x + "," + y;
        if (visited.contains(location)) return true;
        visited.add(location);
    }
    return false;
}
```
1. Initialize a visited set including the starting location (0,0).
2. Iterate through each character in the `path`.
3. Update the coordinates (x, y) as per the direction.
4. Check if the updated location is already in the visited set, then return true.
5. Add the updated location to the visited set.
6. After iterating through the entire path return false if no crossing has occurred.

## A solution in C++

```cpp
bool isPathCrossing(string path) {
    set<pair<int, int>> visited;
    int x = 0, y = 0;
    visited.insert({x, y});
    for (char dir : path) {
        if (dir == 'N') y++;
        else if (dir == 'S') y--;
        else if (dir == 'E') x++;
        else if (dir == 'W') x--;
        if (visited.count({x, y})) return true;
        visited.insert({x, y});
    }
    return false;
}
```
1. Initialize a visited set including the starting location (0,0).
2. Iterate through each character in the `path`.
3. Update the coordinates (x, y) as per the direction.
4. Check if the updated location is already in the visited set, then return true.
5. Add the updated location to the visited set.
6. After iterating through the entire path return false if no crossing has occurred.

## A solution in Python

```python
def is_path_crossing(path: str) -> bool:
    visited = {(0, 0)}
    x, y = 0, 0
    for dir in path:
        if dir == 'N': y += 1
        elif dir == 'S': y -= 1
        elif dir == 'E': x += 1
        elif dir == 'W': x -= 1
        if (x, y) in visited: return True
        visited.add((x, y))
    return False
```
1. Initialize a visited set including the starting location (0,0).
2. Iterate through each character in the `path`.
3. Update the coordinates (x, y) as per the direction.
4. Check if the updated location is already in the visited set, then return true.
5. Add the updated location to the visited set.
6. After iterating through the entire path return false if no crossing has occurred.

## A solution in Javascript

```javascript
function isPathCrossing(path) {
    const visited = new Set(['0,0']);
    let x = 0, y = 0;
    for (const dir of path) {
        if (dir === 'N') y++;
        else if (dir === 'S') y--;
        else if (dir === 'E') x++;
        else if (dir === 'W') x--;
        const location = `${x},${y}`;
        if (visited.has(location)) return true;
        visited.add(location);
    }
    return false;
}
```
1. Initialize a visited set including the starting location (0,0).
2. Iterate through each character in the `path`.
3. Update the coordinates (x, y) as per the direction.
4. Check if the updated location is already in the visited set, then return true.
5. Add the updated location to the visited set.
6. After iterating through the entire path return false if no crossing has occurred.


# Coordinate With Maximum Network Quality

- slug: coordinate-with-maximum-network-quality
- difficulty: Medium

You are given an array of network towers `towers`, where `towers[i] = [xi, yi, qi]` denotes the `ith` network tower with location `(xi, yi)` and quality factor `qi`. All the coordinates are **integral coordinates** on the X-Y plane, and the distance between the two coordinates is the **Euclidean distance**.

You are also given an integer `radius` where a tower is **reachable** if the distance is **less than or equal to** `radius`. Outside that distance, the signal becomes garbled, and the tower is **not reachable**.

The signal quality of the `ith` tower at a coordinate `(x, y)` is calculated with the formula `⌊qi / (1 + d)⌋`, where `d` is the distance between the tower and the coordinate. The **network quality** at a coordinate is the sum of the signal qualities from all the **reachable** towers.

Return _the array_ `[cx, cy]` _representing the **integral** coordinate_ `(cx, cy)` _where the **network quality** is maximum. If there are multiple coordinates with the same **network quality**, return the lexicographically minimum **non-negative** coordinate._

**Note:**

*   A coordinate `(x1, y1)` is lexicographically smaller than `(x2, y2)` if either:
    *   `x1 < x2`, or
    *   `x1 == x2` and `y1 < y2`.
*   `⌊val⌋` is the greatest integer less than or equal to `val` (the floor function).

**Example 1:**

**Input:** towers = \[\[1,2,5\],\[2,1,7\],\[3,1,9\]\], radius = 2
**Output:** \[2,1\]
**Explanation:** At coordinate (2, 1) the total quality is 13.
- Quality of 7 from (2, 1) results in ⌊7 / (1 + sqrt(0)⌋ = ⌊7⌋ = 7
- Quality of 5 from (1, 2) results in ⌊5 / (1 + sqrt(2)⌋ = ⌊2.07⌋ = 2
- Quality of 9 from (3, 1) results in ⌊9 / (1 + sqrt(1)⌋ = ⌊4.5⌋ = 4
No other coordinate has a higher network quality.

**Example 2:**

**Input:** towers = \[\[23,11,21\]\], radius = 9
**Output:** \[23,11\]
**Explanation:** Since there is only one tower, the network quality is highest right at the tower's location.

**Example 3:**

**Input:** towers = \[\[1,2,13\],\[2,1,7\],\[0,1,9\]\], radius = 2
**Output:** \[1,2\]
**Explanation:** Coordinate (1, 2) has the highest network quality.

**Constraints:**

*   `1 <= towers.length <= 50`
*   `towers[i].length == 3`
*   `0 <= xi, yi, qi <= 50`
*   `1 <= radius <= 50`

## A solution in Java

```java
public boolean canArrange(int[] arr, int k) {
    int[] counts = new int[k];
    for (int num : arr) {
        counts[(num % k + k) % k]++;
    }
    if (counts[0] % 2 != 0) {
        return false;
    }
    for (int i = 1; i <= k / 2; i++) {
        if (counts[i] != counts[k - i]) {
            return false;
        }
    }
    return true;
}
```
1. Create a counts array of size k, initializing all elements to 0.
2. Iterate through the input array and increment the count of (num % k + k) % k (to handle negative numbers as well) for each element in the array.
3. After counting, if the count at index 0 (sums that are multiples of k) is not even, return false, since we cannot create n / 2 pairs.
4. Iterate through the counts array from index 1 to k / 2 (inclusive) and check if the counts at index i and (k - i) are equal, if not then return false, since pairs cannot be formed that sum up to a multiple of k.
5. If no issues are found, return true as the pairs can be formed.

## A solution in C++

```cpp
bool canArrange(vector<int>& arr, int k) {
    vector<int> counts(k, 0);
    for (int num : arr) {
        counts[(num % k + k) % k]++;
    }
    if (counts[0] % 2 != 0) {
        return false;
    }
    for (int i = 1; i <= k / 2; i++) {
        if (counts[i] != counts[k - i]) {
            return false;
        }
    }
    return true;
}
```
1. Create a counts array of size k, initializing all elements to 0.
2. Iterate through the input array and increment the count of (num % k + k) % k (to handle negative numbers as well) for each element in the array.
3. After counting, if the count at index 0 (sums that are multiples of k) is not even, return false, since we cannot create n / 2 pairs.
4. Iterate through the counts array from index 1 to k / 2 (inclusive) and check if the counts at index i and (k - i) are equal, if not then return false, since pairs cannot be formed that sum up to a multiple of k.
5. If no issues are found, return true as the pairs can be formed.

## A solution in Python

```python
def canArrange(arr, k):
    counts = [0] * k
    for num in arr:
        counts[(num % k + k) % k] += 1
    if counts[0] % 2 != 0:
        return False
    for i in range(1, k // 2 + 1):
        if counts[i] != counts[k - i]:
            return False
    return True
```
1. Create a counts array of size k, initializing all elements to 0.
2. Iterate through the input array and increment the count of (num % k + k) % k (to handle negative numbers as well) for each element in the array.
3. After counting, if the count at index 0 (sums that are multiples of k) is not even, return false, since we cannot create n / 2 pairs.
4. Iterate through the counts array from index 1 to k / 2 (inclusive) and check if the counts at index i and (k - i) are equal, if not then return false, since pairs cannot be formed that sum up to a multiple of k.
5. If no issues are found, return true as the pairs can be formed.

## A solution in Javascript

```javascript
function canArrange(arr, k) {
    let counts = new Array(k).fill(0);
    for (let num of arr) {
        counts[(num % k + k) % k]++;
    }
    if (counts[0] % 2 != 0) {
        return false;
    }
    for (let i = 1; i <= k / 2; i++) {
        if (counts[i] !== counts[k - i]) {
            return false;
        }
    }
    return true;
}
```
1. Create a counts array of size k, initializing all elements to 0.
2. Iterate through the input array and increment the count of (num % k + k) % k (to handle negative numbers as well) for each element in the array.
3. After counting, if the count at index 0 (sums that are multiples of k) is not even, return false, since we cannot create n / 2 pairs.
4. Iterate through the counts array from index 1 to k / 2 (inclusive) and check if the counts at index i and (k - i) are equal, if not then return false, since pairs cannot be formed that sum up to a multiple of k.
5. If no issues are found, return true as the pairs can be formed.


# Number of Sets of K Non-Overlapping Line Segments

- slug: number-of-sets-of-k-non-overlapping-line-segments
- difficulty: Medium

Given `n` points on a 1-D plane, where the `ith` point (from `0` to `n-1`) is at `x = i`, find the number of ways we can draw **exactly** `k` **non-overlapping** line segments such that each segment covers two or more points. The endpoints of each segment must have **integral coordinates**. The `k` line segments **do not** have to cover all `n` points, and they are **allowed** to share endpoints.

Return _the number of ways we can draw_ `k` _non-overlapping line segments__._ Since this number can be huge, return it **modulo** `109 + 7`.

**Example 1:**

**Input:** n = 4, k = 2
**Output:** 5
**Explanation:** The two line segments are shown in red and blue.
The image above shows the 5 different ways {(0,2),(2,3)}, {(0,1),(1,3)}, {(0,1),(2,3)}, {(1,2),(2,3)}, {(0,1),(1,2)}.

**Example 2:**

**Input:** n = 3, k = 1
**Output:** 3
**Explanation:** The 3 ways are {(0,1)}, {(0,2)}, {(1,2)}.

**Example 3:**

**Input:** n = 30, k = 7
**Output:** 796297179
**Explanation:** The total number of possible ways to draw 7 line segments is 3796297200. Taking this number modulo 109 + 7 gives us 796297179.

**Constraints:**

*   `2 <= n <= 1000`
*   `1 <= k <= n-1`

## A solution in Java

```java
import java.util.Arrays;

class Solution {
    public int numSubseq(int[] nums, int target) {
        int n = nums.length;
        int mod = 1000000007;

        Arrays.sort(nums);

        long[] power = new long[n];
        power[0] = 1;
        for (int i = 1; i < n; ++i) {
            power[i] = (power[i - 1] * 2) % mod;
        }

        int ans = 0;
        int r = n;

        for (int l = 0; l < n; ++l) {
            while (r > l && nums[l] + nums[r - 1] > target) {
                --r;
            }

            ans = (ans + (int)power[r - l]) % mod;
        }

        return ans;
    }
}
```
1. Sort the nums array in ascending order.
2. Initialize an array `power` of length n, with `power[0] = 1`, and `power[i] = (power[i - 1] * 2) % mod` for `1 <= i < n`.
3. Initialize variables `ans` to store the number of valid subsequences and `r` to point at the end of the nums array.
4. Iterate from the left side of the nums array with variable `l`. In each iteration:
   a. Move the pointer `r` to the left as long as the sum of nums[l] and nums[r - 1] is greater than the target.
   b. Add `power[r - l]` to the answer (modulo mod).
5. Return the final answer (modulo mod).

## A solution in C++

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

int numSubseq(std::vector<int>& nums, int target) {
    int n = nums.size();
    int mod = 1e9 + 7;

    std::sort(nums.begin(), nums.end());

    std::vector<long long> power(n, 1);
    for (int i = 1; i < n; ++i) {
        power[i] = (power[i - 1] * 2) % mod;
    }

    int ans = 0;
    int r = n;
    for (int l = 0; l < n; ++l) {
        while (r > l && nums[l] + nums[r - 1] > target) {
            --r;
        }

        ans = (ans + power[r - l]) % mod;
    }

    return ans;
}
```
1. Sort the nums array in ascending order.
2. Initialize an array `power` of length n, with `power[0] = 1`, and `power[i] = (power[i - 1] * 2) % mod` for `1 <= i < n`.
3. Initialize variables `ans` to store the number of valid subsequences and `r` to point at the end of the nums array.
4. Iterate from the left side of the nums array with variable `l`. In each iteration:
   a. Move the pointer `r` to the left as long as the sum of nums[l] and nums[r - 1] is greater than the target.
   b. Add `power[r - l]` to the answer (modulo mod).
5. Return the final answer (modulo mod).

## A solution in Python

```python
def numSubseq(nums, target):
    nums.sort()
    n = len(nums)
    mod = 10**9 + 7

    power = [1] * n
    for i in range(1, n):
        power[i] = (power[i - 1] * 2) % mod

    ans = 0
    r = n
    for l in range(n):
        while r > l and nums[l] + nums[r - 1] > target:
            r -= 1

        ans = (ans + power[r - l]) % mod

    return ans
```
1. Sort the nums array in ascending order.
2. Initialize an array `power` of length n, with `power[0] = 1`, and `power[i] = (power[i - 1] * 2) % mod` for `1 <= i < n`.
3. Initialize variables `ans` to store the number of valid subsequences and `r` to point at the end of the nums array.
4. Iterate from the left side of the nums array with variable `l`. In each iteration:
   a. Move the pointer `r` to the left as long as the sum of nums[l] and nums[r - 1] is greater than the target.
   b. Add `power[r - l]` to the answer (modulo mod).
5. Return the final answer (modulo mod).

## A solution in Javascript

```javascript
function numSubseq(nums, target) {
    nums.sort((a, b) => a - b);
    const n = nums.length;
    const mod = 1e9 + 7;

    const power = new Array(n).fill(1);
    for (let i = 1; i < n; ++i) {
        power[i] = (power[i - 1] * 2) % mod;
    }

    let ans = 0;
    let r = n;
    for (let l = 0; l < n; ++l) {
        while (r > l && nums[l] + nums[r - 1] > target) {
            --r;
        }

        ans = (ans + power[r - l]) % mod;
    }

    return ans;
}
```
1. Sort the nums array in ascending order.
2. Initialize an array `power` of length n, with `power[0] = 1`, and `power[i] = (power[i - 1] * 2) % mod` for `1 <= i < n`.
3. Initialize variables `ans` to store the number of valid subsequences and `r` to point at the end of the nums array.
4. Iterate from the left side of the nums array with variable `l`. In each iteration:
   a. Move the pointer `r` to the left as long as the sum of nums[l] and nums[r - 1] is greater than the target.
   b. Add `power[r - l]` to the answer (modulo mod).
5. Return the final answer (modulo mod).


# Fancy Sequence

- slug: fancy-sequence
- difficulty: Hard

Write an API that generates fancy sequences using the `append`, `addAll`, and `multAll` operations.

Implement the `Fancy` class:

*   `Fancy()` Initializes the object with an empty sequence.
*   `void append(val)` Appends an integer `val` to the end of the sequence.
*   `void addAll(inc)` Increments all existing values in the sequence by an integer `inc`.
*   `void multAll(m)` Multiplies all existing values in the sequence by an integer `m`.
*   `int getIndex(idx)` Gets the current value at index `idx` (0-indexed) of the sequence **modulo** `109 + 7`. If the index is greater or equal than the length of the sequence, return `-1`.

**Example 1:**

**Input**
\[ "Fancy ",  "append ",  "addAll ",  "append ",  "multAll ",  "getIndex ",  "addAll ",  "append ",  "multAll ",  "getIndex ",  "getIndex ",  "getIndex "\]
\[\[\], \[2\], \[3\], \[7\], \[2\], \[0\], \[3\], \[10\], \[2\], \[0\], \[1\], \[2\]\]
**Output**
\[null, null, null, null, null, 10, null, null, null, 26, 34, 20\]

**Explanation**
Fancy fancy = new Fancy();
fancy.append(2);   // fancy sequence: \[2\]
fancy.addAll(3);   // fancy sequence: \[2+3\] -> \[5\]
fancy.append(7);   // fancy sequence: \[5, 7\]
fancy.multAll(2);  // fancy sequence: \[5\*2, 7\*2\] -> \[10, 14\]
fancy.getIndex(0); // return 10
fancy.addAll(3);   // fancy sequence: \[10+3, 14+3\] -> \[13, 17\]
fancy.append(10);  // fancy sequence: \[13, 17, 10\]
fancy.multAll(2);  // fancy sequence: \[13\*2, 17\*2, 10\*2\] -> \[26, 34, 20\]
fancy.getIndex(0); // return 26
fancy.getIndex(1); // return 34
fancy.getIndex(2); // return 20

**Constraints:**

*   `1 <= val, inc, m <= 100`
*   `0 <= idx <= 105`
*   At most `105` calls total will be made to `append`, `addAll`, `multAll`, and `getIndex`.

## A solution in Java

```java
import java.util.*;

class Solution {
    public int findMaxValueOfEquation(int[][] points, int k) {
        int res = Integer.MIN_VALUE;
        Deque<int[]> q = new LinkedList<>();

        for (int[] p : points) {
            while (!q.isEmpty() && p[0] - q.peekFirst()[1] > k)
                q.pollFirst();

            if (!q.isEmpty())
                res = Math.max(res, p[1] + p[0] + q.peekFirst()[0]);

            while (!q.isEmpty() && p[1] - p[0] >= q.peekLast()[0])
                q.pollLast();

            q.offerLast(new int[]{p[1] - p[0], p[0]});
        }

        return res;
    }
}
```
For each point, we maintain a double-ended queue (`deque` in Python and `LinkedList` in Java) of possible candidates that satisfy the condition |xi - xj| <= k, sorted by the value of yk - xk in decreasing order, so that the front of the queue has the largest value.

We iterate through the points array, and for each point:

1. Remove points for which |xi - xj| > k from the front of the queue.
2. Calculate the equation value for the current point using the largest yk - xk value from the front of the queue.
3. Update the result if the calculated value is greater than the current result.
4. If the current point has a larger yk - xk value than the last element in the queue, remove the last element from the queue. Since we want the largest yk - xk value in the queue, we keep removing the last element until we get a larger yk - xk value or the queue becomes empty.
5. Append the current point to the queue.

After iterating through all the points, return the maximum value found.

## A solution in C++

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

int findMaxValueOfEquation(vector<vector<int>>& points, int k) {
    int res = INT_MIN, left = 0;
    vector<pair<int, int>> q;

    for (auto& p : points) {
        while (!q.empty() && p[0] - q.front().second > k)
            q.erase(q.begin());

        if (!q.empty())
            res = max(res, p[1] + p[0] + q.front().first);

        while (!q.empty() && p[1] - p[0] >= q.back().first)
            q.pop_back();

        q.emplace_back(p[1] - p[0], p[0]);
    }

    return res;
}
```
For each point, we maintain a double-ended queue (`deque` in Python and `LinkedList` in Java) of possible candidates that satisfy the condition |xi - xj| <= k, sorted by the value of yk - xk in decreasing order, so that the front of the queue has the largest value.

We iterate through the points array, and for each point:

1. Remove points for which |xi - xj| > k from the front of the queue.
2. Calculate the equation value for the current point using the largest yk - xk value from the front of the queue.
3. Update the result if the calculated value is greater than the current result.
4. If the current point has a larger yk - xk value than the last element in the queue, remove the last element from the queue. Since we want the largest yk - xk value in the queue, we keep removing the last element until we get a larger yk - xk value or the queue becomes empty.
5. Append the current point to the queue.

After iterating through all the points, return the maximum value found.

## A solution in Python

```python
from collections import deque

def findMaxValueOfEquation(points, k):
    res = -float("inf")
    q = deque()

    for p in points:
        while q and p[0] - q[0][1] > k:
            q.popleft()

        if q:
            res = max(res, p[1] + p[0] + q[0][0])

        while q and p[1] - p[0] >= q[-1][0]:
            q.pop()

        q.append((p[1] - p[0], p[0]))

    return res
```
For each point, we maintain a double-ended queue (`deque` in Python and `LinkedList` in Java) of possible candidates that satisfy the condition |xi - xj| <= k, sorted by the value of yk - xk in decreasing order, so that the front of the queue has the largest value.

We iterate through the points array, and for each point:

1. Remove points for which |xi - xj| > k from the front of the queue.
2. Calculate the equation value for the current point using the largest yk - xk value from the front of the queue.
3. Update the result if the calculated value is greater than the current result.
4. If the current point has a larger yk - xk value than the last element in the queue, remove the last element from the queue. Since we want the largest yk - xk value in the queue, we keep removing the last element until we get a larger yk - xk value or the queue becomes empty.
5. Append the current point to the queue.

After iterating through all the points, return the maximum value found.

## A solution in Javascript

```javascript
function findMaxValueOfEquation(points, k) {
    let res = -Infinity;
    let q = [];

    for (let p of points) {
        while (q.length > 0 && p[0] - q[0][1] > k)
            q.shift();

        if (q.length > 0)
            res = Math.max(res, p[1] + p[0] + q[0][0]);

        while (q.length > 0 && p[1] - p[0] >= q[q.length - 1][0])
            q.pop();

        q.push([p[1] - p[0], p[0]]);
    }

    return res;
}
```
For each point, we maintain a double-ended queue (`deque` in Python and `LinkedList` in Java) of possible candidates that satisfy the condition |xi - xj| <= k, sorted by the value of yk - xk in decreasing order, so that the front of the queue has the largest value.

We iterate through the points array, and for each point:

1. Remove points for which |xi - xj| > k from the front of the queue.
2. Calculate the equation value for the current point using the largest yk - xk value from the front of the queue.
3. Update the result if the calculated value is greater than the current result.
4. If the current point has a larger yk - xk value than the last element in the queue, remove the last element from the queue. Since we want the largest yk - xk value in the queue, we keep removing the last element until we get a larger yk - xk value or the queue becomes empty.
5. Append the current point to the queue.

After iterating through all the points, return the maximum value found.