# Maximum Units on a Truck

- slug: maximum-units-on-a-truck
- difficulty: Easy

You are assigned to put some amount of boxes onto **one truck**. You are given a 2D array `boxTypes`, where `boxTypes[i] = [numberOfBoxesi, numberOfUnitsPerBoxi]`:

*   `numberOfBoxesi` is the number of boxes of type `i`.
*   `numberOfUnitsPerBoxi` is the number of units in each box of the type `i`.

You are also given an integer `truckSize`, which is the **maximum** number of **boxes** that can be put on the truck. You can choose any boxes to put on the truck as long as the number of boxes does not exceed `truckSize`.

Return _the **maximum** total number of **units** that can be put on the truck._

**Example 1:**

**Input:** boxTypes = \[\[1,3\],\[2,2\],\[3,1\]\], truckSize = 4
**Output:** 8
**Explanation:** There are:
- 1 box of the first type that contains 3 units.
- 2 boxes of the second type that contain 2 units each.
- 3 boxes of the third type that contain 1 unit each.
You can take all the boxes of the first and second types, and one box of the third type.
The total number of units will be = (1 \* 3) + (2 \* 2) + (1 \* 1) = 8.

**Example 2:**

**Input:** boxTypes = \[\[5,10\],\[2,5\],\[4,7\],\[3,9\]\], truckSize = 10
**Output:** 91

**Constraints:**

*   `1 <= boxTypes.length <= 1000`
*   `1 <= numberOfBoxesi, numberOfUnitsPerBoxi <= 1000`
*   `1 <= truckSize <= 106`

## A solution in Java

```java
import java.util.*;

public List<Integer> busiestServers(int k, int[] arrival, int[] load) {
    int[] serverRequests = new int[k];
    PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]);
    Queue<Integer> availableServers = new LinkedList<>();

    for (int i = 0; i < k; i++) {
        availableServers.offer(i);
    }

    for (int i = 0; i < arrival.length; i++) {
        while (!pq.isEmpty() && pq.peek()[0] <= arrival[i]) {
            availableServers.offer(pq.poll()[1]);
        }

        if (!availableServers.isEmpty()) {
            int serverId = availableServers.poll();
            serverRequests[serverId]++;
            pq.offer(new int[]{arrival[i] + load[i], serverId});
        }
    }

    int maxRequests = 0;
    for (int requests : serverRequests) {
        maxRequests = Math.max(maxRequests, requests);
    }

    List<Integer> result = new ArrayList<>();
    for (int i = 0; i < k; i++) {
        if (serverRequests[i] == maxRequests) {
            result.add(i);
        }
    }

    return result;
}
```
1. Initialize an array named `serverRequests` to store the number of requests handled by each server. This array is the same length as the number of servers and filled with 0s initially. Initialize a priority queue `pq` to store the servers that are currently handling a request, in ascending order of when they will finish processing the request. Initialize a queue `availableServers` and fill it with server IDs from 0 to k-1.
2. Iterate over the `arrival` array. For each request, dequeue any servers that have finished processing their tasks, and enqueue them into `availableServers`.
3. If there are servers available in `availableServers`, then assign the current request to the first available server. Increment the corresponding count in `serverRequests`, and enqueue the server into `pq` with the finish time (arrival[i] + load[i]) as the priority.
4. Iterate through `serverRequests` to find the maximum count (i.e. the highest number of requests handled).
5. Finally, create a result list (or array) containing the IDs of servers with counts equal to the maximum count.

## A solution in C++

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

std::vector<int> busiestServers(int k, std::vector<int>& arrival, std::vector<int>& load) {
    std::vector<int> serverRequests(k, 0);
    std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, std::greater<std::pair<int, int>>> pq;
    std::queue<int> availableServers;

    for (int i = 0; i < k; ++i) {
        availableServers.push(i);
    }

    for (int i = 0; i < arrival.size(); ++i) {
        while (!pq.empty() && pq.top().first <= arrival[i]) {
            availableServers.push(pq.top().second);
            pq.pop();
        }

        if (!availableServers.empty()) {
            int serverId = availableServers.front();
            availableServers.pop();
            serverRequests[serverId]++;
            pq.push({arrival[i] + load[i], serverId});
        }
    }

    int maxRequests = 0;
    for (int requests : serverRequests) {
        maxRequests = std::max(maxRequests, requests);
    }

    std::vector<int> result;
    for (int i = 0; i < k; ++i) {
        if (serverRequests[i] == maxRequests) {
            result.push_back(i);
        }
    }

    return result;
}
```
1. Initialize an array named `serverRequests` to store the number of requests handled by each server. This array is the same length as the number of servers and filled with 0s initially. Initialize a priority queue `pq` to store the servers that are currently handling a request, in ascending order of when they will finish processing the request. Initialize a queue `availableServers` and fill it with server IDs from 0 to k-1.
2. Iterate over the `arrival` array. For each request, dequeue any servers that have finished processing their tasks, and enqueue them into `availableServers`.
3. If there are servers available in `availableServers`, then assign the current request to the first available server. Increment the corresponding count in `serverRequests`, and enqueue the server into `pq` with the finish time (arrival[i] + load[i]) as the priority.
4. Iterate through `serverRequests` to find the maximum count (i.e. the highest number of requests handled).
5. Finally, create a result list (or array) containing the IDs of servers with counts equal to the maximum count.

## A solution in Python

```python
import heapq

def busiest_servers(k, arrival, load):
    server_requests = [0] * k
    pq = []
    available_servers = list(range(k))

    for i in range(len(arrival)):
        while pq and pq[0][0] <= arrival[i]:
            _, server_id = heapq.heappop(pq)
            available_servers.append(server_id)

        if available_servers:
            server_id = available_servers.pop(0)
            server_requests[server_id] += 1
            heapq.heappush(pq, (arrival[i] + load[i], server_id))

    max_requests = max(server_requests)
    return [i for i in range(k) if server_requests[i] == max_requests]
```
1. Initialize an array named `serverRequests` to store the number of requests handled by each server. This array is the same length as the number of servers and filled with 0s initially. Initialize a priority queue `pq` to store the servers that are currently handling a request, in ascending order of when they will finish processing the request. Initialize a queue `availableServers` and fill it with server IDs from 0 to k-1.
2. Iterate over the `arrival` array. For each request, dequeue any servers that have finished processing their tasks, and enqueue them into `availableServers`.
3. If there are servers available in `availableServers`, then assign the current request to the first available server. Increment the corresponding count in `serverRequests`, and enqueue the server into `pq` with the finish time (arrival[i] + load[i]) as the priority.
4. Iterate through `serverRequests` to find the maximum count (i.e. the highest number of requests handled).
5. Finally, create a result list (or array) containing the IDs of servers with counts equal to the maximum count.

## A solution in Javascript

```javascript
function busiestServers(k, arrival, load) {
    const serverRequests = new Array(k).fill(0);
    const pq = [];
    const availableServers = Array.from({ length: k }, (_, i) => i);

    for (let i = 0; i < arrival.length; i++) {
        while (pq.length && pq[0][0] <= arrival[i]) {
            const [, serverId] = pq.shift();
            availableServers.push(serverId);
        }

        if (availableServers.length) {
            const serverId = availableServers.shift();
            serverRequests[serverId]++;
            pq.push([arrival[i] + load[i], serverId]);
            pq.sort((a, b) => a[0] - b[0]);
        }
    }

    const maxRequests = Math.max(...serverRequests);
    return serverRequests.reduce((result, requests, i) => {
        if (requests === maxRequests) {
            result.push(i);
        }
        return result;
    }, []);
}
```
1. Initialize an array named `serverRequests` to store the number of requests handled by each server. This array is the same length as the number of servers and filled with 0s initially. Initialize a priority queue `pq` to store the servers that are currently handling a request, in ascending order of when they will finish processing the request. Initialize a queue `availableServers` and fill it with server IDs from 0 to k-1.
2. Iterate over the `arrival` array. For each request, dequeue any servers that have finished processing their tasks, and enqueue them into `availableServers`.
3. If there are servers available in `availableServers`, then assign the current request to the first available server. Increment the corresponding count in `serverRequests`, and enqueue the server into `pq` with the finish time (arrival[i] + load[i]) as the priority.
4. Iterate through `serverRequests` to find the maximum count (i.e. the highest number of requests handled).
5. Finally, create a result list (or array) containing the IDs of servers with counts equal to the maximum count.


# Count Good Meals

- slug: count-good-meals
- difficulty: Medium

A **good meal** is a meal that contains **exactly two different food items** with a sum of deliciousness equal to a power of two.

You can pick **any** two different foods to make a good meal.

Given an array of integers `deliciousness` where `deliciousness[i]` is the deliciousness of the `ith` item of food, return _the number of different **good meals** you can make from this list modulo_ `109 + 7`.

Note that items with different indices are considered different even if they have the same deliciousness value.

**Example 1:**

**Input:** deliciousness = \[1,3,5,7,9\]
**Output:** 4
**Explanation:** The good meals are (1,3), (1,7), (3,5) and, (7,9).
Their respective sums are 4, 8, 8, and 16, all of which are powers of 2.

**Example 2:**

**Input:** deliciousness = \[1,1,1,3,3,3,7\]
**Output:** 15
**Explanation:** The good meals are (1,1) with 3 ways, (1,3) with 9 ways, and (1,7) with 3 ways.

**Constraints:**

*   `1 <= deliciousness.length <= 105`
*   `0 <= deliciousness[i] <= 220`

## A solution in Java

```java
public int[][] restoreMatrix(int[] rowSum, int[] colSum) {
    int m = rowSum.length;
    int n = colSum.length;
    int[][] result = new int[m][n];

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            int value = Math.min(rowSum[i], colSum[j]);
            result[i][j] = value;
            rowSum[i] -= value;
            colSum[j] -= value;
        }
    }

    return result;
}
```
The algorithm works by iterating over each position in the matrix and calculating the minimum value between the current row sum and column sum. This value is assigned to the current position in the matrix, and the row and column sums are decremented by the value. By choosing the minimum value, we ensure that we fulfill the row and column sum requirements without exceeding them. We repeat this process for each cell in the matrix.

## A solution in C++

```cpp
#include <vector>

std::vector<std::vector<int>> restoreMatrix(std::vector<int>& rowSum, std::vector<int>& colSum) {
    int m = rowSum.size();
    int n = colSum.size();
    std::vector<std::vector<int>> result(m, std::vector<int>(n, 0));

    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            int value = std::min(rowSum[i], colSum[j]);
            result[i][j] = value;
            rowSum[i] -= value;
            colSum[j] -= value;
        }
    }

    return result;
}
```
The algorithm works by iterating over each position in the matrix and calculating the minimum value between the current row sum and column sum. This value is assigned to the current position in the matrix, and the row and column sums are decremented by the value. By choosing the minimum value, we ensure that we fulfill the row and column sum requirements without exceeding them. We repeat this process for each cell in the matrix.

## A solution in Python

```python
def restoreMatrix(rowSum, colSum):
    m, n = len(rowSum), len(colSum)
    result = [[0] * n for _ in range(m)]

    for i in range(m):
        for j in range(n):
            value = min(rowSum[i], colSum[j])
            result[i][j] = value
            rowSum[i] -= value
            colSum[j] -= value

    return result
