# Path with Maximum Gold

- slug: path-with-maximum-gold
- difficulty: Medium

In a gold mine `grid` of size `m x n`, each cell in this mine has an integer representing the amount of gold in that cell, `0` if it is empty.

Return the maximum amount of gold you can collect under the conditions:

*   Every time you are located in a cell you will collect all the gold in that cell.
*   From your position, you can walk one step to the left, right, up, or down.
*   You can't visit the same cell more than once.
*   Never visit a cell with `0` gold.
*   You can start and stop collecting gold from **any** position in the grid that has some gold.

**Example 1:**

**Input:** grid = \[\[0,6,0\],\[5,8,7\],\[0,9,0\]\]
**Output:** 24
**Explanation:**
\[\[0,6,0\],
 \[5,8,7\],
 \[0,9,0\]\]
Path to get the maximum gold, 9 -> 8 -> 7.

**Example 2:**

**Input:** grid = \[\[1,0,7\],\[2,0,6\],\[3,4,5\],\[0,3,0\],\[9,0,20\]\]
**Output:** 28
**Explanation:**
\[\[1,0,7\],
 \[2,0,6\],
 \[3,4,5\],
 \[0,3,0\],
 \[9,0,20\]\]
Path to get the maximum gold, 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7.

**Constraints:**

*   `m == grid.length`
*   `n == grid[i].length`
*   `1 <= m, n <= 15`
*   `0 <= grid[i][j] <= 100`
*   There are at most **25** cells containing gold.

## A solution in Java

```java
import java.util.HashMap;

public int longestWPI(int[] hours) {
    int score = 0;
    int maxLength = 0;
    HashMap<Integer, Integer> firstOccurrence = new HashMap<>();

    for (int i = 0; i < hours.length; ++i) {
        score += hours[i] > 8 ? 1 : -1;
        if (score > 0) maxLength = i + 1;
        else {
            firstOccurrence.putIfAbsent(score, i);
            if (firstOccurrence.containsKey(score - 1))
                maxLength = Math.max(maxLength, i - firstOccurrence.get(score - 1));
        }
    }
    return maxLength;
}
```
The algorithm uses a single pass over the `hours` array, keeping track of a `score` which increases by 1 for every tiring day, and decreases by 1 for every non-tiring day. Whenever the score is positive, we set maxLength to the current index plus one. If the score turns negative or remains negative, we store the index of first occurrence of the score in a hash map, and check if a score minus one is present in the map, if yes, we have an interval with more tiring days than non-tiring days, so we update maxLength if it's more than the current maxLength.

## A solution in C++

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

int longestWPI(std::vector<int>& hours) {
    int score = 0;
    int maxLength = 0;
    std::unordered_map<int, int> firstOccurrence;

    for (int i = 0; i < hours.size(); ++i) {
        score += hours[i] > 8 ? 1 : -1;
        if (score > 0) maxLength = i + 1;
        else {
             if (firstOccurrence.find(score) == firstOccurrence.end())
                firstOccurrence[score] = i;
             if (firstOccurrence.find(score - 1) != firstOccurrence.end())
                maxLength = std::max(maxLength, i - firstOccurrence[score - 1]);
        }
    }
    return maxLength;
}
```
The algorithm uses a single pass over the `hours` array, keeping track of a `score` which increases by 1 for every tiring day, and decreases by 1 for every non-tiring day. Whenever the score is positive, we set maxLength to the current index plus one. If the score turns negative or remains negative, we store the index of first occurrence of the score in a hash map, and check if a score minus one is present in the map, if yes, we have an interval with more tiring days than non-tiring days, so we update maxLength if it's more than the current maxLength.

## A solution in Python

```python
def longest_wpi(hours):
    score = 0
    max_length = 0
    first_occurrence = {}

    for i, h in enumerate(hours):
        score += 1 if h > 8 else -1
        if score > 0:
            max_length = i + 1
        else:
            if score not in first_occurrence:
                first_occurrence[score] = i
            if score - 1 in first_occurrence:
                max_length = max(max_length, i - first_occurrence[score - 1])
    return max_length
```
The algorithm uses a single pass over the `hours` array, keeping track of a `score` which increases by 1 for every tiring day, and decreases by 1 for every non-tiring day. Whenever the score is positive, we set maxLength to the current index plus one. If the score turns negative or remains negative, we store the index of first occurrence of the score in a hash map, and check if a score minus one is present in the map, if yes, we have an interval with more tiring days than non-tiring days, so we update maxLength if it's more than the current maxLength.

## A solution in Javascript

```javascript
function longestWPI(hours) {
    let score = 0;
    let maxLength = 0;
    let firstOccurrence = new Map();

    for (let i = 0; i < hours.length; ++i) {
        score += hours[i] > 8 ? 1 : -1;
        if (score > 0) maxLength = i + 1;
        else {
            if (!firstOccurrence.has(score))
                firstOccurrence.set(score, i);
            if (firstOccurrence.has(score - 1))
                maxLength = Math.max(maxLength, i - firstOccurrence.get(score - 1));
        }
    }
    return maxLength;
}
```
The algorithm uses a single pass over the `hours` array, keeping track of a `score` which increases by 1 for every tiring day, and decreases by 1 for every non-tiring day. Whenever the score is positive, we set maxLength to the current index plus one. If the score turns negative or remains negative, we store the index of first occurrence of the score in a hash map, and check if a score minus one is present in the map, if yes, we have an interval with more tiring days than non-tiring days, so we update maxLength if it's more than the current maxLength.


# Count Vowels Permutation

- slug: count-vowels-permutation
- difficulty: Hard

Given an integer `n`, your task is to count how many strings of length `n` can be formed under the following rules:

*   Each character is a lower case vowel (`'a'`, `'e'`, `'i'`, `'o'`, `'u'`)
*   Each vowel `'a'` may only be followed by an `'e'`.
*   Each vowel `'e'` may only be followed by an `'a'` or an `'i'`.
*   Each vowel `'i'` **may not** be followed by another `'i'`.
*   Each vowel `'o'` may only be followed by an `'i'` or a `'u'`.
*   Each vowel `'u'` may only be followed by an `'a'.`

Since the answer may be too large, return it modulo `10^9 + 7.`

**Example 1:**

**Input:** n = 1
**Output:** 5
**Explanation:** All possible strings are:  "a ",  "e ",  "i " ,  "o " and  "u ".

**Example 2:**

**Input:** n = 2
**Output:** 10
**Explanation:** All possible strings are:  "ae ",  "ea ",  "ei ",  "ia ",  "ie ",  "io ",  "iu ",  "oi ",  "ou " and  "ua ".

**Example 3:**

**Input:** n = 5
**Output:** 68

**Constraints:**

*   `1 <= n <= 2 * 10^4`

## A solution in Java

```java
import java.util.*;

class Solution {
    public int[] smallestSufficientTeam(String[] req_skills, List<List<String>> people) {
        Map<String, Integer> index = new HashMap<>();
        int num_skills = req_skills.length;
        for (int i = 0; i < num_skills; i++) {
            index.put(req_skills[i], i);
        }

        List<Integer> sks = new ArrayList<>();
        for (int i = 0; i < people.size(); i++) {
            int cur = 0;
            for (String s : people.get(i)) {
                cur |= 1 << index.get(s);
            }
            sks.add(cur);
        }

        int INF = 64;
        int[] dp = new int[1 << num_skills];
        int[] parent = new int[1 << num_skills];
        Arrays.fill(dp, INF);
        dp[0] = 0;

        for (int i = 0; i < people.size(); i++) {
            int hiskills = sks.get(i);
            for (int done = (1 << num_skills) - 1; done >= 0; done--) {
                int withhim = done | hiskills;
                if (dp[withhim] > dp[done] + 1) {
                    dp[withhim] = dp[done] + 1;
                    parent[withhim] = done;
                }
            }
        }

        int[] ans = new int[dp[(1 << num_skills) - 1]];
        int cur = (1 << num_skills) - 1;
        int t = dp[(1 << num_skills) - 1] - 1;

        for (int i = people.size() - 1; i >= 0; i--) {
            int old = parent[cur];
            int diff = cur ^ old;
            boolean isEssential = (sks.get(i) & diff) > 0;
            if (isEssential) {
                ans[t] = i;
                t--;
            }
            cur = old;
        }
        return ans;
    }
}
```
The algorithm can be described as follows:

1. Create a map of each required skill to a unique integer (0-indexed).
2. Convert the people's skills into integers using bitwise operations, where each bit represents whether the person has a particular skill or not.
3. Use dynamic programming to find the smallest sufficient team. For each person in the list, iterate through all possible skill subsets (done by looping from (2^n - 1) to 0, where n is the number of required skills) and calculate the skill set with the current person.
4. If the team size with the current person is smaller than the previously known team size without the person for the same skill set, update the dynamic programming table with the new team size and store the parent state.
5. Finally, iterate through the parent state array to reconstruct the team and return the indices of the team members.

The time complexity of the algorithm is O(people * 2^req_skills). As req_skills is guaranteed to be at most 16, the time complexity is at most O(60 * 2^16), which is enough for the constraints in the problem statement.

## A solution in C++

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

vector<int> smallestSufficientTeam(vector<string>& req_skills, vector<vector<string>>& people) {
    int n = req_skills.size(), m = people.size();
    vector<int> skill_to_int(128, -1);
    vector<vector<int>> people_int(m);
    vector<int> res(n);
    int cur_min = n + 1;

    for (int i = 0; i < n; ++i) skill_to_int[req_skills[i].front()] = i;

    for (int i = 0; i < m; ++i)
        for (const string& s : people[i]) people_int[i].push_back(skill_to_int[s.front()]);

    function<void(bitset<26>, int, int)> dfs = [&](bitset<26> s, int p, int count) {
        if (count >= cur_min) return;
        if (p == m && (s & ((1 << n) - 1)) != (1 << n) - 1) return;
        if (p == m) {
            cur_min = count;
            int idx = 0;
            for (int i = 0; i < m; ++i) if (s[26 - i - 1]) res[idx++] = i;
            return;
    }
        dfs(s | (s >> people_int[p]) | (s << n << people_int[p]), p + 1, count + 1);
        dfs(s, p + 1, count);
    };

    dfs(0, 0, 0);
    res.resize(cur_min);
    return res;
}
```
The algorithm can be described as follows:

1. Create a map of each required skill to a unique integer (0-indexed).
2. Convert the people's skills into integers using bitwise operations, where each bit represents whether the person has a particular skill or not.
3. Use dynamic programming to find the smallest sufficient team. For each person in the list, iterate through all possible skill subsets (done by looping from (2^n - 1) to 0, where n is the number of required skills) and calculate the skill set with the current person.
4. If the team size with the current person is smaller than the previously known team size without the person for the same skill set, update the dynamic programming table with the new team size and store the parent state.
5. Finally, iterate through the parent state array to reconstruct the team and return the indices of the team members.

The time complexity of the algorithm is O(people * 2^req_skills). As req_skills is guaranteed to be at most 16, the time complexity is at most O(60 * 2^16), which is enough for the constraints in the problem statement.

## A solution in Python