```
The algorithm works by iterating over each position in the matrix and calculating the minimum value between the current row sum and column sum. This value is assigned to the current position in the matrix, and the row and column sums are decremented by the value. By choosing the minimum value, we ensure that we fulfill the row and column sum requirements without exceeding them. We repeat this process for each cell in the matrix.

## A solution in Javascript

```javascript
function restoreMatrix(rowSum, colSum) {
    let m = rowSum.length;
    let n = colSum.length;
    let result = Array.from({ length: m }, () => Array(n).fill(0));

    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            let value = Math.min(rowSum[i], colSum[j]);
            result[i][j] = value;
            rowSum[i] -= value;
            colSum[j] -= value;
        }
    }

    return result;
}
```
The algorithm works by iterating over each position in the matrix and calculating the minimum value between the current row sum and column sum. This value is assigned to the current position in the matrix, and the row and column sums are decremented by the value. By choosing the minimum value, we ensure that we fulfill the row and column sum requirements without exceeding them. We repeat this process for each cell in the matrix.


# Ways to Split Array Into Three Subarrays

- slug: ways-to-split-array-into-three-subarrays
- difficulty: Medium

A split of an integer array is **good** if:

*   The array is split into three **non-empty** contiguous subarrays - named `left`, `mid`, `right` respectively from left to right.
*   The sum of the elements in `left` is less than or equal to the sum of the elements in `mid`, and the sum of the elements in `mid` is less than or equal to the sum of the elements in `right`.

Given `nums`, an array of **non-negative** integers, return _the number of **good** ways to split_ `nums`. As the number may be too large, return it **modulo** `109 + 7`.

**Example 1:**

**Input:** nums = \[1,1,1\]
**Output:** 1
**Explanation:** The only good way to split nums is \[1\] \[1\] \[1\].

**Example 2:**

**Input:** nums = \[1,2,2,2,5,0\]
**Output:** 3
**Explanation:** There are three good ways of splitting nums:
\[1\] \[2\] \[2,2,5,0\]
\[1\] \[2,2\] \[2,5,0\]
\[1,2\] \[2,2\] \[5,0\]

**Example 3:**

**Input:** nums = \[3,2,1\]
**Output:** 0
**Explanation:** There is no good way to split nums.

**Constraints:**

*   `3 <= nums.length <= 105`
*   `0 <= nums[i] <= 104`

## A solution in Java

```java
public int waysToSplit(int[] nums) {
    int MOD = 1000000007;
    int n = nums.length;
    long[] prefixSum = new long[n + 1];
    for (int i = 0; i < n; i++) {
        prefixSum[i + 1] = prefixSum[i] + nums[i];
    }
    int ans = 0;
    int left = 0, right = 0;
    for (int mid = 1; mid < n - 1; mid++) {
        while (left + 1 < mid && prefixSum[left + 1] * 2 <= prefixSum[mid]) {
            left++;
        }
        while (right < mid || (right + 1 < n && prefixSum[right + 1] - prefixSum[mid] <= prefixSum[n] - prefixSum[right + 1])) {
            right++;
        }
        if (right >= mid && prefixSum[mid] - prefixSum[left] <= prefixSum[right] - prefixSum[mid]) {
            ans = (int) ((ans + right - mid + 1) % MOD);
        }
    }
    return ans;
}
```
We can calculate the prefis sum for the nums array so that we can have the sums for any subarray later in O(1) time complexity.
Then we can use a sliding window like technique for the mid and the right pointers. While updating the mid pointer, we update the left and the right pointer as well while making sure they remain valid with  subarray sums constraints mentioned in the problem statement.
For each valid mid, left, and right positions, we calculate the number of good splits by calculating the difference between mid and right pointers and add this to the result. We take this result modulo 10^9 + 7 as the answer may get too large.

Finally, we return the answer.

## A solution in C++

```cpp
int waysToSplit(vector<int>& nums) {
    int MOD = 1e9 + 7;
    int n = nums.size();
    vector<long long> prefixSum(n + 1, 0);
    for (int i = 0; i < n; i++) {
        prefixSum[i + 1] = prefixSum[i] + nums[i];
    }
    int ans = 0;
    int left = 0, right = 0;
    for (int mid = 1; mid < n - 1; mid++) {
        while (left + 1 < mid && prefixSum[left + 1] * 2 <= prefixSum[mid]) {
            left++;
        }
        while (right < mid || (right + 1 < n && prefixSum[right + 1] - prefixSum[mid] <= prefixSum[n] - prefixSum[right + 1])) {
            right++;
        }
        if (right >= mid && prefixSum[mid] - prefixSum[left] <= prefixSum[right] - prefixSum[mid]) {
            ans = (ans + right - mid + 1) % MOD;
        }
    }
    return ans;
}
```
We can calculate the prefis sum for the nums array so that we can have the sums for any subarray later in O(1) time complexity.
Then we can use a sliding window like technique for the mid and the right pointers. While updating the mid pointer, we update the left and the right pointer as well while making sure they remain valid with  subarray sums constraints mentioned in the problem statement.
For each valid mid, left, and right positions, we calculate the number of good splits by calculating the difference between mid and right pointers and add this to the result. We take this result modulo 10^9 + 7 as the answer may get too large.

Finally, we return the answer.

## A solution in Python

```python
def waysToSplit(nums):
    MOD = 10**9 + 7
    n = len(nums)
    prefixSum = [0] * (n + 1)
    for i in range(n):
        prefixSum[i + 1] = prefixSum[i] + nums[i]

    ans = 0
    left, right = 0, 0
    for mid in range(1, n - 1):
        while left + 1 < mid and prefixSum[left + 1] * 2 <= prefixSum[mid]:
            left += 1
        while right < mid or (right + 1 < n and prefixSum[right + 1] - prefixSum[mid] <= prefixSum[n] - prefixSum[right + 1]):
            right += 1
        if right >= mid and prefixSum[mid] - prefixSum[left] <= prefixSum[right] - prefixSum[mid]:
            ans = (ans + right - mid + 1) % MOD

    return ans
```
We can calculate the prefis sum for the nums array so that we can have the sums for any subarray later in O(1) time complexity.
Then we can use a sliding window like technique for the mid and the right pointers. While updating the mid pointer, we update the left and the right pointer as well while making sure they remain valid with  subarray sums constraints mentioned in the problem statement.
For each valid mid, left, and right positions, we calculate the number of good splits by calculating the difference between mid and right pointers and add this to the result. We take this result modulo 10^9 + 7 as the answer may get too large.

Finally, we return the answer.

## A solution in Javascript

```javascript
function waysToSplit(nums) {
    const MOD = BigInt(1e9 + 7);
    const n = nums.length;
    const prefixSum = new Array(n + 1).fill(BigInt(0));
    for (let i = 0; i < n; i++) {
        prefixSum[i + 1] = prefixSum[i] + BigInt(nums[i]);
    }
    let ans = BigInt(0);
    let left = 0, right = 0;
    for (let mid = 1; mid < n - 1; mid++) {
        while (left + 1 < mid && prefixSum[left + 1] * BigInt(2) <= prefixSum[mid]) {
            left++;
        }
        while (right < mid || (right + 1 < n && prefixSum[right + 1] - prefixSum[mid] <= prefixSum[n] - prefixSum[right + 1])) {
            right++;
        }
        if (right >= mid && prefixSum[mid] - prefixSum[left] <= prefixSum[right] - prefixSum[mid]) {
            ans = (ans + BigInt(right - mid + 1)) % MOD;
        }
    }
    return Number(ans);
}
```
We can calculate the prefis sum for the nums array so that we can have the sums for any subarray later in O(1) time complexity.
Then we can use a sliding window like technique for the mid and the right pointers. While updating the mid pointer, we update the left and the right pointer as well while making sure they remain valid with  subarray sums constraints mentioned in the problem statement.
For each valid mid, left, and right positions, we calculate the number of good splits by calculating the difference between mid and right pointers and add this to the result. We take this result modulo 10^9 + 7 as the answer may get too large.

Finally, we return the answer.


# Minimum Operations to Make a Subsequence

- slug: minimum-operations-to-make-a-subsequence
- difficulty: Hard

You are given an array `target` that consists of **distinct** integers and another integer array `arr` that **can** have duplicates.

In one operation, you can insert any integer at any position in `arr`. For example, if `arr = [1,4,1,2]`, you can add `3` in the middle and make it `[1,4,3,1,2]`. Note that you can insert the integer at the very beginning or end of the array.

Return _the **minimum** number of operations needed to make_ `target` _a **subsequence** of_ `arr`_._

A **subsequence** of an array is a new array generated from the original array by deleting some elements (possibly none) without changing the remaining elements' relative order. For example, `[2,7,4]` is a subsequence of `[4,2,3,7,2,1,4]` (the underlined elements), while `[2,4,2]` is not.

**Example 1:**

**Input:** target = \[5,1,3\], `arr` = \[9,4,2,3,4\]
**Output:** 2
**Explanation:** You can add 5 and 1 in such a way that makes `arr` = \[5,9,4,1,2,3,4\], then target will be a subsequence of `arr`.

**Example 2:**

**Input:** target = \[6,4,8,1,3,2\], `arr` = \[4,7,6,2,3,8,6,1\]
**Output:** 3

**Constraints:**

*   `1 <= target.length, arr.length <= 105`
*   `1 <= target[i], arr[i] <= 109`
*   `target` contains no duplicates.

## A solution in Java

```java
import java.util.*;