```python
from typing import List

def smallestSufficientTeam(req_skills: List[str], people: List[List[str]]) -> List[int]:
    skill_to_int = {s: i for i, s in enumerate(req_skills)}
    people_skills = [sum(1 << skill_to_int[skill] for skill in person) for person in people]

    n = len(req_skills)
    INF = 64
    dp = [INF] * (1 << n)
    dp[0] = 0
    parent = [None] * (1 << n)

    for i, person_skills in enumerate(people_skills):
        for completed_skills in range((1 << n) - 1, -1, -1):
            with_person_skills = completed_skills | person_skills
            if dp[with_person_skills] > dp[completed_skills] + 1:
                dp[with_person_skills] = dp[completed_skills] + 1
                parent[with_person_skills] = completed_skills

    ans = [0] * dp[-1]
    cur = (1 << n) - 1
    t = dp[-1] - 1

    for i in range(len(people) - 1, -1, -1):
        old = parent[cur]
        diff = cur ^ old
        is_essential = (people_skills[i] & diff) > 0
        if is_essential:
            ans[t] = i
            t -= 1
        cur = old
    return ans
```
The algorithm can be described as follows:

1. Create a map of each required skill to a unique integer (0-indexed).
2. Convert the people's skills into integers using bitwise operations, where each bit represents whether the person has a particular skill or not.
3. Use dynamic programming to find the smallest sufficient team. For each person in the list, iterate through all possible skill subsets (done by looping from (2^n - 1) to 0, where n is the number of required skills) and calculate the skill set with the current person.
4. If the team size with the current person is smaller than the previously known team size without the person for the same skill set, update the dynamic programming table with the new team size and store the parent state.
5. Finally, iterate through the parent state array to reconstruct the team and return the indices of the team members.

The time complexity of the algorithm is O(people * 2^req_skills). As req_skills is guaranteed to be at most 16, the time complexity is at most O(60 * 2^16), which is enough for the constraints in the problem statement.

## A solution in Javascript

```javascript
function smallestSufficientTeam(req_skills, people) {
    const skill_to_int = new Map()
    req_skills.forEach((v, i) => skill_to_int.set(v, i))

    const people_int = people.map(person =>
        person.reduce((skills, p) => skills | 1 << skill_to_int.get(p), 0)
    )

    const n = req_skills.length
    const INF = 64
    const dp = Array(1 << n).fill(INF)
    const parent = Array(1 << n).fill(0)

    dp[0] = 0

    for (let i = 0; i < people.length; i++) {
        for (let skills_done = (1 << n) - 1; skills_done >= 0; skills_done--) {
            const with_person_skills = skills_done | people_int[i]
            if (dp[with_person_skills] > dp[skills_done] + 1) {
                dp[with_person_skills] = dp[skills_done] + 1
                parent[with_person_skills] = skills_done
            }
        }
    }

    const result = Array(dp[(1 << n) - 1])
    let cur = (1 << n) - 1
    let t = result.length - 1

    for (let i = people.length - 1; i >= 0; i--) {
        const old = parent[cur]
        const diff = cur ^ old
        const is_essential = (people_int[i] & diff) > 0
        if (is_essential) {
            result[t] = i
            t -= 1
        }
        cur = old
    }

    return result
}
```
The algorithm can be described as follows:

1. Create a map of each required skill to a unique integer (0-indexed).
2. Convert the people's skills into integers using bitwise operations, where each bit represents whether the person has a particular skill or not.
3. Use dynamic programming to find the smallest sufficient team. For each person in the list, iterate through all possible skill subsets (done by looping from (2^n - 1) to 0, where n is the number of required skills) and calculate the skill set with the current person.
4. If the team size with the current person is smaller than the previously known team size without the person for the same skill set, update the dynamic programming table with the new team size and store the parent state.
5. Finally, iterate through the parent state array to reconstruct the team and return the indices of the team members.

The time complexity of the algorithm is O(people * 2^req_skills). As req_skills is guaranteed to be at most 16, the time complexity is at most O(60 * 2^16), which is enough for the constraints in the problem statement.


# Split a String in Balanced Strings

- slug: split-a-string-in-balanced-strings
- difficulty: Easy

**Balanced** strings are those that have an equal quantity of `'L'` and `'R'` characters.

Given a **balanced** string `s`, split it into some number of substrings such that:

*   Each substring is balanced.

Return _the **maximum** number of balanced strings you can obtain._

**Example 1:**

**Input:** s =  "RLRRLLRLRL "
**Output:** 4
**Explanation:** s can be split into  "RL ",  "RRLL ",  "RL ",  "RL ", each substring contains same number of 'L' and 'R'.

**Example 2:**

**Input:** s =  "RLRRRLLRLL "
**Output:** 2
**Explanation:** s can be split into  "RL ",  "RRRLLRLL ", each substring contains same number of 'L' and 'R'.
Note that s cannot be split into  "RL ",  "RR ",  "RL ",  "LR ",  "LL ", because the 2nd and 5th substrings are not balanced.

**Example 3:**

**Input:** s =  "LLLLRRRR "
**Output:** 1
**Explanation:** s can be split into  "LLLLRRRR ".

**Constraints:**

*   `2 <= s.length <= 1000`
*   `s[i]` is either `'L'` or `'R'`.
*   `s` is a **balanced** string.

## A solution in Java

```java
public int findSpecialInteger(int[] arr) {
    int n = arr.length, requiredCount = n / 4;
    for (int i = 0; i < n; i++) {
        if (arr[i] == arr[i + requiredCount]) {
            return arr[i];
        }
    }
    return -1;
}
```
The algorithm iterates through the sorted array once. At each iteration, it compares the current integer with the integer that's "requiredCount" positions ahead (where "requiredCount" is the number of elements divided by 4). If the two integers are the same, it means that the integer occurs more than 25% of the time in the array, and it is returned. If no such integer is found, the algorithm returns -1, which should not happen according to the problem constraints. The time complexity is O(n), where n is the number of elements in the array.

## A solution in C++

```cpp
int findSpecialInteger(const vector<int>& arr) {
    int n = arr.size(), requiredCount = n / 4;
    for (int i = 0; i < n; i++) {
        if (arr[i] == arr[i + requiredCount]) {
            return arr[i];
        }
    }
    return -1;
}
```
The algorithm iterates through the sorted array once. At each iteration, it compares the current integer with the integer that's "requiredCount" positions ahead (where "requiredCount" is the number of elements divided by 4). If the two integers are the same, it means that the integer occurs more than 25% of the time in the array, and it is returned. If no such integer is found, the algorithm returns -1, which should not happen according to the problem constraints. The time complexity is O(n), where n is the number of elements in the array.

## A solution in Python

```python
def find_special_integer(arr):
    n = len(arr)
    required_count = n // 4
    for i in range(n):
        if arr[i] == arr[i + required_count]:
            return arr[i]
    return -1
```
The algorithm iterates through the sorted array once. At each iteration, it compares the current integer with the integer that's "requiredCount" positions ahead (where "requiredCount" is the number of elements divided by 4). If the two integers are the same, it means that the integer occurs more than 25% of the time in the array, and it is returned. If no such integer is found, the algorithm returns -1, which should not happen according to the problem constraints. The time complexity is O(n), where n is the number of elements in the array.

## A solution in Javascript

```javascript
function findSpecialInteger(arr) {
    let n = arr.length, requiredCount = Math.floor(n / 4);
    for (let i = 0; i < n; i++) {
        if (arr[i] === arr[i + requiredCount]) {
            return arr[i];
        }
    }
    return -1;
}
```
The algorithm iterates through the sorted array once. At each iteration, it compares the current integer with the integer that's "requiredCount" positions ahead (where "requiredCount" is the number of elements divided by 4). If the two integers are the same, it means that the integer occurs more than 25% of the time in the array, and it is returned. If no such integer is found, the algorithm returns -1, which should not happen according to the problem constraints. The time complexity is O(n), where n is the number of elements in the array.


# Queens That Can Attack the King

- slug: queens-that-can-attack-the-king
- difficulty: Medium

On a **0-indexed** `8 x 8` chessboard, there can be multiple black queens ad one white king.

You are given a 2D integer array `queens` where `queens[i] = [xQueeni, yQueeni]` represents the position of the `ith` black queen on the chessboard. You are also given an integer array `king` of length `2` where `king = [xKing, yKing]` represents the position of the white king.

Return _the coordinates of the black queens that can directly attack the king_. You may return the answer in **any order**.

**Example 1:**

**Input:** queens = \[\[0,1\],\[1,0\],\[4,0\],\[0,4\],\[3,3\],\[2,4\]\], king = \[0,0\]
**Output:** \[\[0,1\],\[1,0\],\[3,3\]\]
**Explanation:** The diagram above shows the three queens that can directly attack the king and the three queens that cannot attack the king (i.e., marked with red dashes).

**Example 2:**

**Input:** queens = \[\[0,0\],\[1,1\],\[2,2\],\[3,4\],\[3,5\],\[4,4\],\[4,5\]\], king = \[3,3\]
**Output:** \[\[2,2\],\[3,4\],\[4,4\]\]
**Explanation:** The diagram above shows the three queens that can directly attack the king and the three queens that cannot attack the king (i.e., marked with red dashes).

**Constraints:**

*   `1 <= queens.length < 64`
*   `queens[i].length == king.length == 2`
*   `0 <= xQueeni, yQueeni, xKing, yKing < 8`
*   All the given positions are **unique**.

## A solution in Java

```java
public int removeCoveredIntervals(int[][] intervals) {
    Arrays.sort(intervals, (a, b) -> {
        if (a[0] == b[0]) return b[1] - a[1];
        return a[0] - b[0];
    });

    int count = 0, end = 0;
    for (int[] interval : intervals) {
        if (interval[1] > end) {
            count++;
            end = interval[1];
        }
    }
    return count;
}
```
1. Sort the intervals by their starting points. When their starting points are the same, sort them by their ending points in descending order.
2. Initialize a variable `count` to store the number of remaining intervals, and a variable `end` to store the maximum ending point found so far.
3. Iterate through the sorted intervals. If the ending point of the current interval is greater than the `end`, increment `count` and set `end` equal to the ending point of the current interval.
4. Return `count` after iterating through all intervals. This is the number of remaining intervals.

## A solution in C++

```cpp
int removeCoveredIntervals(vector<vector<int>>& intervals) {
    sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b) {
        if (a[0] == b[0]) return a[1] > b[1];
        return a[0] < b[0];
    });

    int count = 0, end = 0;
    for (const auto& i : intervals) {
        if (i[1] > end) {
            count++;
            end = i[1];
        }
    }
    return count;
}
```
1. Sort the intervals by their starting points. When their starting points are the same, sort them by their ending points in descending order.
2. Initialize a variable `count` to store the number of remaining intervals, and a variable `end` to store the maximum ending point found so far.
3. Iterate through the sorted intervals. If the ending point of the current interval is greater than the `end`, increment `count` and set `end` equal to the ending point of the current interval.
4. Return `count` after iterating through all intervals. This is the number of remaining intervals.

## A solution in Python