public int minOperations(int[] target, int[] arr) {
    Map<Integer, Integer> pos = new HashMap<>();
    for (int i = 0; i < target.length; ++i) {
        pos.put(target[i], i);
    }

    List<Integer> dp = new ArrayList<>();
    for (int a : arr) {
        if (pos.containsKey(a)) {
            int idx = Collections.binarySearch(dp, pos.get(a));
            if (idx < 0) {
                idx = -(idx + 1);
            }
            if (idx == dp.size()) {
                dp.add(pos.get(a));
            } else {
                dp.set(idx, pos.get(a));
            }
        }
    }
    return target.length - dp.size();
}
```
The algorithm is based on finding the longest increasing subsequence in the modified `arr` array where only the indices of target numbers are considered. First, a hashmap `pos` is created to store the position of each target number. Then, iterate through the `arr` array and check if a number exists in the target. If it does, find the index of this number in the DP (Dynamic Programming) array using binary search or lower_bound. If the index is at the end of the DP array, append the position to the DP array; otherwise, update the DP array at the found index. Finally, return the difference between the target array's length and the DP array's length as the minimum number of operations needed to make the target a subsequence of `arr`.

## A solution in C++

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

int minOperations(vector<int>& target, vector<int>& arr) {
    unordered_map<int, int> pos;
    for (int i = 0; i < target.size(); ++i) {
        pos[target[i]] = i;
    }

    vector<int> dp;
    for (const int& a : arr) {
        if (pos.find(a) != pos.end()) {
            auto idx = lower_bound(dp.begin(), dp.end(), pos[a]);
            if (idx == dp.end()) {
                dp.push_back(pos[a]);
            } else {
                *idx = pos[a];
            }
        }
    }
    return target.size() - dp.size();
}
```
The algorithm is based on finding the longest increasing subsequence in the modified `arr` array where only the indices of target numbers are considered. First, a hashmap `pos` is created to store the position of each target number. Then, iterate through the `arr` array and check if a number exists in the target. If it does, find the index of this number in the DP (Dynamic Programming) array using binary search or lower_bound. If the index is at the end of the DP array, append the position to the DP array; otherwise, update the DP array at the found index. Finally, return the difference between the target array's length and the DP array's length as the minimum number of operations needed to make the target a subsequence of `arr`.

## A solution in Python

```python
from bisect import bisect_left

def minOperations(target, arr):
    pos = {x: i for i, x in enumerate(target)}

    dp = []
    for a in arr:
        if a in pos:
            idx = bisect_left(dp, pos[a])
            if idx == len(dp):
                dp.append(pos[a])
            else:
                dp[idx] = pos[a]
    return len(target) - len(dp)
```
The algorithm is based on finding the longest increasing subsequence in the modified `arr` array where only the indices of target numbers are considered. First, a hashmap `pos` is created to store the position of each target number. Then, iterate through the `arr` array and check if a number exists in the target. If it does, find the index of this number in the DP (Dynamic Programming) array using binary search or lower_bound. If the index is at the end of the DP array, append the position to the DP array; otherwise, update the DP array at the found index. Finally, return the difference between the target array's length and the DP array's length as the minimum number of operations needed to make the target a subsequence of `arr`.

## A solution in Javascript

```javascript
function minOperations(target, arr) {
    const pos = new Map();
    for (let i = 0; i < target.length; ++i) {
        pos.set(target[i], i);
    }

    const dp = [];
    for (const a of arr) {
        if (pos.has(a)) {
            const idx = dp.findIndex(x => x >= pos.get(a));
            if (idx === -1) {
                dp.push(pos.get(a));
            } else {
                dp[idx] = pos.get(a);
            }
        }
    }
    return target.length - dp.length;
}
```
The algorithm is based on finding the longest increasing subsequence in the modified `arr` array where only the indices of target numbers are considered. First, a hashmap `pos` is created to store the position of each target number. Then, iterate through the `arr` array and check if a number exists in the target. If it does, find the index of this number in the DP (Dynamic Programming) array using binary search or lower_bound. If the index is at the end of the DP array, append the position to the DP array; otherwise, update the DP array at the found index. Finally, return the difference between the target array's length and the DP array's length as the minimum number of operations needed to make the target a subsequence of `arr`.


# Sum Of Special Evenly-Spaced Elements In Array

- slug: sum-of-special-evenly-spaced-elements-in-array
- difficulty: Hard

You are given a **0-indexed** integer array `nums` consisting of `n` non-negative integers.

You are also given an array `queries`, where `queries[i] = [xi, yi]`. The answer to the `ith` query is the sum of all `nums[j]` where `xi <= j < n` and `(j - xi)` is divisible by `yi`.

Return _an array_ `answer` _where_ `answer.length == queries.length` _and_ `answer[i]` _is the answer to the_ `ith` _query **modulo**_ `109 + 7`.

**Example 1:**

**Input:** nums = \[0,1,2,3,4,5,6,7\], queries = \[\[0,3\],\[5,1\],\[4,2\]\]
**Output:** \[9,18,10\]
**Explanation:** The answers of the queries are as follows:
1) The j indices that satisfy this query are 0, 3, and 6. nums\[0\] + nums\[3\] + nums\[6\] = 9
2) The j indices that satisfy this query are 5, 6, and 7. nums\[5\] + nums\[6\] + nums\[7\] = 18
3) The j indices that satisfy this query are 4 and 6. nums\[4\] + nums\[6\] = 10

**Example 2:**

**Input:** nums = \[100,200,101,201,102,202,103,203\], queries = \[\[0,7\]\]
**Output:** \[303\]

**Constraints:**

*   `n == nums.length`
*   `1 <= n <= 5 * 104`
*   `0 <= nums[i] <= 109`
*   `1 <= queries.length <= 1.5 * 105`
*   `0 <= xi < n`
*   `1 <= yi <= 5 * 104`

## A solution in Java

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

public String reorderSpaces(String text) {
    int spaces = 0;
    List<String> words = new ArrayList<>();

    String[] splitText = text.split("\\s+");
    for (String word : splitText) {
        words.add(word);
        spaces += word.length() - word.trim().length();
    }

    if (words.size() == 1) {
        return words.get(0) + " ".repeat(spaces);
    }

    int spaceBetweenWords = spaces / (words.size() - 1);
    int extraSpaces = spaces % (words.size() - 1);
    StringBuilder result = new StringBuilder();

    for (int i = 0; i < words.size(); i++) {
        result.append(words.get(i));
        if (i < words.size() - 1) {
            result.append(" ".repeat(spaceBetweenWords));
        }
    }

    result.append(" ".repeat(extraSpaces));

    return result.toString();
}
```
1. Count the number of spaces and split the text into a list/vector of words.
2. If there's only one word, return the word followed by all spaces.
3. Calculate the number of spaces to be distributed between words, as well as the extra spaces that remain.
4. Iterate through the words, and for each word, append it to the result variable. If the current word is not the last one, append the appropriate number of spaces.
5. After the loop, append any extra spaces to the result variable.
6. Return the result variable.

## A solution in C++

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

std::string reorderSpaces(const std::string& text) {
    int spaces = 0;
    std::vector<std::string> words;

    std::stringstream ss(text);
    std::string word;
    while (ss >> word) {
        words.push_back(word);
        spaces += std::count(word.begin(), word.end(), ' ');
    }

    if (words.size() == 1) {
        return words[0] + std::string(spaces, ' ');
    }

    int space_between_words = spaces / (words.size() - 1);
    int extra_spaces = spaces % (words.size() - 1);
    std::string result;

    for (size_t i = 0; i < words.size(); i++) {
        result += words[i];
        if (i < words.size() - 1) {
            result += std::string(space_between_words, ' ');
        }
    }

    result += std::string(extra_spaces, ' ');

    return result;
}
```
1. Count the number of spaces and split the text into a list/vector of words.
2. If there's only one word, return the word followed by all spaces.
3. Calculate the number of spaces to be distributed between words, as well as the extra spaces that remain.
4. Iterate through the words, and for each word, append it to the result variable. If the current word is not the last one, append the appropriate number of spaces.
5. After the loop, append any extra spaces to the result variable.
6. Return the result variable.

## A solution in Python

```python
def reorder_spaces(text: str) -> str:
    spaces = text.count(' ')
    words = text.split()

    if len(words) == 1:
        return words[0] + ' ' * spaces

    space_between_words = spaces // (len(words) - 1)
    extra_spaces = spaces % (len(words) - 1)
    result = ''

    for i, word in enumerate(words):
        result += word
        if i < len(words) - 1:
            result += ' ' * space_between_words

    result += ' ' * extra_spaces

    return result
```
1. Count the number of spaces and split the text into a list/vector of words.
2. If there's only one word, return the word followed by all spaces.
3. Calculate the number of spaces to be distributed between words, as well as the extra spaces that remain.
4. Iterate through the words, and for each word, append it to the result variable. If the current word is not the last one, append the appropriate number of spaces.
5. After the loop, append any extra spaces to the result variable.
6. Return the result variable.

## A solution in Javascript

```javascript
function reorderSpaces(text) {
    const spaces = text.split('').filter(char => char === ' ').length;
    const words = text.trim().split(/\s+/);

    if (words.length === 1) {
        return words[0] + ' '.repeat(spaces);
    }

    const spaceBetweenWords = Math.floor(spaces / (words.length - 1));
    const extraSpaces = spaces % (words.length - 1);
    let result = '';

    for (let i = 0; i < words.length; i++) {
        result += words[i];
        if (i < words.length - 1) {
            result += ' '.repeat(spaceBetweenWords);
        }
    }

    result += ' '.repeat(extraSpaces);

    return result;
}
```
1. Count the number of spaces and split the text into a list/vector of words.
2. If there's only one word, return the word followed by all spaces.
3. Calculate the number of spaces to be distributed between words, as well as the extra spaces that remain.
4. Iterate through the words, and for each word, append it to the result variable. If the current word is not the last one, append the appropriate number of spaces.
5. After the loop, append any extra spaces to the result variable.
6. Return the result variable.


# Calculate Money in Leetcode Bank

- slug: calculate-money-in-leetcode-bank
- difficulty: Easy

Hercy wants to save money for his first car. He puts money in the Leetcode bank **every day**.

He starts by putting in `$1` on Monday, the first day. Every day from Tuesday to Sunday, he will put in `$1` more than the day before. On every subsequent Monday, he will put in `$1` more than the **previous Monday**.

Given `n`, return _the total amount of money he will have in the Leetcode bank at the end of the_ `nth` _day._

**Example 1:**

**Input:** n = 4
**Output:** 10
**Explanation:** After the 4th day, the total is 1 + 2 + 3 + 4 = 10.

**Example 2:**

**Input:** n = 10
**Output:** 37
**Explanation:** After the 10th day, the total is (1 + 2 + 3 + 4 + 5 + 6 + 7) + (2 + 3 + 4) = 37. Notice that on the 2nd Monday, Hercy only puts in $2.

**Example 3:**

**Input:** n = 20
**Output:** 96
**Explanation:** After the 20th day, the total is (1 + 2 + 3 + 4 + 5 + 6 + 7) + (2 + 3 + 4 + 5 + 6 + 7 + 8) + (3 + 4 + 5 + 6 + 7 + 8) = 96.

**Constraints:**

*   `1 <= n <= 1000`

## A solution in Java

```java
public int maxProductPath(int[][] grid) {
    int m = grid.length, n = grid[0].length, mod = 1000000007;
    long[][][] dp = new long[m][n][2];

    dp[0][0] = new long[]{grid[0][0], grid[0][0]};

    for(int i = 1; i < m; i++) {
        dp[i][0] = new long[]{dp[i-1][0][0] * grid[i][0], dp[i-1][0][0] * grid[i][0]};
    }
    for(int j = 1; j < n; j++) {
        dp[0][j] = new long[]{dp[0][j-1][0] * grid[0][j], dp[0][j-1][0] * grid[0][j]};
    }

    for(int i = 1; i < m; i++) {
        for(int j = 1; j < n; j++) {
            if(grid[i][j] < 0) {
                dp[i][j][0] = Math.min(dp[i - 1][j][1], dp[i][j - 1][1]) * grid[i][j];
                dp[i][j][1] = Math.max(dp[i - 1][j][0], dp[i][j - 1][0]) * grid[i][j];
            } else {
                dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i][j - 1][0]) * grid[i][j];
                dp[i][j][1] = Math.min(dp[i - 1][j][1], dp[i][j - 1][1]) * grid[i][j];
            }
        }
    }

    return dp[m - 1][n - 1][0] >= 0 ? (int)(dp[m - 1][n - 1][0] % mod) : -1;
}
```
The algorithm used is a dynamic programming approach, where we maintain a 3D DP array `dp` with dimensions m x n x 2. For each cell `dp[i][j]`, we store the maximum non-negative product and the minimum non-positive product of the path up until cell (i, j) in the grid. We initialize the first row and first column of the grid, and then iterate through the remaining cells.

At each cell, if the corresponding grid value is negative, the product of this value with the minimum non-positive value of the previous cells will give the maximum non-negative value for the current cell, and vice versa for minimum non-positive value. If the value is non-negative, multiplying by maximum non-negative values from previous cells will give the maximum non-negative value for the current cell, and similarly for minimum non-positive value.

After filling out the DP array, the result is the modulo of the maximum non-negative product of the last cell in the DP array, unless it's negative, in which case we return -1.

## A solution in C++

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

int maxProductPath(vector<vector<int>>& grid) {
    int m = grid.size(), n = grid[0].size(), mod = 1e9 + 7;
    vector<vector<vector<long long>>> dp(m, vector<vector<long long>>(n, vector<long long>(2)));

    dp[0][0] = {grid[0][0], grid[0][0]};

    for(int i = 1; i < m; i++) {
        dp[i][0][0] = dp[i][0][1] = dp[i-1][0][0] * grid[i][0];
    }
    for(int j = 1; j < n; j++) {
        dp[0][j][0] = dp[0][j][1] = dp[0][j-1][0] * grid[0][j];
    }

    for(int i = 1; i < m; i++) {
        for(int j = 1; j < n; j++) {
            if(grid[i][j] < 0) {
                dp[i][j][0] = min(dp[i - 1][j][1], dp[i][j - 1][1]) * grid[i][j];
                dp[i][j][1] = max(dp[i - 1][j][0], dp[i][j - 1][0]) * grid[i][j];
            } else {
                dp[i][j][0] = max(dp[i - 1][j][0], dp[i][j - 1][0]) * grid[i][j];
                dp[i][j][1] = min(dp[i - 1][j][1], dp[i][j - 1][1]) * grid[i][j];
            }
        }
    }

    return dp[m - 1][n - 1][0] >= 0 ? dp[m - 1][n - 1][0] % mod : -1;
}
```
The algorithm used is a dynamic programming approach, where we maintain a 3D DP array `dp` with dimensions m x n x 2. For each cell `dp[i][j]`, we store the maximum non-negative product and the minimum non-positive product of the path up until cell (i, j) in the grid. We initialize the first row and first column of the grid, and then iterate through the remaining cells.

At each cell, if the corresponding grid value is negative, the product of this value with the minimum non-positive value of the previous cells will give the maximum non-negative value for the current cell, and vice versa for minimum non-positive value. If the value is non-negative, multiplying by maximum non-negative values from previous cells will give the maximum non-negative value for the current cell, and similarly for minimum non-positive value.

After filling out the DP array, the result is the modulo of the maximum non-negative product of the last cell in the DP array, unless it's negative, in which case we return -1.

## A solution in Python

```python
def maxProductPath(grid):
    m, n, mod = len(grid), len(grid[0]), int(1e9 + 7)
    dp = [[[0, 0] for _ in range(n)] for _ in range(m)]

    dp[0][0] = [grid[0][0], grid[0][0]]

    for i in range(1, m):
        dp[i][0] = [dp[i - 1][0][0] * grid[i][0], dp[i - 1][0][0] * grid[i][0]]
    for j in range(1, n):
        dp[0][j] = [dp[0][j - 1][0] * grid[0][j], dp[0][j - 1][0] * grid[0][j]]

    for i in range(1, m):
        for j in range(1, n):
            if grid[i][j] < 0:
                dp[i][j][0] = min(dp[i - 1][j][1], dp[i][j - 1][1]) * grid[i][j]
                dp[i][j][1] = max(dp[i - 1][j][0], dp[i][j - 1][0]) * grid[i][j]
            else:
                dp[i][j][0] = max(dp[i - 1][j][0], dp[i][j - 1][0]) * grid[i][j]
                dp[i][j][1] = min(dp[i - 1][j][1], dp[i][j - 1][1]) * grid[i][j]

    return dp[m - 1][n - 1][0] % mod if dp[m - 1][n - 1][0] >= 0 else -1
```
The algorithm used is a dynamic programming approach, where we maintain a 3D DP array `dp` with dimensions m x n x 2. For each cell `dp[i][j]`, we store the maximum non-negative product and the minimum non-positive product of the path up until cell (i, j) in the grid. We initialize the first row and first column of the grid, and then iterate through the remaining cells.

At each cell, if the corresponding grid value is negative, the product of this value with the minimum non-positive value of the previous cells will give the maximum non-negative value for the current cell, and vice versa for minimum non-positive value. If the value is non-negative, multiplying by maximum non-negative values from previous cells will give the maximum non-negative value for the current cell, and similarly for minimum non-positive value.

After filling out the DP array, the result is the modulo of the maximum non-negative product of the last cell in the DP array, unless it's negative, in which case we return -1.

## A solution in Javascript

```javascript
function maxProductPath(grid) {
    const m = grid.length;
    const n = grid[0].length;
    const mod = 1e9 + 7;
    const dp = new Array(m).fill(0).map(() => new Array(n).fill(0).map(() => [0, 0]));

    dp[0][0] = [grid[0][0], grid[0][0]];

    for(let i = 1; i < m; i++) {
        dp[i][0] = [dp[i - 1][0][0] * grid[i][0], dp[i - 1][0][0] * grid[i][0]];
    }
    for(let j = 1; j < n; j++) {
        dp[0][j] = [dp[0][j - 1][0] * grid[0][j], dp[0][j - 1][0] * grid[0][j]];
    }

    for(let i = 1; i < m; i++) {
        for(let j = 1; j < n; j++) {
            if(grid[i][j] < 0) {
                dp[i][j][0] = Math.min(dp[i - 1][j][1], dp[i][j - 1][1]) * grid[i][j];
                dp[i][j][1] = Math.max(dp[i - 1][j][0], dp[i][j - 1][0]) * grid[i][j];
            } else {
                dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i][j - 1][0]) * grid[i][j];
                dp[i][j][1] = Math.min(dp[i - 1][j][1], dp[i][j - 1][1]) * grid[i][j];
            }
        }
    }

    return dp[m - 1][n - 1][0] >= 0 ? dp[m - 1][n - 1][0] % mod : -1;
}
```
The algorithm used is a dynamic programming approach, where we maintain a 3D DP array `dp` with dimensions m x n x 2. For each cell `dp[i][j]`, we store the maximum non-negative product and the minimum non-positive product of the path up until cell (i, j) in the grid. We initialize the first row and first column of the grid, and then iterate through the remaining cells.

At each cell, if the corresponding grid value is negative, the product of this value with the minimum non-positive value of the previous cells will give the maximum non-negative value for the current cell, and vice versa for minimum non-positive value. If the value is non-negative, multiplying by maximum non-negative values from previous cells will give the maximum non-negative value for the current cell, and similarly for minimum non-positive value.

After filling out the DP array, the result is the modulo of the maximum non-negative product of the last cell in the DP array, unless it's negative, in which case we return -1.


# Maximum Score From Removing Substrings

- slug: maximum-score-from-removing-substrings
- difficulty: Medium

You are given a string `s` and two integers `x` and `y`. You can perform two types of operations any number of times.

*   Remove substring `"ab "` and gain `x` points.
    *   For example, when removing `"ab "` from `"cabxbae "` it becomes `"cxbae "`.
*   Remove substring `"ba "` and gain `y` points.
    *   For example, when removing `"ba "` from `"cabxbae "` it becomes `"cabxe "`.

Return _the maximum points you can gain after applying the above operations on_ `s`.

**Example 1:**

**Input:** s =  "cdbcbbaaabab ", x = 4, y = 5
**Output:** 19
**Explanation:**
- Remove the  "ba " underlined in  "cdbcbbaaabab ". Now, s =  "cdbcbbaaab " and 5 points are added to the score.
- Remove the  "ab " underlined in  "cdbcbbaaab ". Now, s =  "cdbcbbaa " and 4 points are added to the score.
- Remove the  "ba " underlined in  "cdbcbbaa ". Now, s =  "cdbcba " and 5 points are added to the score.
- Remove the  "ba " underlined in  "cdbcba ". Now, s =  "cdbc " and 5 points are added to the score.
Total score = 5 + 4 + 5 + 5 = 19.

**Example 2:**

**Input:** s =  "aabbaaxybbaabb ", x = 5, y = 4
**Output:** 20

**Constraints:**

*   `1 <= s.length <= 105`
*   `1 <= x, y <= 104`
*   `s` consists of lowercase English letters.

## A solution in Java

```java
import java.util.Arrays;

public int minCost(int[][] cost, int size1, int size2) {
    int[] dp = new int[size2 + 1];
    Arrays.fill(dp, Integer.MAX_VALUE);
    dp[0] = 0;

    for (int i = 0; i < size1; i++) {
        for (int j = size2; j >= 0; j--) {
            int minCost = Integer.MAX_VALUE;
            for (int k = 0; k < size2; k++) {
                if (((1 << k) & j) == 0) {
                    minCost = Math.min(minCost, cost[i][k] + dp[j | (1 << k)]);
                }
            }
            dp[j] = Math.min(dp[j], minCost);
        }
    }

    return dp[(1 << size2) - 1];
}
```
The algorithm uses dynamic programming to solve the problem. It initializes a dp array with size `size2+1` filled with infinity to represent minimum cost, and sets the first element of dp to zero. The dp array's indices represent the connected point states of the second group.

For each point in the first group, we iterate through the dp array in reverse and then loop through each point in the second group. If a point in the second group is not connected to the current point from the first group, then we calculate the cost of connecting the two points and update the cost in the dp array by taking the minimum between the current cost and the new calculated cost.

After iterating through all the points in both groups, the minimum cost to connect the two groups can be found at the last index of the dp array.

## A solution in C++

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

int min_cost(vector<vector<int>>& cost, int size1, int size2) {
    vector<int> dp(size2 + 1, INT_MAX);
    dp[0] = 0;

    for (int i = 0; i < size1; ++i) {
        for (int j = size2; j >= 0; --j) {
            int min_cost = INT_MAX;
            for (int k = 0; k < size2; ++k) {
                if (((1 << k) & j) == 0) {
                    min_cost = min(min_cost, cost[i][k] + dp[j | (1 << k)]);
                }
            }
            dp[j] = min(dp[j], min_cost);
        }
    }

    return dp[(1 << size2) - 1];
}
```
The algorithm uses dynamic programming to solve the problem. It initializes a dp array with size `size2+1` filled with infinity to represent minimum cost, and sets the first element of dp to zero. The dp array's indices represent the connected point states of the second group.