```python
def remove_covered_intervals(intervals):
    intervals.sort(key=lambda x: (x[0], -x[1]))

    count = 0
    end = 0
    for i in intervals:
        if i[1] > end:
            count += 1
            end = i[1]
    return count
```
1. Sort the intervals by their starting points. When their starting points are the same, sort them by their ending points in descending order.
2. Initialize a variable `count` to store the number of remaining intervals, and a variable `end` to store the maximum ending point found so far.
3. Iterate through the sorted intervals. If the ending point of the current interval is greater than the `end`, increment `count` and set `end` equal to the ending point of the current interval.
4. Return `count` after iterating through all intervals. This is the number of remaining intervals.

## A solution in Javascript

```javascript
function removeCoveredIntervals(intervals) {
    intervals.sort((a, b) => {
        if (a[0] === b[0]) return b[1] - a[1];
        return a[0] - b[0];
    });

    let count = 0;
    let end = 0;
    for (let i of intervals) {
        if (i[1] > end) {
            count++;
            end = i[1];
        }
    }
    return count;
}
```
1. Sort the intervals by their starting points. When their starting points are the same, sort them by their ending points in descending order.
2. Initialize a variable `count` to store the number of remaining intervals, and a variable `end` to store the maximum ending point found so far.
3. Iterate through the sorted intervals. If the ending point of the current interval is greater than the `end`, increment `count` and set `end` equal to the ending point of the current interval.
4. Return `count` after iterating through all intervals. This is the number of remaining intervals.


# Dice Roll Simulation

- slug: dice-roll-simulation
- difficulty: Hard

A die simulator generates a random number from `1` to `6` for each roll. You introduced a constraint to the generator such that it cannot roll the number `i` more than `rollMax[i]` (**1-indexed**) consecutive times.

Given an array of integers `rollMax` and an integer `n`, return _the number of distinct sequences that can be obtained with exact_ `n` _rolls_. Since the answer may be too large, return it **modulo** `109 + 7`.

Two sequences are considered different if at least one element differs from each other.

**Example 1:**

**Input:** n = 2, rollMax = \[1,1,2,2,2,3\]
**Output:** 34
**Explanation:** There will be 2 rolls of die, if there are no constraints on the die, there are 6 \* 6 = 36 possible combinations. In this case, looking at rollMax array, the numbers 1 and 2 appear at most once consecutively, therefore sequences (1,1) and (2,2) cannot occur, so the final answer is 36-2 = 34.

**Example 2:**

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

**Example 3:**

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

**Constraints:**

*   `1 <= n <= 5000`
*   `rollMax.length == 6`
*   `1 <= rollMax[i] <= 15`

## A solution in Java

```java
import java.util.Arrays;
import java.util.function.Function;
import java.util.function.BiConsumer;

public boolean[] areConnected(int n, int threshold, int[][] queries) {
    boolean[] answer = new boolean[queries.length];
    int[] parent = new int[n + 1];
    int[] rank = new int[n + 1];

    for (int i = 1; i <= n; i++) {
        parent[i] = i;
    }

    Function<Integer, Integer> find = x -> {
        if (parent[x] != x)
            parent[x] = find.apply(parent[x]);
        return parent[x];
    };

    BiConsumer<Integer, Integer> unite = (x, y) -> {
        int rootx = find.apply(x);
        int rooty = find.apply(y);
        if (rootx != rooty) {
            if (rank[rootx] > rank[rooty]) {
                int temp = rootx;
                rootx = rooty;
                rooty = temp;
            }
            parent[rootx] = rooty;
            if (rank[rootx] == rank[rooty])
                rank[rooty]++;
        }
    };

    for (int i = threshold + 1; i <= n; i++) {
        for (int j = 2 * i; j <= n; j += i) {
            unite.accept(i, j);
        }
    }

    for (int i = 0; i < queries.length; i++) {
        answer[i] = find.apply(queries[i][0]) == find.apply(queries[i][1]);
    }

    return answer;
}
```
We can treat each city as a node, and if city x and y are connected, we can add an edge between them. To solve this problem, we can use the disjoint set data structure (union-find). First, we initialize the data structure with n sets, each containing one element (city).
Next, we use a nested loop to iterate over all possible pairs of cities (i and j), and if i and j share a common divisor greater than the threshold, we connect them in the data structure. Note that we start the inner loop at 2 * i since we don't need to consider divisors less than i. After finding and connecting all cities that share a common divisor and satisfy the condition, we can then iterate through the queries and check if the cities in the query are connected using the find function. If they are connected, we return true, otherwise false for the corresponding query.

## A solution in C++

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

vector<bool> areConnected(int n, int threshold, vector<vector<int>>& queries) {
    vector<bool> answer(queries.size());
    vector<int> parent(n + 1), rank(n + 1, 0);

    for (int i = 1; i <= n; ++i)
        parent[i] = i;

    function<int(int)> find = [&](int x) {
        if (parent[x] != x)
            parent[x] = find(parent[x]);
        return parent[x];
    };

    auto unite = [&](int x, int y) {
        int rootx = find(x);
        int rooty = find(y);
        if (rootx != rooty) {
            if (rank[rootx] > rank[rooty])
                swap(rootx, rooty);
            parent[rootx] = rooty;
            if (rank[rootx] == rank[rooty])
                rank[rooty]++;
        }
    };

    for (int i = threshold + 1; i <= n; ++i)
        for (int j = 2 * i; j <= n; j += i)
            unite(i, j);

    for (int i = 0; i < queries.size(); ++i)
        answer[i] = find(queries[i][0]) == find(queries[i][1]);

    return answer;
}
```
We can treat each city as a node, and if city x and y are connected, we can add an edge between them. To solve this problem, we can use the disjoint set data structure (union-find). First, we initialize the data structure with n sets, each containing one element (city).
Next, we use a nested loop to iterate over all possible pairs of cities (i and j), and if i and j share a common divisor greater than the threshold, we connect them in the data structure. Note that we start the inner loop at 2 * i since we don't need to consider divisors less than i. After finding and connecting all cities that share a common divisor and satisfy the condition, we can then iterate through the queries and check if the cities in the query are connected using the find function. If they are connected, we return true, otherwise false for the corresponding query.

## A solution in Python

```python
def areConnected(n, threshold, queries):
    answer = [False] * len(queries)
    parent = list(range(n + 1))
    rank = [0] * (n + 1)

    def find(x):
        if parent[x] != x:
            parent[x] = find(parent[x])
        return parent[x]

    def unite(x, y):
        rootx = find(x)
        rooty = find(y)
        if rootx != rooty:
            if rank[rootx] > rank[rooty]:
                rootx, rooty = rooty, rootx
            parent[rootx] = rooty
            if rank[rootx] == rank[rooty]:
                rank[rooty] += 1

    for i in range(threshold + 1, n + 1):
        for j in range(i * 2, n + 1, i):
            unite(i, j)

    for i, query in enumerate(queries):
        answer[i] = find(query[0]) == find(query[1])

    return answer
```
We can treat each city as a node, and if city x and y are connected, we can add an edge between them. To solve this problem, we can use the disjoint set data structure (union-find). First, we initialize the data structure with n sets, each containing one element (city).
Next, we use a nested loop to iterate over all possible pairs of cities (i and j), and if i and j share a common divisor greater than the threshold, we connect them in the data structure. Note that we start the inner loop at 2 * i since we don't need to consider divisors less than i. After finding and connecting all cities that share a common divisor and satisfy the condition, we can then iterate through the queries and check if the cities in the query are connected using the find function. If they are connected, we return true, otherwise false for the corresponding query.

## A solution in Javascript

```javascript
function areConnected(n, threshold, queries) {
    const answer = new Array(queries.length).fill(false);
    const parent = Array.from({ length: n + 1 }, (v, i) => i);
    const rank = new Array(n + 1).fill(0);

    function find(x) {
        if (parent[x] !== x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }

    function unite(x, y) {
        let rootx = find(x);
        let rooty = find(y);
        if (rootx !== rooty) {
            if (rank[rootx] > rank[rooty]) {
                [rootx, rooty] = [rooty, rootx];
            }
            parent[rootx] = rooty;
            if (rank[rootx] === rank[rooty]) {
                rank[rooty]++;
            }
        }
    }

    for (let i = threshold + 1; i <= n; i++) {
        for (let j = 2 * i; j <= n; j += i) {
            unite(i, j);
        }
    }

    for (let i = 0; i < queries.length; i++) {
        answer[i] = find(queries[i][0]) === find(queries[i][1]);
    }

    return answer;
}
```
We can treat each city as a node, and if city x and y are connected, we can add an edge between them. To solve this problem, we can use the disjoint set data structure (union-find). First, we initialize the data structure with n sets, each containing one element (city).
Next, we use a nested loop to iterate over all possible pairs of cities (i and j), and if i and j share a common divisor greater than the threshold, we connect them in the data structure. Note that we start the inner loop at 2 * i since we don't need to consider divisors less than i. After finding and connecting all cities that share a common divisor and satisfy the condition, we can then iterate through the queries and check if the cities in the query are connected using the find function. If they are connected, we return true, otherwise false for the corresponding query.


# Maximum Equal Frequency

- slug: maximum-equal-frequency
- difficulty: Hard

Given an array `nums` of positive integers, return the longest possible length of an array prefix of `nums`, such that it is possible to remove **exactly one** element from this prefix so that every number that has appeared in it will have the same number of occurrences.

If after removing one element there are no remaining elements, it's still considered that every appeared number has the same number of ocurrences (0).

**Example 1:**

**Input:** nums = \[2,2,1,1,5,3,3,5\]
**Output:** 7
**Explanation:** For the subarray \[2,2,1,1,5,3,3\] of length 7, if we remove nums\[4\] = 5, we will get \[2,2,1,1,3,3\], so that each number will appear exactly twice.

**Example 2:**

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

**Constraints:**

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

## A solution in Java

```java
import java.util.Arrays;

class Solution {
    public int minFallingPathSum(int[][] grid) {
        int n = grid.length;
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < n; j++) {
                int minVal = Integer.MAX_VALUE;
                for (int k = 0; k < n; k++) {
                    if (k == j) continue;
                    minVal = Math.min(minVal, grid[i - 1][k]);
                }
                grid[i][j] += minVal;
            }
        }
        return Arrays.stream(grid[n - 1]).min().getAsInt();
    }
}
```
The algorithm involves iterating through the grid and computing the minimum sum for each element, considering only the adjacent elements in the previous row that have non-zero shifts (elements with different column indices than the current element).

We first iterate through the rows of grid (starting at row 1, because the base case is row 0). Then, we iterate through the columns in each row, calculating the minimum sum value for each element at grid[i][j] by iterating through all the elements in the previous row (grid[i - 1][k]) and choosing the element with the minimum sum that isn't in the same column (k != j). We then add the calculated minimum sum value to the current element grid[i][j] to update it.

After traversal of the whole grid, we return the minimum value in the last row of grid, as this value now represents the minimum sum of the falling path with non-zero shifts.

The time complexity of this algorithm is O(n^3), where n is the dimension of the grid, since we are using three nested loops to iterate through the elements of the grid. The space complexity is O(1), since we are not using any additional data structures.

## A solution in C++

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

int minFallingPathSum(vector<vector<int>>& grid) {
    int n = grid.size();
    for (int i = 1; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            int minVal = INT_MAX;
            for (int k = 0; k < n; ++k) {
                if (k == j) continue;
                minVal = min(minVal, grid[i - 1][k]);
            }
            grid[i][j] += minVal;
        }
    }
    return *min_element(grid[n-1].begin(), grid[n-1].end());
}
```
The algorithm involves iterating through the grid and computing the minimum sum for each element, considering only the adjacent elements in the previous row that have non-zero shifts (elements with different column indices than the current element).