For each point in the first group, we iterate through the dp array in reverse and then loop through each point in the second group. If a point in the second group is not connected to the current point from the first group, then we calculate the cost of connecting the two points and update the cost in the dp array by taking the minimum between the current cost and the new calculated cost.

After iterating through all the points in both groups, the minimum cost to connect the two groups can be found at the last index of the dp array.

## A solution in Python

```python
def min_cost(cost, size1, size2):
    dp = [float('inf')] * (size2 + 1)
    dp[0] = 0

    for i in range(size1):
        for j in range(size2, -1, -1):
            min_cost = float('inf')
            for k in range(size2):
                if (1 << k) & j == 0:
                    min_cost = min(min_cost, cost[i][k] + dp[j | (1 << k)])
            dp[j] = min(dp[j], min_cost)

    return dp[(1 << size2) - 1]
```
The algorithm uses dynamic programming to solve the problem. It initializes a dp array with size `size2+1` filled with infinity to represent minimum cost, and sets the first element of dp to zero. The dp array's indices represent the connected point states of the second group.

For each point in the first group, we iterate through the dp array in reverse and then loop through each point in the second group. If a point in the second group is not connected to the current point from the first group, then we calculate the cost of connecting the two points and update the cost in the dp array by taking the minimum between the current cost and the new calculated cost.

After iterating through all the points in both groups, the minimum cost to connect the two groups can be found at the last index of the dp array.

## A solution in Javascript

```javascript
function minCost(cost, size1, size2) {
    let dp = new Array(size2 + 1).fill(Infinity);
    dp[0] = 0;

    for (let i = 0; i < size1; i++) {
        for (let j = size2; j >= 0; j--) {
            let minCost = Infinity;
            for (let k = 0; k < size2; k++) {
                if (((1 << k) & j) === 0) {
                    minCost = Math.min(minCost, cost[i][k] + dp[j | (1 << k)]);
                }
            }
            dp[j] = Math.min(dp[j], minCost);
        }
    }

    return dp[(1 << size2) - 1];
}
```
The algorithm uses dynamic programming to solve the problem. It initializes a dp array with size `size2+1` filled with infinity to represent minimum cost, and sets the first element of dp to zero. The dp array's indices represent the connected point states of the second group.

For each point in the first group, we iterate through the dp array in reverse and then loop through each point in the second group. If a point in the second group is not connected to the current point from the first group, then we calculate the cost of connecting the two points and update the cost in the dp array by taking the minimum between the current cost and the new calculated cost.

After iterating through all the points in both groups, the minimum cost to connect the two groups can be found at the last index of the dp array.


# Construct the Lexicographically Largest Valid Sequence

- slug: construct-the-lexicographically-largest-valid-sequence
- difficulty: Medium

Given an integer `n`, find a sequence that satisfies all of the following:

*   The integer `1` occurs once in the sequence.
*   Each integer between `2` and `n` occurs twice in the sequence.
*   For every integer `i` between `2` and `n`, the **distance** between the two occurrences of `i` is exactly `i`.

The **distance** between two numbers on the sequence, `a[i]` and `a[j]`, is the absolute difference of their indices, `|j - i|`.

Return _the **lexicographically largest** sequence__. It is guaranteed that under the given constraints, there is always a solution._

A sequence `a` is lexicographically larger than a sequence `b` (of the same length) if in the first position where `a` and `b` differ, sequence `a` has a number greater than the corresponding number in `b`. For example, `[0,1,9,0]` is lexicographically larger than `[0,1,5,6]` because the first position they differ is at the third number, and `9` is greater than `5`.

**Example 1:**

**Input:** n = 3
**Output:** \[3,1,2,3,2\]
**Explanation:** \[2,3,2,1,3\] is also a valid sequence, but \[3,1,2,3,2\] is the lexicographically largest valid sequence.

**Example 2:**

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

**Constraints:**

*   `1 <= n <= 20`

## A solution in Java

```java
public int[] constructDistancedSequence(int n) {
    int[] res = new int[2 * n - 1];
    dfs(res, 0, new boolean[n + 1]);
    return res;
}

private boolean dfs(int[] res, int i, boolean[] used) {
    if (i == res.length) {
        return true;
    }
    if (res[i] != 0) {
        return dfs(res, i + 1, used);
    }
    for (int num = used.length - 1; num > 0; num--) {
        if (!used[num] && (num == 1 || (i + num < res.length && res[i + num] == 0))) {
            res[i] = num;
            if (num > 1) {
                res[i + num] = num;
            }
            used[num] = true;
            if (dfs(res, i + 1, used)) {
                return true;
            }
            res[i] = 0;
            if (num > 1) {
                res[i + num] = 0;
            }
            used[num] = false;
        }
    }
    return false;
}
```
The algorithm is based on a depth-first search and backtracking. Create an empty result array `res` with a length of `2 * n - 1` and fill it with zeros. The `dfs` function takes two parameters: the current index `i` and a bitmask `unused` that represents the unused numbers from `1` to `n`. The bitmask is initialized as `(1 << (n + 1)) - 2`.

In the `dfs` function, if the current index `i` reaches the length of `res`, we've found a valid sequence and return `true`. If the current position of `res[i]` is already filled (non-zero), we move forward and call `dfs` recursively with `i + 1`.

For each remaining number from `n` down to `1`, we check if it is still unused by checking the corresponding bit in the `unused` bitmask. If the number is unused and either the number is `1` or there's available space in the result array to place it, we mark the positions in the result array and update the bitmask. We then call `dfs` recursively with `i + 1` and the updated bitmask. If the recursive call returns `true`, we've found a valid sequence and return `true` immediately.

If none of the remaining numbers can be placed, perform the backtracking by resetting the positions in the result array, undoing the bitmask changes, and then return `false`.

Call the `dfs` function initially with `0` as the starting index and the initialized `unused` bitmask. Finally, return the result array `res` as the lexicographically largest valid sequence.

## A solution in C++

```cpp
vector<int> constructDistancedSequence(int n) {
    vector<int> res(2 * n - 1, 0);
    function<bool(int,int)> dfs = [&](int i, int unused){
        if (i == res.size()) return true;
        if (res[i]) return dfs(i + 1, unused);
        for (int num = n; num > 0; --num) {
            if ((unused >> num) & 1) {
                if (num == 1 || i + num < res.size() && !res[i + num]) {
                    res[i] = num;
                    if (num > 1) res[i + num] = num;
                    if (dfs(i + 1, unused ^ (1 << num))) return true;
                    res[i] = 0;
                    if (num > 1) res[i + num] = 0;
                }
            }
        }
        return false;
    };
    dfs(0, (1 << (n + 1)) - 2);
    return res;
}
```
The algorithm is based on a depth-first search and backtracking. Create an empty result array `res` with a length of `2 * n - 1` and fill it with zeros. The `dfs` function takes two parameters: the current index `i` and a bitmask `unused` that represents the unused numbers from `1` to `n`. The bitmask is initialized as `(1 << (n + 1)) - 2`.

In the `dfs` function, if the current index `i` reaches the length of `res`, we've found a valid sequence and return `true`. If the current position of `res[i]` is already filled (non-zero), we move forward and call `dfs` recursively with `i + 1`.

For each remaining number from `n` down to `1`, we check if it is still unused by checking the corresponding bit in the `unused` bitmask. If the number is unused and either the number is `1` or there's available space in the result array to place it, we mark the positions in the result array and update the bitmask. We then call `dfs` recursively with `i + 1` and the updated bitmask. If the recursive call returns `true`, we've found a valid sequence and return `true` immediately.

If none of the remaining numbers can be placed, perform the backtracking by resetting the positions in the result array, undoing the bitmask changes, and then return `false`.

Call the `dfs` function initially with `0` as the starting index and the initialized `unused` bitmask. Finally, return the result array `res` as the lexicographically largest valid sequence.

## A solution in Python

```python
class Solution:
    def constructDistancedSequence(self, n: int) -> List[int]:
        res = [0] * (2 * n - 1)

        def backtrack(i, unused):
            if i == len(res):
                return True
            if res[i]:
                return backtrack(i + 1, unused)
            for num in range(n, 0, -1):
                if (unused >> num) & 1:
                    if num == 1 or (i + num < len(res) and not res[i + num]):
                        res[i] = num
                        if num > 1:
                            res[i + num] = num
                        if backtrack(i + 1, unused ^ (1 << num)):
                            return True
                        res[i] = 0
                        if num > 1:
                            res[i + num] = 0
            return False

        backtrack(0, (1 << (n + 1)) - 2)
        return res
```
The algorithm is based on a depth-first search and backtracking. Create an empty result array `res` with a length of `2 * n - 1` and fill it with zeros. The `dfs` function takes two parameters: the current index `i` and a bitmask `unused` that represents the unused numbers from `1` to `n`. The bitmask is initialized as `(1 << (n + 1)) - 2`.

In the `dfs` function, if the current index `i` reaches the length of `res`, we've found a valid sequence and return `true`. If the current position of `res[i]` is already filled (non-zero), we move forward and call `dfs` recursively with `i + 1`.

For each remaining number from `n` down to `1`, we check if it is still unused by checking the corresponding bit in the `unused` bitmask. If the number is unused and either the number is `1` or there's available space in the result array to place it, we mark the positions in the result array and update the bitmask. We then call `dfs` recursively with `i + 1` and the updated bitmask. If the recursive call returns `true`, we've found a valid sequence and return `true` immediately.

If none of the remaining numbers can be placed, perform the backtracking by resetting the positions in the result array, undoing the bitmask changes, and then return `false`.

Call the `dfs` function initially with `0` as the starting index and the initialized `unused` bitmask. Finally, return the result array `res` as the lexicographically largest valid sequence.

## A solution in Javascript