We first iterate through the rows of grid (starting at row 1, because the base case is row 0). Then, we iterate through the columns in each row, calculating the minimum sum value for each element at grid[i][j] by iterating through all the elements in the previous row (grid[i - 1][k]) and choosing the element with the minimum sum that isn't in the same column (k != j). We then add the calculated minimum sum value to the current element grid[i][j] to update it.

After traversal of the whole grid, we return the minimum value in the last row of grid, as this value now represents the minimum sum of the falling path with non-zero shifts.

The time complexity of this algorithm is O(n^3), where n is the dimension of the grid, since we are using three nested loops to iterate through the elements of the grid. The space complexity is O(1), since we are not using any additional data structures.

## A solution in Python

```python
def minFallingPathSum(grid):
    n = len(grid)
    for i in range(1, n):
        for j in range(n):
            minVal = float('inf')
            for k in range(n):
                if k == j:
                    continue
                minVal = min(minVal, grid[i - 1][k])
            grid[i][j] += minVal
    return min(grid[n - 1])
```
The algorithm involves iterating through the grid and computing the minimum sum for each element, considering only the adjacent elements in the previous row that have non-zero shifts (elements with different column indices than the current element).

We first iterate through the rows of grid (starting at row 1, because the base case is row 0). Then, we iterate through the columns in each row, calculating the minimum sum value for each element at grid[i][j] by iterating through all the elements in the previous row (grid[i - 1][k]) and choosing the element with the minimum sum that isn't in the same column (k != j). We then add the calculated minimum sum value to the current element grid[i][j] to update it.

After traversal of the whole grid, we return the minimum value in the last row of grid, as this value now represents the minimum sum of the falling path with non-zero shifts.

The time complexity of this algorithm is O(n^3), where n is the dimension of the grid, since we are using three nested loops to iterate through the elements of the grid. The space complexity is O(1), since we are not using any additional data structures.

## A solution in Javascript

```javascript
function minFallingPathSum(grid) {
    const n = grid.length;
    for (let i = 1; i < n; i++) {
        for (let j = 0; j < n; j++) {
            let minVal = Infinity;
            for (let k = 0; k < n; k++) {
                if (k === j) continue;
                minVal = Math.min(minVal, grid[i - 1][k]);
            }
            grid[i][j] += minVal;
        }
    }
    return Math.min(...grid[n - 1]);
}
```
The algorithm involves iterating through the grid and computing the minimum sum for each element, considering only the adjacent elements in the previous row that have non-zero shifts (elements with different column indices than the current element).

We first iterate through the rows of grid (starting at row 1, because the base case is row 0). Then, we iterate through the columns in each row, calculating the minimum sum value for each element at grid[i][j] by iterating through all the elements in the previous row (grid[i - 1][k]) and choosing the element with the minimum sum that isn't in the same column (k != j). We then add the calculated minimum sum value to the current element grid[i][j] to update it.

After traversal of the whole grid, we return the minimum value in the last row of grid, as this value now represents the minimum sum of the falling path with non-zero shifts.

The time complexity of this algorithm is O(n^3), where n is the dimension of the grid, since we are using three nested loops to iterate through the elements of the grid. The space complexity is O(1), since we are not using any additional data structures.


# Airplane Seat Assignment Probability

- slug: airplane-seat-assignment-probability
- difficulty: Medium

`n` passengers board an airplane with exactly `n` seats. The first passenger has lost the ticket and picks a seat randomly. But after that, the rest of the passengers will:

*   Take their own seat if it is still available, and
*   Pick other seats randomly when they find their seat occupied

Return _the probability that the_ `nth` _person gets his own seat_.

**Example 1:**

**Input:** n = 1
**Output:** 1.00000
**Explanation:** The first person can only get the first seat.

**Example 2:**

**Input:** n = 2
**Output:** 0.50000
**Explanation:** The second person has a probability of 0.5 to get the second seat (when first person gets the first seat).

**Constraints:**

*   `1 <= n <= 105`

## A solution in Java

```java
import java.util.*;

public int numEquivDominoPairs(int[][] dominoes) {
    Map<Integer, Integer> freq = new HashMap<>();
    int result = 0;
    for (int[] domino : dominoes) {
        int key = Math.min(domino[0], domino[1]) * 10 + Math.max(domino[0], domino[1]);
        result += freq.getOrDefault(key, 0);
        freq.put(key, freq.getOrDefault(key, 0) + 1);
    }
    return result;
}
```
To find the number of equivalent domino pairs, we can use a hash map to count the frequencies of distinct dominoes. We loop through the given domino list and create a unique key for each domino by taking the minimum of the two numbers as the first part, and the maximum as the second part (this ensures that equivalent rotated dominoes have the same key).

For each domino, we increment the frequency count in the hash map and then add the current frequency count to the result. This sum represents the count of equivalent pairs found so far.

Once the loop is completed, we return the result as the total number of equivalent domino pairs.

## A solution in C++

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

int num_equiv_domino_pairs(std::vector<std::vector<int>>& dominoes) {
    std::unordered_map<int, int> freq;
    int result = 0;
    for (auto& domino : dominoes) {
        int key = (std::min(domino[0], domino[1]) << 4) | std::max(domino[0], domino[1]);
        result += freq[key]++;
    }
    return result;
}
```
To find the number of equivalent domino pairs, we can use a hash map to count the frequencies of distinct dominoes. We loop through the given domino list and create a unique key for each domino by taking the minimum of the two numbers as the first part, and the maximum as the second part (this ensures that equivalent rotated dominoes have the same key).

For each domino, we increment the frequency count in the hash map and then add the current frequency count to the result. This sum represents the count of equivalent pairs found so far.

Once the loop is completed, we return the result as the total number of equivalent domino pairs.

## A solution in Python

```python
from collections import defaultdict

def num_equiv_domino_pairs(dominoes):
    freq = defaultdict(int)
    result = 0
    for domino in dominoes:
        key = min(domino[0], domino[1]) * 10 + max(domino[0], domino[1])
        result += freq[key]
        freq[key] += 1
    return result
```
To find the number of equivalent domino pairs, we can use a hash map to count the frequencies of distinct dominoes. We loop through the given domino list and create a unique key for each domino by taking the minimum of the two numbers as the first part, and the maximum as the second part (this ensures that equivalent rotated dominoes have the same key).

For each domino, we increment the frequency count in the hash map and then add the current frequency count to the result. This sum represents the count of equivalent pairs found so far.

Once the loop is completed, we return the result as the total number of equivalent domino pairs.

## A solution in Javascript

```javascript
function numEquivDominoPairs(dominoes) {
    const freq = {};
    let result = 0;
    for (const domino of dominoes) {
        const key = Math.min(domino[0], domino[1]) * 10 + Math.max(domino[0], domino[1]);
        result += (freq[key] || 0);
        freq[key] = (freq[key] || 0) + 1;
    }
    return result;
}
```
To find the number of equivalent domino pairs, we can use a hash map to count the frequencies of distinct dominoes. We loop through the given domino list and create a unique key for each domino by taking the minimum of the two numbers as the first part, and the maximum as the second part (this ensures that equivalent rotated dominoes have the same key).

For each domino, we increment the frequency count in the hash map and then add the current frequency count to the result. This sum represents the count of equivalent pairs found so far.

Once the loop is completed, we return the result as the total number of equivalent domino pairs.


# Missing Number In Arithmetic Progression

- slug: missing-number-in-arithmetic-progression
- difficulty: Easy

In some array `arr`, the values were in arithmetic progression: the values `arr[i + 1] - arr[i]` are all equal for every `0 <= i < arr.length - 1`.

A value from `arr` was removed that **was not the first or last value in the array**.

Given `arr`, return _the removed value_.

**Example 1:**

**Input:** arr = \[5,7,11,13\]
**Output:** 9
**Explanation:** The previous array was \[5,7,**9**,11,13\].

**Example 2:**

**Input:** arr = \[15,13,12\]
**Output:** 14
**Explanation:** The previous array was \[15,**14**,13,12\].

**Constraints:**

*   `3 <= arr.length <= 1000`
*   `0 <= arr[i] <= 105`
*   The given array is **guaranteed** to be a valid array.

## A solution in Java

```java
public int mctFromLeafValues(int[] arr) {
    int n = arr.length;
    int[][] dp = new int[n][n];
    int[][] maxs = new int[n][n];

    for (int i = 0; i < n; ++i) {
        for (int j = i; j < n; ++j) {
            maxs[i][j] = Arrays.stream(arr, i, j + 1).max().getAsInt();
        }
    }

    for (int len = 1; len < n; ++len) {
        for (int i = 0; i + len < n; ++i) {
            int j = i + len;
            dp[i][j] = Integer.MAX_VALUE;
            for (int k = i; k < j; ++k) {
                dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k + 1][j] + maxs[i][k] * maxs[k + 1][j]);
            }
        }
    }
    return dp[0][n - 1];
}
```
The algorithm uses dynamic programming to find the smallest possible sum of non-leaf nodes. The 'dp' matrix stores the minimum sum for each sub-array within the input array 'arr'. The 'maxs' matrix stores the maximum values for each sub-array of 'arr'. To fill up the 'dp' matrix, the code iterates through sub-arrays of increasing length and uses previously computed values to find the minimum sum. It tries all possible binary trees using a nested loop and selects the one with the smallest sum. At the end, it returns the minimum sum of non-leaf nodes for the whole array, which is stored in dp[0][n-1].

## A solution in C++

```cpp
int mctFromLeafValues(vector<int>& arr) {
    int n = arr.size();
    vector<vector<int>> dp(n, vector<int>(n, 0));
    vector<vector<int>> maxs(n, vector<int>(n, 0));

    for (int i = 0; i < n; ++i) {
        for (int j = i; j < n; ++j) {
            maxs[i][j] = *max_element(arr.begin() + i, arr.begin() + j + 1);
        }
    }

    for (int len = 1; len < n; ++len) {
        for (int i = 0; i + len < n; ++i) {
            int j = i + len;
            dp[i][j] = INT_MAX;
            for (int k = i; k < j; ++k) {
                dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + maxs[i][k] * maxs[k + 1][j]);
            }
        }
    }
    return dp[0][n - 1];
}
```
The algorithm uses dynamic programming to find the smallest possible sum of non-leaf nodes. The 'dp' matrix stores the minimum sum for each sub-array within the input array 'arr'. The 'maxs' matrix stores the maximum values for each sub-array of 'arr'. To fill up the 'dp' matrix, the code iterates through sub-arrays of increasing length and uses previously computed values to find the minimum sum. It tries all possible binary trees using a nested loop and selects the one with the smallest sum. At the end, it returns the minimum sum of non-leaf nodes for the whole array, which is stored in dp[0][n-1].

## A solution in Python

```python
def mctFromLeafValues(arr: List[int]) -> int:
    n = len(arr)
    dp = [[0] * n for _ in range(n)]
    maxs = [[0] * n for _ in range(n)]

    for i in range(n):
        for j in range(i, n):
            maxs[i][j] = max(arr[i:j+1])

    for len_ in range(1, n):
        for i in range(n - len_):
            j = i + len_
            dp[i][j] = float('inf')
            for k in range(i, j):
                dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j] + maxs[i][k] * maxs[k+1][j])

    return dp[0][n - 1]
```
The algorithm uses dynamic programming to find the smallest possible sum of non-leaf nodes. The 'dp' matrix stores the minimum sum for each sub-array within the input array 'arr'. The 'maxs' matrix stores the maximum values for each sub-array of 'arr'. To fill up the 'dp' matrix, the code iterates through sub-arrays of increasing length and uses previously computed values to find the minimum sum. It tries all possible binary trees using a nested loop and selects the one with the smallest sum. At the end, it returns the minimum sum of non-leaf nodes for the whole array, which is stored in dp[0][n-1].

## A solution in Javascript

```javascript
function mctFromLeafValues(arr) {
    const n = arr.length;
    const dp = Array(n).fill(0).map(() => Array(n).fill(0));
    const maxs = Array(n).fill(0).map(() => Array(n).fill(0));

    for (let i = 0; i < n; ++i) {
        for (let j = i; j < n; ++j) {
            maxs[i][j] = Math.max(...arr.slice(i, j + 1));
        }
    }

    for (let len = 1; len < n; ++len) {
        for (let i = 0; i + len < n; ++i) {
            let j = i + len;
            dp[i][j] = Number.MAX_SAFE_INTEGER;
            for (let k = i; k < j; ++k) {
                dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k + 1][j] + maxs[i][k] * maxs[k + 1][j]);
            }
        }
    }
    return dp[0][n - 1];
}
```
The algorithm uses dynamic programming to find the smallest possible sum of non-leaf nodes. The 'dp' matrix stores the minimum sum for each sub-array within the input array 'arr'. The 'maxs' matrix stores the maximum values for each sub-array of 'arr'. To fill up the 'dp' matrix, the code iterates through sub-arrays of increasing length and uses previously computed values to find the minimum sum. It tries all possible binary trees using a nested loop and selects the one with the smallest sum. At the end, it returns the minimum sum of non-leaf nodes for the whole array, which is stored in dp[0][n-1].


# Meeting Scheduler

- slug: meeting-scheduler
- difficulty: Medium

Given the availability time slots arrays `slots1` and `slots2` of two people and a meeting duration `duration`, return the **earliest time slot** that works for both of them and is of duration `duration`.

If there is no common time slot that satisfies the requirements, return an **empty array**.

The format of a time slot is an array of two elements `[start, end]` representing an inclusive time range from `start` to `end`.

It is guaranteed that no two availability slots of the same person intersect with each other. That is, for any two time slots `[start1, end1]` and `[start2, end2]` of the same person, either `start1 > end2` or `start2 > end1`.

**Example 1:**

**Input:** slots1 = \[\[10,50\],\[60,120\],\[140,210\]\], slots2 = \[\[0,15\],\[60,70\]\], duration = 8
**Output:** \[60,68\]

**Example 2:**

**Input:** slots1 = \[\[10,50\],\[60,120\],\[140,210\]\], slots2 = \[\[0,15\],\[60,70\]\], duration = 12
**Output:** \[\]

**Constraints:**

*   `1 <= slots1.length, slots2.length <= 104`
*   `slots1[i].length, slots2[i].length == 2`
*   `slots1[i][0] < slots1[i][1]`
*   `slots2[i][0] < slots2[i][1]`
*   `0 <= slots1[i][j], slots2[i][j] <= 109`
*   `1 <= duration <= 106`

## A solution in Java

```java
import java.util.*;

public int[] shortestAlternatingPaths(int n, int[][] redEdges, int[][] blueEdges) {
    List<List<Integer>>[] adjList = new ArrayList[n][2];

    for (int i = 0; i < n; i++) {
        adjList[i][0] = new ArrayList<>();
        adjList[i][1] = new ArrayList<>();
    }

    for (int[] edge : redEdges) {
        adjList[edge[0]][0].add(edge[1]);
    }

    for (int[] edge : blueEdges) {
        adjList[edge[0]][1].add(edge[1]);
    }

    int[][] dist = new int[n][2];
    for (int[] row : dist) {
        Arrays.fill(row, -1);
    }
    dist[0][0] = 0;
    dist[0][1] = 0;

    Queue<int[]> q = new LinkedList<>();
    q.offer(new int[]{0, 0});
    q.offer(new int[]{0, 1});

    while (!q.isEmpty()) {
        int[] cur = q.poll();
        int node = cur[0], color = cur[1];
        int next_color = color ^ 1;

        for (int neighbor : adjList[node][next_color]) {
            if (dist[neighbor][next_color] == -1) {
                dist[neighbor][next_color] = dist[node][color] + 1;
                q.offer(new int[]{neighbor, next_color});
            }
        }
    }

    int[] result = new int[n];
    for (int i = 0; i < n; i++) {
        result[i] = Math.min(dist[i][0], dist[i][1]);
        if (dist[i][0] == -1 || dist[i][1] == -1) {
            result[i] = Math.max(dist[i][0], dist[i][1]);
        }
    }
    return result;
}
```
The algorithm starts by constructing an adjacency list to store the graph's edges. It uses a 3D array (n x 2) for adjacency lists, where one dimension represents nodes, another represents the edge color (0 for red, 1 for blue), and the third is a list of connected neighbors.

It initializes a distance array (dist) to store the minimum distance from node 0 to each node by alternating edge colors. The initial distances are all set to -1, except for the distances from 0 to itself (0 for red and blue).

The algorithm then uses a standard BFS traversal. It alternates the edge colors at each step of the BFS by bitwise XOR (^) of the current edge color (this switches between 0 and 1). If the distance to a neighbor node by the next edge color hasn't been visited yet, it updates the distance and adds the neighbor to the queue.

After the traversal, the algorithm constructs the result by iterating through the distances array and calculates the minimum of the distances by red and blue edges. If only one of the distances is -1, the other valid distance is considered, otherwise returns -1 if both are -1.

## A solution in C++

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

using namespace std;

vector<int> shortestAlternatingPaths(int n, vector<vector<int>>& redEdges, vector<vector<int>>& blueEdges) {
    vector<vector<vector<int>>> adjList(n, vector<vector<int>>(2));

    for (const auto& edge : redEdges) {
        adjList[edge[0]][0].push_back(edge[1]);
    }

    for (const auto& edge : blueEdges) {
        adjList[edge[0]][1].push_back(edge[1]);
    }

    vector<vector<int>> dist(n, vector<int>(2, -1));
    dist[0] = {0, 0};

    queue<pair<int,int>> q;
    q.push({0, 0});
    q.push({0, 1});

    while (!q.empty()) {
        int node = q.front().first, color = q.front().second;
        q.pop();
        int next_color = color ^ 1;

        for (int neighbor : adjList[node][next_color]) {
            if (dist[neighbor][next_color] == -1) {
                dist[neighbor][next_color] = dist[node][color] + 1;
                q.push({neighbor, next_color});
            }
        }
    }

    vector<int> result(n);
    for (int i = 0; i < n; ++i) {
        result[i] = min(dist[i][0], dist[i][1]);
        if (dist[i][0] == -1 || dist[i][1] == -1) {
            result[i] = max(dist[i][0], dist[i][1]);
        }
    }
    return result;
}
```
The algorithm starts by constructing an adjacency list to store the graph's edges. It uses a 3D array (n x 2) for adjacency lists, where one dimension represents nodes, another represents the edge color (0 for red, 1 for blue), and the third is a list of connected neighbors.

It initializes a distance array (dist) to store the minimum distance from node 0 to each node by alternating edge colors. The initial distances are all set to -1, except for the distances from 0 to itself (0 for red and blue).

The algorithm then uses a standard BFS traversal. It alternates the edge colors at each step of the BFS by bitwise XOR (^) of the current edge color (this switches between 0 and 1). If the distance to a neighbor node by the next edge color hasn't been visited yet, it updates the distance and adds the neighbor to the queue.

After the traversal, the algorithm constructs the result by iterating through the distances array and calculates the minimum of the distances by red and blue edges. If only one of the distances is -1, the other valid distance is considered, otherwise returns -1 if both are -1.

## A solution in Python

```python
from collections import defaultdict, deque

def shortestAlternatingPaths(n, redEdges, blueEdges):
    adj_list = defaultdict(lambda: defaultdict(set))

    for u, v in redEdges:
        adj_list[u][0].add(v)

    for u, v in blueEdges:
        adj_list[u][1].add(v)

    dist = [[-1] * 2 for _ in range(n)]
    dist[0] = [0, 0]

    q = deque([(0,0), (0,1)])

    while q:
        node, color = q.popleft()
        next_color = color ^ 1

        for neighbor in adj_list[node][next_color]:
            if dist[neighbor][next_color] == -1:
                dist[neighbor][next_color] = dist[node][color] + 1
                q.append((neighbor, next_color))

    result = []
    for a, b in dist:
        result.append(min(a, b) if a != -1 and b != -1 else max(a, b))

    return result
```
The algorithm starts by constructing an adjacency list to store the graph's edges. It uses a 3D array (n x 2) for adjacency lists, where one dimension represents nodes, another represents the edge color (0 for red, 1 for blue), and the third is a list of connected neighbors.

It initializes a distance array (dist) to store the minimum distance from node 0 to each node by alternating edge colors. The initial distances are all set to -1, except for the distances from 0 to itself (0 for red and blue).

The algorithm then uses a standard BFS traversal. It alternates the edge colors at each step of the BFS by bitwise XOR (^) of the current edge color (this switches between 0 and 1). If the distance to a neighbor node by the next edge color hasn't been visited yet, it updates the distance and adds the neighbor to the queue.

After the traversal, the algorithm constructs the result by iterating through the distances array and calculates the minimum of the distances by red and blue edges. If only one of the distances is -1, the other valid distance is considered, otherwise returns -1 if both are -1.

## A solution in Javascript