```javascript
var constructDistancedSequence = function(n) {
    const res = new Array(2 * n - 1).fill(0);

    function dfs(i, unused) {
        if (i === res.length) return true;
        if (res[i]) return dfs(i + 1, unused);
        for (let num = n; num > 0; num--) {
            if ((unused >> num) & 1) {
                if (num === 1 || i + num < res.length && !res[i + num]) {
                    res[i] = num;
                    if (num > 1) res[i + num] = num;
                    if (dfs(i + 1, unused ^ (1 << num))) return true;
                    res[i] = 0;
                    if (num > 1) res[i + num] = 0;
                }
            }
        }
        return false;
    }

    dfs(0, (1 << (n + 1)) - 2);
    return res;
};
```
The algorithm is based on a depth-first search and backtracking. Create an empty result array `res` with a length of `2 * n - 1` and fill it with zeros. The `dfs` function takes two parameters: the current index `i` and a bitmask `unused` that represents the unused numbers from `1` to `n`. The bitmask is initialized as `(1 << (n + 1)) - 2`.

In the `dfs` function, if the current index `i` reaches the length of `res`, we've found a valid sequence and return `true`. If the current position of `res[i]` is already filled (non-zero), we move forward and call `dfs` recursively with `i + 1`.

For each remaining number from `n` down to `1`, we check if it is still unused by checking the corresponding bit in the `unused` bitmask. If the number is unused and either the number is `1` or there's available space in the result array to place it, we mark the positions in the result array and update the bitmask. We then call `dfs` recursively with `i + 1` and the updated bitmask. If the recursive call returns `true`, we've found a valid sequence and return `true` immediately.

If none of the remaining numbers can be placed, perform the backtracking by resetting the positions in the result array, undoing the bitmask changes, and then return `false`.

Call the `dfs` function initially with `0` as the starting index and the initialized `unused` bitmask. Finally, return the result array `res` as the lexicographically largest valid sequence.


# Number Of Ways To Reconstruct A Tree

- slug: number-of-ways-to-reconstruct-a-tree
- difficulty: Hard

You are given an array `pairs`, where `pairs[i] = [xi, yi]`, and:

*   There are no duplicates.
*   `xi < yi`

Let `ways` be the number of rooted trees that satisfy the following conditions:

*   The tree consists of nodes whose values appeared in `pairs`.
*   A pair `[xi, yi]` exists in `pairs` **if and only if** `xi` is an ancestor of `yi` or `yi` is an ancestor of `xi`.
*   **Note:** the tree does not have to be a binary tree.

Two ways are considered to be different if there is at least one node that has different parents in both ways.

Return:

*   `0` if `ways == 0`
*   `1` if `ways == 1`
*   `2` if `ways > 1`

A **rooted tree** is a tree that has a single root node, and all edges are oriented to be outgoing from the root.

An **ancestor** of a node is any node on the path from the root to that node (excluding the node itself). The root has no ancestors.

**Example 1:**

**Input:** pairs = \[\[1,2\],\[2,3\]\]
**Output:** 1
**Explanation:** There is exactly one valid rooted tree, which is shown in the above figure.

**Example 2:**

**Input:** pairs = \[\[1,2\],\[2,3\],\[1,3\]\]
**Output:** 2
**Explanation:** There are multiple valid rooted trees. Three of them are shown in the above figures.

**Example 3:**

**Input:** pairs = \[\[1,2\],\[2,3\],\[2,4\],\[1,5\]\]
**Output:** 0
**Explanation:** There are no valid rooted trees.

**Constraints:**

*   `1 <= pairs.length <= 105`
*   `1 <= xi < yi <= 500`
*   The elements in `pairs` are unique.

## A solution in Java

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

public int checkWays(List<List<Integer>> pairs) {
    Map<Integer, Integer> candidates = new HashMap<>();
    for (List<Integer> pair : pairs) {
        candidates.put(pair.get(0),
                candidates.getOrDefault(pair.get(0), 0) + 1);
        candidates.put(pair.get(1),
                candidates.getOrDefault(pair.get(1), 0) + 1);
    }

    int rootCount = 0;
    for (int candidate : candidates.values()) {
        if (candidate == 1) {
            rootCount++;
            if (rootCount > 1) {
                return 2;
            }
        }
    }

    return rootCount;
}
```
The algorithm uses a hash map to count the occurrences of each node in the `pairs` array. After counting the occurrences, it iterates through the hash map and counts how many nodes have only a single occurrence, which implies that they could be the root of a tree. If there is more than one node with a single occurrence, it means that there are multiple ways to create trees; therefore, the function returns 2. If there is only one node with a single occurrence, there is only one way to create a tree; hence, the function returns 1. If there are no nodes with a single occurrence, the function returns 0, since we cannot create a tree. All implementations follow this algorithm for each language.

## A solution in C++

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

int checkWays(std::vector<std::vector<int>>& pairs) {
    std::unordered_map<int, int> candidates;
    for (const auto& pair : pairs) {
        ++candidates[pair[0]];
        ++candidates[pair[1]];
    }

    int rootCount = 0;
    for (const auto& candidate : candidates) {
        if (candidate.second == 1) {
            ++rootCount;
            if (rootCount > 1) {
                return 2;
            }
        }
    }

    return rootCount;
}
```
The algorithm uses a hash map to count the occurrences of each node in the `pairs` array. After counting the occurrences, it iterates through the hash map and counts how many nodes have only a single occurrence, which implies that they could be the root of a tree. If there is more than one node with a single occurrence, it means that there are multiple ways to create trees; therefore, the function returns 2. If there is only one node with a single occurrence, there is only one way to create a tree; hence, the function returns 1. If there are no nodes with a single occurrence, the function returns 0, since we cannot create a tree. All implementations follow this algorithm for each language.

## A solution in Python

```python
def check_ways(pairs):
    candidates = {}
    for x, y in pairs:
        candidates[x] = candidates.get(x, 0) + 1
        candidates[y] = candidates.get(y, 0) + 1

    root_count = sum(1 for v in candidates.values() if v == 1)
    return min(root_count, 2)
```
The algorithm uses a hash map to count the occurrences of each node in the `pairs` array. After counting the occurrences, it iterates through the hash map and counts how many nodes have only a single occurrence, which implies that they could be the root of a tree. If there is more than one node with a single occurrence, it means that there are multiple ways to create trees; therefore, the function returns 2. If there is only one node with a single occurrence, there is only one way to create a tree; hence, the function returns 1. If there are no nodes with a single occurrence, the function returns 0, since we cannot create a tree. All implementations follow this algorithm for each language.

## A solution in Javascript

```javascript
function checkWays(pairs) {
    const candidates = {};
    for (const [x, y] of pairs) {
        candidates[x] = (candidates[x] || 0) + 1;
        candidates[y] = (candidates[y] || 0) + 1;
    }

    let rootCount = 0;
    for (const candidate in candidates) {
        if (candidates[candidate] == 1) {
            rootCount++;
            if (rootCount > 1) {
                return 2;
            }
        }
    }

    return rootCount;
}
```
The algorithm uses a hash map to count the occurrences of each node in the `pairs` array. After counting the occurrences, it iterates through the hash map and counts how many nodes have only a single occurrence, which implies that they could be the root of a tree. If there is more than one node with a single occurrence, it means that there are multiple ways to create trees; therefore, the function returns 2. If there is only one node with a single occurrence, there is only one way to create a tree; hence, the function returns 1. If there are no nodes with a single occurrence, the function returns 0, since we cannot create a tree. All implementations follow this algorithm for each language.


# Decode XORed Array

- slug: decode-xored-array
- difficulty: Easy

There is a **hidden** integer array `arr` that consists of `n` non-negative integers.

It was encoded into another integer array `encoded` of length `n - 1`, such that `encoded[i] = arr[i] XOR arr[i + 1]`. For example, if `arr = [1,0,2,1]`, then `encoded = [1,2,3]`.

You are given the `encoded` array. You are also given an integer `first`, that is the first element of `arr`, i.e. `arr[0]`.

Return _the original array_ `arr`. It can be proved that the answer exists and is unique.

**Example 1:**

**Input:** encoded = \[1,2,3\], first = 1
**Output:** \[1,0,2,1\]
**Explanation:** If arr = \[1,0,2,1\], then first = 1 and encoded = \[1 XOR 0, 0 XOR 2, 2 XOR 1\] = \[1,2,3\]

**Example 2:**

**Input:** encoded = \[6,2,7,3\], first = 4
**Output:** \[4,2,0,7,4\]

**Constraints:**

*   `2 <= n <= 104`
*   `encoded.length == n - 1`
*   `0 <= encoded[i] <= 105`
*   `0 <= first <= 105`

## A solution in Java

```java
public int minOperations(String[] logs) {
    int depth = 0;
    for (String log : logs) {
        if (log.equals("../")) {
            if (depth > 0) {
                depth--;
            }
        } else if (!log.equals("./")) {
            depth++;
        }
    }
    return depth;
}
```
The algorithm maintains a variable `depth` to keep track of the current folder depth from the main folder. It starts from 0 (main folder) becuase the file system initially starts in the main folder. Then, it iterates through the `logs` list:

- If the log is "../", it means the operation is to go up one level, so we decrement the `depth` by 1. Note that we check if `depth` is greater than 0 to handle the situation where the current folder is already the main folder (we don't want to go above the main folder).
- If the log is not "./" (which means it's a sub-folder), it means the operation is to go down one level, so we increment the `depth` by 1.

After the loop, the value of `depth` represents the minimum number of operations needed to go back to the main folder, so we return it.

## A solution in C++

```cpp
int minOperations(vector<string>& logs) {
    int depth = 0;
    for (const string& log : logs) {
        if (log == "../") {
            if (depth > 0) {
                depth--;
            }
        } else if (log != "./") {
            depth++;
        }
    }
    return depth;
}
```
The algorithm maintains a variable `depth` to keep track of the current folder depth from the main folder. It starts from 0 (main folder) becuase the file system initially starts in the main folder. Then, it iterates through the `logs` list:

- If the log is "../", it means the operation is to go up one level, so we decrement the `depth` by 1. Note that we check if `depth` is greater than 0 to handle the situation where the current folder is already the main folder (we don't want to go above the main folder).
- If the log is not "./" (which means it's a sub-folder), it means the operation is to go down one level, so we increment the `depth` by 1.

After the loop, the value of `depth` represents the minimum number of operations needed to go back to the main folder, so we return it.

## A solution in Python

```python
def minOperations(logs):
    depth = 0
    for log in logs:
        if log == "../":
            if depth > 0:
                depth -= 1
        elif log != "./":
            depth += 1
    return depth
```
The algorithm maintains a variable `depth` to keep track of the current folder depth from the main folder. It starts from 0 (main folder) becuase the file system initially starts in the main folder. Then, it iterates through the `logs` list:

- If the log is "../", it means the operation is to go up one level, so we decrement the `depth` by 1. Note that we check if `depth` is greater than 0 to handle the situation where the current folder is already the main folder (we don't want to go above the main folder).
- If the log is not "./" (which means it's a sub-folder), it means the operation is to go down one level, so we increment the `depth` by 1.

After the loop, the value of `depth` represents the minimum number of operations needed to go back to the main folder, so we return it.

## A solution in Javascript

```javascript
function minOperations(logs) {
    let depth = 0;
    for (const log of logs) {
        if (log === "../") {
            if (depth > 0) {
                depth--;
            }
        } else if (log !== "./") {
            depth++;
        }
    }
    return depth;
}
```
The algorithm maintains a variable `depth` to keep track of the current folder depth from the main folder. It starts from 0 (main folder) becuase the file system initially starts in the main folder. Then, it iterates through the `logs` list:

- If the log is "../", it means the operation is to go up one level, so we decrement the `depth` by 1. Note that we check if `depth` is greater than 0 to handle the situation where the current folder is already the main folder (we don't want to go above the main folder).
- If the log is not "./" (which means it's a sub-folder), it means the operation is to go down one level, so we increment the `depth` by 1.

After the loop, the value of `depth` represents the minimum number of operations needed to go back to the main folder, so we return it.


# Swapping Nodes in a Linked List

- slug: swapping-nodes-in-a-linked-list
- difficulty: Medium

You are given the `head` of a linked list, and an integer `k`.

Return _the head of the linked list after **swapping** the values of the_ `kth` _node from the beginning and the_ `kth` _node from the end (the list is **1-indexed**)._

**Example 1:**

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

**Example 2:**

**Input:** head = \[7,9,6,6,7,8,3,0,9,5\], k = 5
**Output:** \[7,9,6,6,8,7,3,0,9,5\]

**Constraints:**

*   The number of nodes in the list is `n`.
*   `1 <= k <= n <= 105`
*   `0 <= Node.val <= 100`

## A solution in Java

```java
public int minOperationsMaxProfit(int[] customers, int boardingCost, int runningCost) {
    int rotations = 0, waiting = 0, onBoard, profit = 0, maxProfit = 0, maxRotations = 0;
    int idx = 0;
    while (idx < customers.length || waiting > 0) {
        if (idx < customers.length) {
            waiting += customers[idx];
            idx++;
        }

        onBoard = Math.min(waiting, 4);
        waiting -= onBoard;
        profit += onBoard * boardingCost - runningCost;
        rotations++;

        if (profit > maxProfit) {
            maxProfit = profit;
            maxRotations = rotations;
        }
    }
    return maxProfit > 0 ? maxRotations : -1;
}
```
1. Initialize necessary variables for counting rotations, waiting customers, onboard customers, profit, max profit and rotations for max profit.
2. Iterate while there are still customers in the given list or there are customers waiting.
3. If there are customers in the list, dequeue the first item and add it to the waiting customers.
4. Calculate how many customers can board (minimum of waiting customers and 4) and update the numbers of waiting customers and profit accordingly.
5. Increment the rotations counter.
6. Update max profit and rotations for max profit if the current profit is greater than the max profit.
7. When the loop finishes, check if the max profit is positive. If it is, return rotations for max profit, otherwise, return -1.

## A solution in C++

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

int minOperationsMaxProfit(vector<int>& customers, int boardingCost, int runningCost) {
    int rotations = 0, waiting = 0, onBoard = 0, profit = 0, maxProfit = 0, maxRotations = 0;
    while (!customers.empty() || waiting > 0) {
        if (!customers.empty()) {
            waiting += customers.front();
            customers.erase(customers.begin());
        }

        onBoard = min(waiting, 4);
        waiting -= onBoard;
        profit += onBoard * boardingCost - runningCost;
        rotations++;

        if (profit > maxProfit) {
            maxProfit = profit;
            maxRotations = rotations;
        }
    }
    return maxProfit > 0 ? maxRotations : -1;
}
```
1. Initialize necessary variables for counting rotations, waiting customers, onboard customers, profit, max profit and rotations for max profit.
2. Iterate while there are still customers in the given list or there are customers waiting.
3. If there are customers in the list, dequeue the first item and add it to the waiting customers.
4. Calculate how many customers can board (minimum of waiting customers and 4) and update the numbers of waiting customers and profit accordingly.
5. Increment the rotations counter.
6. Update max profit and rotations for max profit if the current profit is greater than the max profit.
7. When the loop finishes, check if the max profit is positive. If it is, return rotations for max profit, otherwise, return -1.

## A solution in Python

```python
def min_operations_max_profit(customers, boarding_cost, running_cost):
    rotations = waiting = on_board = profit = max_profit = max_rotations = 0
    while customers or waiting > 0:
        if customers:
            waiting += customers.pop(0)

        on_board = min(waiting, 4)
        waiting -= on_board
        profit += on_board * boarding_cost - running_cost
        rotations += 1

        if profit > max_profit:
            max_profit = profit
            max_rotations = rotations

    return max_rotations if max_profit > 0 else -1
```
1. Initialize necessary variables for counting rotations, waiting customers, onboard customers, profit, max profit and rotations for max profit.
2. Iterate while there are still customers in the given list or there are customers waiting.
3. If there are customers in the list, dequeue the first item and add it to the waiting customers.
4. Calculate how many customers can board (minimum of waiting customers and 4) and update the numbers of waiting customers and profit accordingly.
5. Increment the rotations counter.
6. Update max profit and rotations for max profit if the current profit is greater than the max profit.
7. When the loop finishes, check if the max profit is positive. If it is, return rotations for max profit, otherwise, return -1.

## A solution in Javascript

```javascript
function minOperationsMaxProfit(customers, boardingCost, runningCost) {
    let rotations = 0, waiting = 0, onBoard = 0, profit = 0, maxProfit = 0, maxRotations = 0;
    while (customers.length > 0 || waiting > 0) {
        if (customers.length > 0) {
            waiting += customers.shift();
        }

        onBoard = Math.min(waiting, 4);
        waiting -= onBoard;
        profit += onBoard * boardingCost - runningCost;
        rotations++;

        if (profit > maxProfit) {
            maxProfit = profit;
            maxRotations = rotations;
        }
    }
    return maxProfit > 0 ? maxRotations : -1;
}
```
1. Initialize necessary variables for counting rotations, waiting customers, onboard customers, profit, max profit and rotations for max profit.
2. Iterate while there are still customers in the given list or there are customers waiting.
3. If there are customers in the list, dequeue the first item and add it to the waiting customers.
4. Calculate how many customers can board (minimum of waiting customers and 4) and update the numbers of waiting customers and profit accordingly.
5. Increment the rotations counter.
6. Update max profit and rotations for max profit if the current profit is greater than the max profit.
7. When the loop finishes, check if the max profit is positive. If it is, return rotations for max profit, otherwise, return -1.


# Minimize Hamming Distance After Swap Operations

- slug: minimize-hamming-distance-after-swap-operations
- difficulty: Medium

You are given two integer arrays, `source` and `target`, both of length `n`. You are also given an array `allowedSwaps` where each `allowedSwaps[i] = [ai, bi]` indicates that you are allowed to swap the elements at index `ai` and index `bi` **(0-indexed)** of array `source`. Note that you can swap elements at a specific pair of indices **multiple** times and in **any** order.

The **Hamming distance** of two arrays of the same length, `source` and `target`, is the number of positions where the elements are different. Formally, it is the number of indices `i` for `0 <= i <= n-1` where `source[i] != target[i]` **(0-indexed)**.

Return _the **minimum Hamming distance** of_ `source` _and_ `target` _after performing **any** amount of swap operations on array_ `source`_._

**Example 1:**

**Input:** source = \[1,2,3,4\], target = \[2,1,4,5\], allowedSwaps = \[\[0,1\],\[2,3\]\]
**Output:** 1
**Explanation:** source can be transformed the following way:
- Swap indices 0 and 1: source = \[2,1,3,4\]
- Swap indices 2 and 3: source = \[2,1,4,3\]
The Hamming distance of source and target is 1 as they differ in 1 position: index 3.

**Example 2:**

**Input:** source = \[1,2,3,4\], target = \[1,3,2,4\], allowedSwaps = \[\]
**Output:** 2
**Explanation:** There are no allowed swaps.
The Hamming distance of source and target is 2 as they differ in 2 positions: index 1 and index 2.

**Example 3:**

**Input:** source = \[5,1,2,4,3\], target = \[1,5,4,2,3\], allowedSwaps = \[\[0,4\],\[4,2\],\[1,3\],\[1,4\]\]
**Output:** 0

**Constraints:**

*   `n == source.length == target.length`
*   `1 <= n <= 105`
*   `1 <= source[i], target[i] <= 105`
*   `0 <= allowedSwaps.length <= 105`
*   `allowedSwaps[i].length == 2`
*   `0 <= ai, bi <= n - 1`
*   `ai != bi`

## A solution in Java

```java
import java.util.*;

class ThroneInheritance {
    Map<String, List<String>> children = new HashMap<>();
    Map<String, Boolean> alive = new HashMap<>();
    String king;

    public ThroneInheritance(String kingName) {
        king = kingName;
        alive.put(kingName, true);
    }

    public void birth(String parentName, String childName) {
        children.computeIfAbsent(parentName, k -> new ArrayList<>()).add(childName);
        alive.put(childName, true);
    }

    public void death(String name) {
        alive.put(name, false);
    }

    public List<String> getInheritanceOrder() {
        List<String> order = new ArrayList<>();
        getSuccessor(king, order);
        return order;
    }

    private void getSuccessor(String name, List<String> order) {
        if (alive.get(name)) {
            order.add(name);
        }
        for (String child : children.getOrDefault(name, new ArrayList<>())) {
            getSuccessor(child, order);
        }
    }
}
```
The algorithm uses a hash map to store the parent-child relationships and another hash map to store whether each person is alive or dead. It keeps track of the current king's name.

When a child is born, add the child's name to the parent's children list, and set the child's alive status as true. When a person dies, change their alive status to false.

To find the inheritance order, start with the king as the first in the order. Recursively call the `getSuccessor` function, which, given a person's name and the inheritance order so far, returns who should be the next person after the given person in the order of inheritance. If the given person is alive, add them to the inheritance order. Then, for each child of the given person, call `getSuccessor` again.

This algorithm ensures that the kingdom has a well-defined order of inheritance as it recursively traverses the family tree in a depth-first manner, honoring the order of the children for each parent.

## A solution in C++

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

class ThroneInheritance {
    unordered_map<string, vector<string>> children;
    unordered_map<string, bool> alive;
    string king;
public:
    ThroneInheritance(string kingName) : king(kingName) {
        alive[kingName] = true;
    }

    void birth(string parentName, string childName) {
        children[parentName].push_back(childName);
        alive[childName] = true;
    }

    void death(string name) {
        alive[name] = false;
    }

    vector<string> getInheritanceOrder() {
        vector<string> order;
        getSuccessor(king, order);
        return order;
    }

    void getSuccessor(string name, vector<string>& order) {
        if (alive[name]) {
            order.push_back(name);
        }
        for (const auto& child : children[name]) {
            getSuccessor(child, order);
        }
    }
};
```
The algorithm uses a hash map to store the parent-child relationships and another hash map to store whether each person is alive or dead. It keeps track of the current king's name.

When a child is born, add the child's name to the parent's children list, and set the child's alive status as true. When a person dies, change their alive status to false.

To find the inheritance order, start with the king as the first in the order. Recursively call the `getSuccessor` function, which, given a person's name and the inheritance order so far, returns who should be the next person after the given person in the order of inheritance. If the given person is alive, add them to the inheritance order. Then, for each child of the given person, call `getSuccessor` again.

This algorithm ensures that the kingdom has a well-defined order of inheritance as it recursively traverses the family tree in a depth-first manner, honoring the order of the children for each parent.

## A solution in Python

```python
class ThroneInheritance:
    def __init__(self, kingName: str):
        self.children = {}
        self.alive = {kingName: True}
        self.king = kingName

    def birth(self, parentName: str, childName: str):
        if parentName not in self.children:
            self.children[parentName] = []
        self.children[parentName].append(childName)
        self.alive[childName] = True

    def death(self, name: str):
        self.alive[name] = False

    def getInheritanceOrder(self):
        order = []
        self.getSuccessor(self.king, order)
        return order

    def getSuccessor(self, name: str, order: list):
        if self.alive[name]:
            order.append(name)
        for child in self.children.get(name, []):
            self.getSuccessor(child, order)
```
The algorithm uses a hash map to store the parent-child relationships and another hash map to store whether each person is alive or dead. It keeps track of the current king's name.

When a child is born, add the child's name to the parent's children list, and set the child's alive status as true. When a person dies, change their alive status to false.

To find the inheritance order, start with the king as the first in the order. Recursively call the `getSuccessor` function, which, given a person's name and the inheritance order so far, returns who should be the next person after the given person in the order of inheritance. If the given person is alive, add them to the inheritance order. Then, for each child of the given person, call `getSuccessor` again.

This algorithm ensures that the kingdom has a well-defined order of inheritance as it recursively traverses the family tree in a depth-first manner, honoring the order of the children for each parent.

## A solution in Javascript

```javascript
class ThroneInheritance {
    constructor(kingName) {
        this.children = {};
        this.alive = {[kingName]: true};
        this.king = kingName;
    }

    birth(parentName, childName) {
        if (!this.children[parentName]) {
            this.children[parentName] = [];
        }
        this.children[parentName].push(childName);
        this.alive[childName] = true;
    }

    death(name) {
        this.alive[name] = false;
    }

    getInheritanceOrder() {
        const order = [];
        this.getSuccessor(this.king, order);
        return order;
    }

    getSuccessor(name, order) {
        if (this.alive[name]) {
            order.push(name);
        }
        if (this.children[name]) {
            for (const child of this.children[name]) {
                this.getSuccessor(child, order);
            }
        }
    }
}
```
The algorithm uses a hash map to store the parent-child relationships and another hash map to store whether each person is alive or dead. It keeps track of the current king's name.

When a child is born, add the child's name to the parent's children list, and set the child's alive status as true. When a person dies, change their alive status to false.

To find the inheritance order, start with the king as the first in the order. Recursively call the `getSuccessor` function, which, given a person's name and the inheritance order so far, returns who should be the next person after the given person in the order of inheritance. If the given person is alive, add them to the inheritance order. Then, for each child of the given person, call `getSuccessor` again.

This algorithm ensures that the kingdom has a well-defined order of inheritance as it recursively traverses the family tree in a depth-first manner, honoring the order of the children for each parent.


# Find Minimum Time to Finish All Jobs

- slug: find-minimum-time-to-finish-all-jobs
- difficulty: Hard

You are given an integer array `jobs`, where `jobs[i]` is the amount of time it takes to complete the `ith` job.

There are `k` workers that you can assign jobs to. Each job should be assigned to **exactly** one worker. The **working time** of a worker is the sum of the time it takes to complete all jobs assigned to them. Your goal is to devise an optimal assignment such that the **maximum working time** of any worker is **minimized**.

_Return the **minimum** possible **maximum working time** of any assignment._

**Example 1:**

**Input:** jobs = \[3,2,3\], k = 3
**Output:** 3
**Explanation:** By assigning each person one job, the maximum time is 3.

**Example 2:**

**Input:** jobs = \[1,2,4,7,8\], k = 2
**Output:** 11
**Explanation:** Assign the jobs the following way:
Worker 1: 1, 2, 8 (working time = 1 + 2 + 8 = 11)
Worker 2: 4, 7 (working time = 4 + 7 = 11)
The maximum working time is 11.

**Constraints:**

*   `1 <= k <= jobs.length <= 12`
*   `1 <= jobs[i] <= 107`

## A solution in Java

```java
import java.util.ArrayList;

public int maxAchievableRequests(int n, ArrayList<ArrayList<Integer>> requests, int idx, ArrayList<Integer> counts) {
    if (counts == null) {
        counts = new ArrayList<Integer>(n);
        for (int i = 0; i < n; i++) {
            counts.add(0);
        }
    }
    if (idx == requests.size()) {
        for (int count : counts) {
            if (count != 0) return 0;
        }
        return 0;
    }
    int ignored = maxAchievableRequests(n, requests, idx + 1, counts);
    counts.set(requests.get(idx).get(0), counts.get(requests.get(idx).get(0)) + 1);
    counts.set(requests.get(idx).get(1), counts.get(requests.get(idx).get(1)) - 1);

    int accepted = 1 + maxAchievableRequests(n, requests, idx + 1, counts);

    return Math.max(ignored, accepted);
}
```
The algorithm uses a helper recursive function `max_achievable_requests` that keeps track of four variables:
- `n`: the number of buildings
- `requests`: the list of employee transfer requests
- `idx`: the index of the current request being processed (default is 0 for the start)
- `counts`: a list that holds the net change in employee transfers for each building (initially empty or None/null)

It uses a base case when `idx` is equal to the length of the `request` list; it checks if all the counts are balanced (all values in the `counts` array are 0). If the counts are balanced, it means all requests have been checked and return 0 as the value of the maximum achievable requests.

If the index is not at the end of the requests list, two options are tried: ignore the request and process the next request in the list, and accept the request and process the next request in the list. For each try, it updates the counts based on the current request and chooses the maximum of the combinations tried.

The time complexity of this algorithm is O(2^n) as it uses a depth-first search approach. It is inefficient for large inputs, but in the context of the question, it should work well to find the maximum number of achievable requests.

## A solution in C++

```cpp
#include <vector>

int maxAchievableRequests(int n, std::vector<std::vector<int>>& requests, int idx = 0, std::vector<int> counts = {}) {
    if (counts.empty()) {
        counts.resize(n, 0);
    }
    if (idx == requests.size()) {
        for (int count : counts) {
            if (count != 0) return 0;
        }
        return 0;
    }
    int ignored = maxAchievableRequests(n, requests, idx + 1, counts);
    counts[requests[idx][0]]++;
    counts[requests[idx][1]]--;

    int accepted = 1 + maxAchievableRequests(n, requests, idx + 1, counts);

    return std::max(ignored, accepted);
}
```
The algorithm uses a helper recursive function `max_achievable_requests` that keeps track of four variables:
- `n`: the number of buildings
- `requests`: the list of employee transfer requests
- `idx`: the index of the current request being processed (default is 0 for the start)
- `counts`: a list that holds the net change in employee transfers for each building (initially empty or None/null)

It uses a base case when `idx` is equal to the length of the `request` list; it checks if all the counts are balanced (all values in the `counts` array are 0). If the counts are balanced, it means all requests have been checked and return 0 as the value of the maximum achievable requests.

If the index is not at the end of the requests list, two options are tried: ignore the request and process the next request in the list, and accept the request and process the next request in the list. For each try, it updates the counts based on the current request and chooses the maximum of the combinations tried.

The time complexity of this algorithm is O(2^n) as it uses a depth-first search approach. It is inefficient for large inputs, but in the context of the question, it should work well to find the maximum number of achievable requests.

## A solution in Python

```python
def max_achievable_requests(n, requests, idx=0, counts=None):
    if counts is None:
        counts = [0] * n
    if idx == len(requests):
        if all(count == 0 for count in counts):
            return 0
        return 0

    ignored = max_achievable_requests(n, requests, idx+1, counts[:])
    counts[requests[idx][0]] += 1
    counts[requests[idx][1]] -= 1

    accepted = 1 + max_achievable_requests(n, requests, idx+1, counts)

    return max(ignored, accepted)
```
The algorithm uses a helper recursive function `max_achievable_requests` that keeps track of four variables:
- `n`: the number of buildings
- `requests`: the list of employee transfer requests
- `idx`: the index of the current request being processed (default is 0 for the start)
- `counts`: a list that holds the net change in employee transfers for each building (initially empty or None/null)

It uses a base case when `idx` is equal to the length of the `request` list; it checks if all the counts are balanced (all values in the `counts` array are 0). If the counts are balanced, it means all requests have been checked and return 0 as the value of the maximum achievable requests.

If the index is not at the end of the requests list, two options are tried: ignore the request and process the next request in the list, and accept the request and process the next request in the list. For each try, it updates the counts based on the current request and chooses the maximum of the combinations tried.

The time complexity of this algorithm is O(2^n) as it uses a depth-first search approach. It is inefficient for large inputs, but in the context of the question, it should work well to find the maximum number of achievable requests.

## A solution in Javascript

```javascript
function maxAchievableRequests(n, requests, idx = 0, counts = null) {
    if (counts === null) {
        counts = new Array(n).fill(0);
    }
    if (idx === requests.length) {
        if (counts.every(count => count === 0)) return 0;
        return 0;
    }
    let ignored = maxAchievableRequests(n, requests, idx + 1, [...counts]);
    counts[requests[idx][0]]++;
    counts[requests[idx][1]]--;

    let accepted = 1 + maxAchievableRequests(n, requests, idx + 1, counts);

    return Math.max(ignored, accepted);
}
```
The algorithm uses a helper recursive function `max_achievable_requests` that keeps track of four variables:
- `n`: the number of buildings
- `requests`: the list of employee transfer requests
- `idx`: the index of the current request being processed (default is 0 for the start)
- `counts`: a list that holds the net change in employee transfers for each building (initially empty or None/null)

It uses a base case when `idx` is equal to the length of the `request` list; it checks if all the counts are balanced (all values in the `counts` array are 0). If the counts are balanced, it means all requests have been checked and return 0 as the value of the maximum achievable requests.

If the index is not at the end of the requests list, two options are tried: ignore the request and process the next request in the list, and accept the request and process the next request in the list. For each try, it updates the counts based on the current request and chooses the maximum of the combinations tried.

The time complexity of this algorithm is O(2^n) as it uses a depth-first search approach. It is inefficient for large inputs, but in the context of the question, it should work well to find the maximum number of achievable requests.