```javascript
function shortestAlternatingPaths(n, redEdges, blueEdges) {
    const adjList = new Array(n).fill(null).map(_ => new Array(2).fill(null).map(_ => []));

    for (const edge of redEdges) {
        adjList[edge[0]][0].push(edge[1]);
    }

    for (const edge of blueEdges) {
        adjList[edge[0]][1].push(edge[1]);
    }

    const dist = new Array(n).fill(null).map(_ => new Array(2).fill(-1));
    dist[0][0] = 0;
    dist[0][1] = 0;

    const q = [[0, 0], [0, 1]];

    while (q.length > 0) {
        const [node, color] = q.shift();
        const next_color = color ^ 1;

        for (const neighbor of adjList[node][next_color]) {
            if (dist[neighbor][next_color] === -1) {
                dist[neighbor][next_color] = dist[node][color] + 1;
                q.push([neighbor, next_color]);
            }
        }
    }

    const result = new Array(n);
    for (let i = 0; i < n; i++) {
        result[i] = Math.min(dist[i][0], dist[i][1]);
        if (dist[i][0] === -1 || dist[i][1] === -1) {
            result[i] = Math.max(dist[i][0], dist[i][1]);
        }
    }
    return result;
}
```
The algorithm starts by constructing an adjacency list to store the graph's edges. It uses a 3D array (n x 2) for adjacency lists, where one dimension represents nodes, another represents the edge color (0 for red, 1 for blue), and the third is a list of connected neighbors.

It initializes a distance array (dist) to store the minimum distance from node 0 to each node by alternating edge colors. The initial distances are all set to -1, except for the distances from 0 to itself (0 for red and blue).

The algorithm then uses a standard BFS traversal. It alternates the edge colors at each step of the BFS by bitwise XOR (^) of the current edge color (this switches between 0 and 1). If the distance to a neighbor node by the next edge color hasn't been visited yet, it updates the distance and adds the neighbor to the queue.

After the traversal, the algorithm constructs the result by iterating through the distances array and calculates the minimum of the distances by red and blue edges. If only one of the distances is -1, the other valid distance is considered, otherwise returns -1 if both are -1.


# Toss Strange Coins

- slug: toss-strange-coins
- difficulty: Medium

You have some coins. The `i`\-th coin has a probability `prob[i]` of facing heads when tossed.

Return the probability that the number of coins facing heads equals `target` if you toss every coin exactly once.

**Example 1:**

**Input:** prob = \[0.4\], target = 1
**Output:** 0.40000

**Example 2:**

**Input:** prob = \[0.5,0.5,0.5,0.5,0.5\], target = 0
**Output:** 0.03125

**Constraints:**

*   `1 <= prob.length <= 1000`
*   `0 <= prob[i] <= 1`
*   `0 <= target` `<= prob.length`
*   Answers will be accepted as correct if they are within `10^-5` of the correct answer.

## A solution in Java

```java
public int maxValue(int[] arr1, int[] arr2) {
    int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE,
        max3 = Integer.MIN_VALUE, max4 = Integer.MIN_VALUE;
    int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE,
        min3 = Integer.MAX_VALUE, min4 = Integer.MAX_VALUE;
    int n = arr1.length;

    for (int i = 0; i < n; i++) {
        max1 = Math.max(max1, arr1[i] - arr2[i] + i);
        max2 = Math.max(max2, arr1[i] + arr2[i] + i);
        max3 = Math.max(max3, -arr1[i] + arr2[i] + i);
        max4 = Math.max(max4, -arr1[i] - arr2[i] + i);

        min1 = Math.min(min1, arr1[i] - arr2[i] + i);
        min2 = Math.min(min2, arr1[i] + arr2[i] + i);
        min3 = Math.min(min3, -arr1[i] + arr2[i] + i);
        min4 = Math.min(min4, -arr1[i] - arr2[i] + i);
    }
    return Math.max(Math.max(max1 - min1, max2 - min2),
            Math.max(max3 - min3, max4 - min4));
}
```
The algorithm first initializes four maximum and four minimum values with appropriate maximum and minimum integer values for the specific programming language.

For each i in [0, arr1.length), the algorithm calculates the maximum and minimum values for the four possibilities of the expression, i.e.,
1. arr1[i] - arr2[i] + i
2. arr1[i] + arr2[i] + i
3. -arr1[i] + arr2[i] + i
4. -arr1[i] - arr2[i] + i

At the end of the loop, the algorithm returns the maximum value of the differences between each maximum value and its corresponding minimum value.

This approach ensures that the maximum value of the given expression is found efficiently in O(n) time complexity.

## A solution in C++

```cpp
int max_value(int arr1[], int arr2[], int n) {
    int max1 = INT_MIN, max2 = INT_MIN, max3 = INT_MIN, max4 = INT_MIN;
    int min1 = INT_MAX, min2 = INT_MAX, min3 = INT_MAX, min4 = INT_MAX;

    for (int i = 0; i < n; i++) {
        max1 = max(max1, arr1[i] - arr2[i] + i);
        max2 = max(max2, arr1[i] + arr2[i] + i);
        max3 = max(max3, -arr1[i] + arr2[i] + i);
        max4 = max(max4, -arr1[i] - arr2[i] + i);

        min1 = min(min1, arr1[i] - arr2[i] + i);
        min2 = min(min2, arr1[i] + arr2[i] + i);
        min3 = min(min3, -arr1[i] + arr2[i] + i);
        min4 = min(min4, -arr1[i] - arr2[i] + i);
    }
    return max({max1 - min1, max2 - min2, max3 - min3, max4 - min4});
}
```
The algorithm first initializes four maximum and four minimum values with appropriate maximum and minimum integer values for the specific programming language.

For each i in [0, arr1.length), the algorithm calculates the maximum and minimum values for the four possibilities of the expression, i.e.,
1. arr1[i] - arr2[i] + i
2. arr1[i] + arr2[i] + i
3. -arr1[i] + arr2[i] + i
4. -arr1[i] - arr2[i] + i

At the end of the loop, the algorithm returns the maximum value of the differences between each maximum value and its corresponding minimum value.

This approach ensures that the maximum value of the given expression is found efficiently in O(n) time complexity.

## A solution in Python

```python
def max_value(arr1, arr2):
    n = len(arr1)
    max1 = max2 = max3 = max4 = float('-inf')
    min1 = min2 = min3 = min4 = float('inf')

    for i in range(n):
        max1 = max(max1, arr1[i] - arr2[i] + i)
        max2 = max(max2, arr1[i] + arr2[i] + i)
        max3 = max(max3, -arr1[i] + arr2[i] + i)
        max4 = max(max4, -arr1[i] - arr2[i] + i)

        min1 = min(min1, arr1[i] - arr2[i] + i)
        min2 = min(min2, arr1[i] + arr2[i] + i)
        min3 = min(min3, -arr1[i] + arr2[i] + i)
        min4 = min(min4, -arr1[i] - arr2[i] + i)

    return max(max1 - min1, max2 - min2, max3 - min3, max4 - min4)
```
The algorithm first initializes four maximum and four minimum values with appropriate maximum and minimum integer values for the specific programming language.

For each i in [0, arr1.length), the algorithm calculates the maximum and minimum values for the four possibilities of the expression, i.e.,
1. arr1[i] - arr2[i] + i
2. arr1[i] + arr2[i] + i
3. -arr1[i] + arr2[i] + i
4. -arr1[i] - arr2[i] + i

At the end of the loop, the algorithm returns the maximum value of the differences between each maximum value and its corresponding minimum value.

This approach ensures that the maximum value of the given expression is found efficiently in O(n) time complexity.

## A solution in Javascript

```javascript
function maxValue(arr1, arr2) {
    let max1 = -Infinity, max2 = -Infinity, max3 = -Infinity, max4 = -Infinity;
    let min1 = Infinity, min2 = Infinity, min3 = Infinity, min4 = Infinity;
    let n = arr1.length;

    for (let i = 0; i < n; i++) {
        max1 = Math.max(max1, arr1[i] - arr2[i] + i);
        max2 = Math.max(max2, arr1[i] + arr2[i] + i);
        max3 = Math.max(max3, -arr1[i] + arr2[i] + i);
        max4 = Math.max(max4, -arr1[i] - arr2[i] + i);

        min1 = Math.min(min1, arr1[i] - arr2[i] + i);
        min2 = Math.min(min2, arr1[i] + arr2[i] + i);
        min3 = Math.min(min3, -arr1[i] + arr2[i] + i);
        min4 = Math.min(min4, -arr1[i] - arr2[i] + i);
    }
    return Math.max(Math.max(max1 - min1, max2 - min2),
            Math.max(max3 - min3, max4 - min4));
}
```
The algorithm first initializes four maximum and four minimum values with appropriate maximum and minimum integer values for the specific programming language.

For each i in [0, arr1.length), the algorithm calculates the maximum and minimum values for the four possibilities of the expression, i.e.,
1. arr1[i] - arr2[i] + i
2. arr1[i] + arr2[i] + i
3. -arr1[i] + arr2[i] + i
4. -arr1[i] - arr2[i] + i

At the end of the loop, the algorithm returns the maximum value of the differences between each maximum value and its corresponding minimum value.

This approach ensures that the maximum value of the given expression is found efficiently in O(n) time complexity.


# Divide Chocolate

- slug: divide-chocolate
- difficulty: Hard

You have one chocolate bar that consists of some chunks. Each chunk has its own sweetness given by the array `sweetness`.

You want to share the chocolate with your `k` friends so you start cutting the chocolate bar into `k + 1` pieces using `k` cuts, each piece consists of some **consecutive** chunks.

Being generous, you will eat the piece with the **minimum total sweetness** and give the other pieces to your friends.

Find the **maximum total sweetness** of the piece you can get by cutting the chocolate bar optimally.

**Example 1:**

**Input:** sweetness = \[1,2,3,4,5,6,7,8,9\], k = 5
**Output:** 6
**Explanation:** You can divide the chocolate to \[1,2,3\], \[4,5\], \[6\], \[7\], \[8\], \[9\]

**Example 2:**

**Input:** sweetness = \[5,6,7,8,9,1,2,3,4\], k = 8
**Output:** 1
**Explanation:** There is only one way to cut the bar into 9 pieces.

**Example 3:**

**Input:** sweetness = \[1,2,2,1,2,2,1,2,2\], k = 2
**Output:** 5
**Explanation:** You can divide the chocolate to \[1,2,2\], \[1,2,2\], \[1,2,2\]

**Constraints:**

*   `0 <= k < sweetness.length <= 104`
*   `1 <= sweetness[i] <= 105`

## A solution in Java

```java
public int[] replaceElements(int[] arr) {
    int n = arr.length;
    int maxElement = -1;
    for (int i = n - 1; i >= 0; i--) {
        int temp = arr[i];
        arr[i] = maxElement;
        maxElement = Math.max(maxElement, temp);
    }
    return arr;
}
```
The algorithm works by iterating through the array in reverse order. It keeps track of the maximum element found so far as it iterates through the array. In each iteration, the current element in the array is replaced with the maximum element found so far (initially set as -1, following the problem statement). The iteration then continues to the next element in reverse order and keeps updating the maximum element found. Finally, the modified array is returned.

## A solution in C++

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

vector<int> replaceElements(vector<int>& arr) {
    int n = arr.size();
    int maxElement = -1;
    for (int i = n - 1; i >= 0; i--) {
        int temp = arr[i];
        arr[i] = maxElement;
        maxElement = max(maxElement, temp);
    }
    return arr;
}
```
The algorithm works by iterating through the array in reverse order. It keeps track of the maximum element found so far as it iterates through the array. In each iteration, the current element in the array is replaced with the maximum element found so far (initially set as -1, following the problem statement). The iteration then continues to the next element in reverse order and keeps updating the maximum element found. Finally, the modified array is returned.

## A solution in Python

```python
def replaceElements(arr):
    n = len(arr)
    maxElement = -1
    for i in range(n - 1, -1, -1):
        temp = arr[i]
        arr[i] = maxElement
        maxElement = max(maxElement, temp)
    return arr
```
The algorithm works by iterating through the array in reverse order. It keeps track of the maximum element found so far as it iterates through the array. In each iteration, the current element in the array is replaced with the maximum element found so far (initially set as -1, following the problem statement). The iteration then continues to the next element in reverse order and keeps updating the maximum element found. Finally, the modified array is returned.

## A solution in Javascript

```javascript
function replaceElements(arr) {
    let n = arr.length;
    let maxElement = -1;
    for (let i = n - 1; i >= 0; i--) {
        let temp = arr[i];
        arr[i] = maxElement;
        maxElement = Math.max(maxElement, temp);
    }
    return arr;
}
```
The algorithm works by iterating through the array in reverse order. It keeps track of the maximum element found so far as it iterates through the array. In each iteration, the current element in the array is replaced with the maximum element found so far (initially set as -1, following the problem statement). The iteration then continues to the next element in reverse order and keeps updating the maximum element found. Finally, the modified array is returned.


# Check If It Is a Straight Line

- slug: check-if-it-is-a-straight-line
- difficulty: Easy

You are given an array `coordinates`, `coordinates[i] = [x, y]`, where `[x, y]` represents the coordinate of a point. Check if these points make a straight line in the XY plane.

**Example 1:**

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

**Example 2:**

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

**Constraints:**

*   `2 <= coordinates.length <= 1000`
*   `coordinates[i].length == 2`
*   `-10^4 <= coordinates[i][0], coordinates[i][1] <= 10^4`
*   `coordinates` contains no duplicate point.

## A solution in Java

```java
public int findBestValue(int[] arr, int target) {
    int left = 0;
    int right = 0;
    for (int num : arr) {
        right = Math.max(right, num);
    }
    int result = -1;
    int min_diff = Integer.MAX_VALUE;

    while (left <= right) {
        int mid = left + (right - left) / 2;
        int sum = 0;
        for (int num : arr) {
            sum += Math.min(num, mid);
        }
        if (sum == target) {
            return mid;
        }
        else if (sum > target) {
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
        if (Math.abs(target - sum) < min_diff || Math.abs(target - sum) == min_diff && mid < result) {
            min_diff = Math.abs(target - sum);
            result = mid;
        }
    }
    return result;
}
```
The algorithm performs a binary search to find the best value. Initially, the search range is [0, max(arr)]. In each step, it calculates the mid-point of the current search range and computes the sum of the array elements after replacing all elements larger than mid with mid itself. If the sum is equal to the target, it returns the mid-point. Otherwise, the algorithm adjusts the search range based on whether the sum is greater than or less than the target.

At each step, the algorithm also keeps track of the minimum absolute difference between the target and the calculated sum. If a new candidate value (mid-point) is found that would result in a smaller absolute difference or an equal absolute difference and a smaller value, the algorithm updates the result.

Once the search range is exhausted (left > right), the algorithm returns the result.

## A solution in C++

```cpp
int findBestValue(vector<int>& arr, int target) {
    int left = 0;
    int right = *max_element(arr.begin(), arr.end());
    int result, min_diff = INT_MAX;

    while (left <= right) {
        int mid = left + (right - left) / 2;
        int sum = 0;
        for (int num : arr) {
            sum += min(num, mid);
        }
        if (sum == target) {
            return mid;
        }
        else if (sum > target) {
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
        if (abs(target - sum) < min_diff || abs(target - sum) == min_diff && mid < result) {
            min_diff = abs(target - sum);
            result = mid;
        }
    }
    return result;
}
```
The algorithm performs a binary search to find the best value. Initially, the search range is [0, max(arr)]. In each step, it calculates the mid-point of the current search range and computes the sum of the array elements after replacing all elements larger than mid with mid itself. If the sum is equal to the target, it returns the mid-point. Otherwise, the algorithm adjusts the search range based on whether the sum is greater than or less than the target.

At each step, the algorithm also keeps track of the minimum absolute difference between the target and the calculated sum. If a new candidate value (mid-point) is found that would result in a smaller absolute difference or an equal absolute difference and a smaller value, the algorithm updates the result.

Once the search range is exhausted (left > right), the algorithm returns the result.

## A solution in Python

```python
def findBestValue(arr, target):
    left = 0
    right = max(arr)
    result = -1
    min_diff = float('inf')

    while left <= right:
        mid = left + (right - left) // 2
        total_sum = sum(min(x, mid) for x in arr)
        if total_sum == target:
            return mid
        elif total_sum > target:
            right = mid - 1
        else:
            left = mid + 1

        if abs(target - total_sum) < min_diff or (
                abs(target - total_sum) == min_diff and mid < result):
            min_diff = abs(target - total_sum)
            result = mid

    return result
```
The algorithm performs a binary search to find the best value. Initially, the search range is [0, max(arr)]. In each step, it calculates the mid-point of the current search range and computes the sum of the array elements after replacing all elements larger than mid with mid itself. If the sum is equal to the target, it returns the mid-point. Otherwise, the algorithm adjusts the search range based on whether the sum is greater than or less than the target.

At each step, the algorithm also keeps track of the minimum absolute difference between the target and the calculated sum. If a new candidate value (mid-point) is found that would result in a smaller absolute difference or an equal absolute difference and a smaller value, the algorithm updates the result.

Once the search range is exhausted (left > right), the algorithm returns the result.

## A solution in Javascript

```javascript
function findBestValue(arr, target) {
    let left = 0;
    let right = Math.max(...arr);
    let result = -1;
    let min_diff = Infinity;

    while (left <= right) {
        let mid = Math.floor(left + (right - left) / 2);
        let sum = 0;
        for (let num of arr) {
            sum += Math.min(num, mid);
        }
        if (sum === target) {
            return mid;
        }
        else if (sum > target) {
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
        if (Math.abs(target - sum) < min_diff || (Math.abs(target - sum) === min_diff && mid < result)) {
            min_diff = Math.abs(target - sum);
            result = mid;
        }
    }
    return result;
}
```
The algorithm performs a binary search to find the best value. Initially, the search range is [0, max(arr)]. In each step, it calculates the mid-point of the current search range and computes the sum of the array elements after replacing all elements larger than mid with mid itself. If the sum is equal to the target, it returns the mid-point. Otherwise, the algorithm adjusts the search range based on whether the sum is greater than or less than the target.

At each step, the algorithm also keeps track of the minimum absolute difference between the target and the calculated sum. If a new candidate value (mid-point) is found that would result in a smaller absolute difference or an equal absolute difference and a smaller value, the algorithm updates the result.

Once the search range is exhausted (left > right), the algorithm returns the result.


# Remove Sub-Folders from the Filesystem

- slug: remove-sub-folders-from-the-filesystem
- difficulty: Medium

Given a list of folders `folder`, return _the folders after removing all **sub-folders** in those folders_. You may return the answer in **any order**.

If a `folder[i]` is located within another `folder[j]`, it is called a **sub-folder** of it.

The format of a path is one or more concatenated strings of the form: `'/'` followed by one or more lowercase English letters.

*   For example, `"/leetcode "` and `"/leetcode/problems "` are valid paths while an empty string and `"/ "` are not.

**Example 1:**

**Input:** folder = \[ "/a ", "/a/b ", "/c/d ", "/c/d/e ", "/c/f "\]
**Output:** \[ "/a ", "/c/d ", "/c/f "\]
**Explanation:** Folders  "/a/b " is a subfolder of  "/a " and  "/c/d/e " is inside of folder  "/c/d " in our filesystem.

**Example 2:**

**Input:** folder = \[ "/a ", "/a/b/c ", "/a/b/d "\]
**Output:** \[ "/a "\]
**Explanation:** Folders  "/a/b/c " and  "/a/b/d " will be removed because they are subfolders of  "/a ".

**Example 3:**

**Input:** folder = \[ "/a/b/c ", "/a/b/ca ", "/a/b/d "\]
**Output:** \[ "/a/b/c ", "/a/b/ca ", "/a/b/d "\]

**Constraints:**

*   `1 <= folder.length <= 4 * 104`
*   `2 <= folder[i].length <= 100`
*   `folder[i]` contains only lowercase letters and `'/'`.
*   `folder[i]` always starts with the character `'/'`.
*   Each folder name is **unique**.

## A solution in Java

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

public List<String> removeSubfolders(String[] folder) {
    List<String> result = new ArrayList<>();
    Arrays.sort(folder);
    String prefix = "/";

    for (String path : folder) {
        if (!path.startsWith(prefix)) {
            result.add(path);
            prefix = path + "/";
        }
    }
    return result;
}
```
First, sort the list of folders lexicographically. This guarantees that if a folder is a subfolder of another folder, the parent folder will always come before the subfolder in the sorted list.

Next, initialize an empty result list and a prefix variable with the value '/'.

Iterate over the sorted folder list. Check if the current folder starts with the current prefix value. If it doesn't, it means that the current folder is not a subfolder of the previously checked folder, so add it to the result list and update the prefix value to the current folder concatenated with a '/' character.

Finally, return the result list after processing all the folders. This eliminates any redundant subfolders in the list.

## A solution in C++

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

std::vector<std::string> removeSubfolders(std::vector<std::string>& folder) {
    std::vector<std::string> result;
    std::sort(folder.begin(), folder.end());
    std::string prefix = "/";

    for (const auto& path : folder) {
        if (path.compare(0, prefix.size(), prefix) != 0) {
            result.push_back(path);
            prefix = path + "/";
        }
    }
    return result;
}
```
First, sort the list of folders lexicographically. This guarantees that if a folder is a subfolder of another folder, the parent folder will always come before the subfolder in the sorted list.

Next, initialize an empty result list and a prefix variable with the value '/'.

Iterate over the sorted folder list. Check if the current folder starts with the current prefix value. If it doesn't, it means that the current folder is not a subfolder of the previously checked folder, so add it to the result list and update the prefix value to the current folder concatenated with a '/' character.

Finally, return the result list after processing all the folders. This eliminates any redundant subfolders in the list.

## A solution in Python

```python
from typing import List

def removeSubfolders(folder: List[str]) -> List[str]:
    result = []
    folder.sort()
    prefix = "/"

    for path in folder:
        if not path.startswith(prefix):
            result.append(path)
            prefix = path + "/"
    return result
```
First, sort the list of folders lexicographically. This guarantees that if a folder is a subfolder of another folder, the parent folder will always come before the subfolder in the sorted list.

Next, initialize an empty result list and a prefix variable with the value '/'.

Iterate over the sorted folder list. Check if the current folder starts with the current prefix value. If it doesn't, it means that the current folder is not a subfolder of the previously checked folder, so add it to the result list and update the prefix value to the current folder concatenated with a '/' character.

Finally, return the result list after processing all the folders. This eliminates any redundant subfolders in the list.

## A solution in Javascript

```javascript
function removeSubfolders(folder) {
    let result = [];
    folder.sort();
    let prefix = "/";

    for (let path of folder) {
        if (!path.startsWith(prefix)) {
            result.push(path);
            prefix = path + "/";
        }
    }
    return result;
}
```
First, sort the list of folders lexicographically. This guarantees that if a folder is a subfolder of another folder, the parent folder will always come before the subfolder in the sorted list.

Next, initialize an empty result list and a prefix variable with the value '/'.

Iterate over the sorted folder list. Check if the current folder starts with the current prefix value. If it doesn't, it means that the current folder is not a subfolder of the previously checked folder, so add it to the result list and update the prefix value to the current folder concatenated with a '/' character.

Finally, return the result list after processing all the folders. This eliminates any redundant subfolders in the list.


# Replace the Substring for Balanced String

- slug: replace-the-substring-for-balanced-string
- difficulty: Medium

You are given a string s of length `n` containing only four kinds of characters: `'Q'`, `'W'`, `'E'`, and `'R'`.

A string is said to be **balanced** if each of its characters appears `n / 4` times where `n` is the length of the string.

Return _the minimum length of the substring that can be replaced with **any** other string of the same length to make_ `s` _**balanced**_. If s is already **balanced**, return `0`.

**Example 1:**

**Input:** s =  "QWER "
**Output:** 0
**Explanation:** s is already balanced.

**Example 2:**

**Input:** s =  "QQWE "
**Output:** 1
**Explanation:** We need to replace a 'Q' to 'R', so that  "RQWE " (or  "QRWE ") is balanced.

**Example 3:**

**Input:** s =  "QQQW "
**Output:** 2
**Explanation:** We can replace the first  "QQ " to  "ER ".

**Constraints:**

*   `n == s.length`
*   `4 <= n <= 105`
*   `n` is a multiple of `4`.
*   `s` contains only `'Q'`, `'W'`, `'E'`, and `'R'`.

## A solution in Java

```java
import java.util.*;

public class Solution {
    public int[] getMaxSumAndCount(String[] board) {
        int mod = 1000000007;
        int n = board.length;
        int[][][] dp = new int[n][n][2];
        dp[n - 1][n - 1][1] = 1;

        for (int i = n - 1; i >= 0; i--) {
            for (int j = n - 1; j >= 0; j--) {
                if (board[i].charAt(j) == 'X' || (i == n - 1 && j == n - 1)) continue;
                int currVal = board[i].charAt(j) == 'E' ? 0 : board[i].charAt(j) - '0';
                int[] up = i > 0 ? dp[i - 1][j] : new int[]{-1, 0};
                int[] left = j > 0 ? dp[i][j - 1] : new int[]{-1, 0};
                int[] diag = i > 0 && j > 0 ? dp[i - 1][j - 1] : new int[]{-1, 0};

                int[] maxArray = getMax(up, left, diag);
                if (maxArray[0] == -1) continue;

                dp[i][j][0] = maxArray[0] + currVal;
                if (Arrays.equals(up, maxArray)) dp[i][j][1] = (dp[i][j][1] + up[1] % mod) % mod;
                if (Arrays.equals(left, maxArray)) dp[i][j][1] = (dp[i][j][1] + left[1] % mod) % mod;
                if (Arrays.equals(diag, maxArray)) dp[i][j][1] = (dp[i][j][1] + diag[1] % mod) % mod;
            }
        }
        return dp[0][0];
    }

    public int[] getMax(int[] a, int[] b, int[] c) {
        if (a[0] >= b[0] && a[0] >= c[0]) return a;
        if (b[0] >= a[0] && b[0] >= c[0]) return b;
        return c;
    }
}
```
The algorithm uses a `n x n` table called `dp` to store the maximum sum and the number of paths to achieve that sum for each cell on the board. It initializes the last cell (bottom right corner) with sum `0` and number of paths `1`.

Then, the algorithm iterates in reverse over the cells. If it encounters the starting cell or a cell marked with 'X', it skips that cell. Otherwise, it calculates the current value of the cell (either 0 in case of 'E' or the numeric character value), and checks for the maximum sum among up, left, and diagonal cells (ignoring the cells that are out of the board).

For the three cells (up, left, and diagonal) with the maximum sum, it adds their number of paths to the number of paths in the current cell modulo 1,000,000,007.

Finally, it returns the maximum sum and the number of paths for the first cell (top left corner) as the final result. In case there is no path, the returned value is [0, 0].

## A solution in C++

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

vector<int> getMaxSumAndCount(vector<string>& board) {
    int mod = 1000000007;
    int n = board.size();
    vector<vector<pair<int, int>>> dp(n, vector<pair<int, int>>(n, {0, 0}));
    dp[n - 1][n - 1] = {0, 1};

    for (int i = n - 1; i >= 0; i--) {
        for (int j = n - 1; j >= 0; j--) {
            if (board[i][j] == 'X' || (i == n - 1 && j == n - 1)) continue;
            int currVal = board[i][j] == 'E' ? 0 : board[i][j] - '0';
            pair<int, int> up = i > 0 ? dp[i - 1][j] : make_pair(-1, 0);
            pair<int, int> left = j > 0 ? dp[i][j - 1] : make_pair(-1, 0);
            pair<int, int> diag = i > 0 && j > 0 ? dp[i - 1][j - 1] : make_pair(-1, 0);

            pair<int, int> maxPair = max({up, left, diag});
            if (maxPair.first == -1) continue;

            dp[i][j].first = maxPair.first + currVal;
            if (up == maxPair) dp[i][j].second = (dp[i][j].second + up.second % mod) % mod;
            if (left == maxPair) dp[i][j].second = (dp[i][j].second + left.second % mod) % mod;
            if (diag == maxPair) dp[i][j].second = (dp[i][j].second + diag.second % mod) % mod;
        }
    }
    return {dp[0][0].first, dp[0][0].second};
}
```
The algorithm uses a `n x n` table called `dp` to store the maximum sum and the number of paths to achieve that sum for each cell on the board. It initializes the last cell (bottom right corner) with sum `0` and number of paths `1`.

Then, the algorithm iterates in reverse over the cells. If it encounters the starting cell or a cell marked with 'X', it skips that cell. Otherwise, it calculates the current value of the cell (either 0 in case of 'E' or the numeric character value), and checks for the maximum sum among up, left, and diagonal cells (ignoring the cells that are out of the board).

For the three cells (up, left, and diagonal) with the maximum sum, it adds their number of paths to the number of paths in the current cell modulo 1,000,000,007.

Finally, it returns the maximum sum and the number of paths for the first cell (top left corner) as the final result. In case there is no path, the returned value is [0, 0].

## A solution in Python

```python
def getMaxSumAndCount(board):
    mod = 1000000007
    n = len(board)
    dp = [[(0, 0) for _ in range(n)] for _ in range(n)]
    dp[n - 1][n - 1] = (0, 1)

    for i in range(n - 1, -1, -1):
        for j in range(n - 1, -1, -1):
            if board[i][j] == 'X' or (i == n - 1 and j == n - 1):
                continue
            currVal = 0 if board[i][j] == 'E' else int(board[i][j])
            up = dp[i - 1][j] if i > 0 else (-1, 0)
            left = dp[i][j - 1] if j > 0 else (-1, 0)
            diag = dp[i - 1][j - 1] if i > 0 and j > 0 else (-1, 0)

            maxTuple = max(up, left, diag)
            if maxTuple[0] == -1:
                continue

            dp[i][j] = (maxTuple[0] + currVal, dp[i][j][1])

            if up == maxTuple:
                dp[i][j] = (dp[i][j][0], (dp[i][j][1] + up[1]) % mod)
            if left == maxTuple:
                dp[i][j] = (dp[i][j][0], (dp[i][j][1] + left[1]) % mod)
            if diag == maxTuple:
                dp[i][j] = (dp[i][j][0], (dp[i][j][1] + diag[1]) % mod)

    return dp[0][0]
```
The algorithm uses a `n x n` table called `dp` to store the maximum sum and the number of paths to achieve that sum for each cell on the board. It initializes the last cell (bottom right corner) with sum `0` and number of paths `1`.

Then, the algorithm iterates in reverse over the cells. If it encounters the starting cell or a cell marked with 'X', it skips that cell. Otherwise, it calculates the current value of the cell (either 0 in case of 'E' or the numeric character value), and checks for the maximum sum among up, left, and diagonal cells (ignoring the cells that are out of the board).

For the three cells (up, left, and diagonal) with the maximum sum, it adds their number of paths to the number of paths in the current cell modulo 1,000,000,007.

Finally, it returns the maximum sum and the number of paths for the first cell (top left corner) as the final result. In case there is no path, the returned value is [0, 0].

## A solution in Javascript

```javascript
function getMaxSumAndCount(board) {
    const mod = 1000000007;
    const n = board.length;
    const dp = Array.from({ length: n }, () => Array.from({ length: n }, () => [0, 0]));
    dp[n - 1][n - 1] = [0, 1];

    for (let i = n - 1; i >= 0; i--) {
        for (let j = n - 1; j >= 0; j--) {
            if (board[i][j] === 'X' || (i === n - 1 && j === n - 1)) continue;
            const currVal = board[i][j] === 'E' ? 0 : parseInt(board[i][j]);
            const up = i > 0 ? dp[i - 1][j] : [-1, 0];
            const left = j > 0 ? dp[i][j - 1] : [-1, 0];
            const diag = i > 0 && j > 0 ? dp[i - 1][j - 1] : [-1, 0];

            const maxArray = getMax(up, left, diag);
            if (maxArray[0] === -1) continue;

            dp[i][j][0] = maxArray[0] + currVal;
            if (arraysEqual(up, maxArray)) dp[i][j][1] = (dp[i][j][1] + up[1] % mod) % mod;
            if (arraysEqual(left, maxArray)) dp[i][j][1] = (dp[i][j][1] + left[1] % mod) % mod;
            if (arraysEqual(diag, maxArray)) dp[i][j][1] = (dp[i][j][1] + diag[1] % mod) % mod;
        }
    }
    return dp[0][0];
}

function getMax(a, b, c) {
    if (a[0] >= b[0] && a[0] >= c[0]) return a;
    if (b[0] >= a[0] && b[0] >= c[0]) return b;
    return c;
}

function arraysEqual(a, b) {
    return a.length === b.length && a.every((val, index) => val === b[index]);
}
```
The algorithm uses a `n x n` table called `dp` to store the maximum sum and the number of paths to achieve that sum for each cell on the board. It initializes the last cell (bottom right corner) with sum `0` and number of paths `1`.

Then, the algorithm iterates in reverse over the cells. If it encounters the starting cell or a cell marked with 'X', it skips that cell. Otherwise, it calculates the current value of the cell (either 0 in case of 'E' or the numeric character value), and checks for the maximum sum among up, left, and diagonal cells (ignoring the cells that are out of the board).

For the three cells (up, left, and diagonal) with the maximum sum, it adds their number of paths to the number of paths in the current cell modulo 1,000,000,007.

Finally, it returns the maximum sum and the number of paths for the first cell (top left corner) as the final result. In case there is no path, the returned value is [0, 0].