# Minimum Moves to Convert String

- slug: minimum-moves-to-convert-string
- difficulty: Easy

You are given a string `s` consisting of `n` characters which are either `'X'` or `'O'`.

A **move** is defined as selecting **three** **consecutive characters** of `s` and converting them to `'O'`. Note that if a move is applied to the character `'O'`, it will stay the **same**.

Return _the **minimum** number of moves required so that all the characters of_ `s` _are converted to_ `'O'`.

**Example 1:**

**Input:** s =  "XXX "
**Output:** 1
**Explanation:** XXX -> OOO
We select all the 3 characters and convert them in one move.

**Example 2:**

**Input:** s =  "XXOX "
**Output:** 2
**Explanation:** XXOX -> OOOX -> OOOO
We select the first 3 characters in the first move, and convert them to `'O'`.
Then we select the last 3 characters and convert them so that the final string contains all `'O'`s.

**Example 3:**

**Input:** s =  "OOOO "
**Output:** 0
**Explanation:** There are no `'X's` in `s` to convert.

**Constraints:**

*   `3 <= s.length <= 1000`
*   `s[i]` is either `'X'` or `'O'`.

## A solution in Java

```java
public int maximumRemovals(String s, String p, int[] removable) {
    int low = 0, high = removable.length;
    while (low < high) {
        int mid = low + (high - low + 1) / 2;
        char[] ss = s.toCharArray();
        for (int i = 0; i < mid; ++i) {
            ss[removable[i]] = '-';
        }
        int j = 0, i = 0;
        while (i < ss.length && j < p.length()) {
            if (ss[i] == p.charAt(j)) {
                ++j;
            }
            ++i;
        }
        if (j == p.length()) {
            low = mid;
        } else {
            high = mid - 1;
        }
    }
    return low;
}
```
The algorithm is basically binary search. We iterate through the removable array and start by removing `mid` (the middle element) number of characters from `s`. Then, we check if `p` is still a subsequence of the modified string. If it's a subsequence, it means we can try removing more characters, hence updating the lower bound `low` to `mid`. If it's not a subsequence, we update the upper bound `high` to `mid - 1`, meaning we have to try removing fewer characters. We do this until `low < high`, and then return the maximum value of `k = low` which will give us the maximum removable characters where `p` is still a subsequence of `s`.

## A solution in C++

```cpp
int maximumRemovals(string s, string p, vector<int>& removable) {
    int low = 0, high = removable.size();
    while (low < high) {
        int mid = low + (high - low + 1) / 2;
        string ss = s;
        for (int i = 0; i < mid; ++i) {
            ss[removable[i]] = '-';
        }
        int j = 0, i = 0;
        while (i < ss.size() && j < p.size()) {
            if (ss[i] == p[j]) {
                ++j;
            }
            ++i;
        }
        if (j == p.size()) {
            low = mid;
        } else {
            high = mid - 1;
        }
    }
    return low;
}
```
The algorithm is basically binary search. We iterate through the removable array and start by removing `mid` (the middle element) number of characters from `s`. Then, we check if `p` is still a subsequence of the modified string. If it's a subsequence, it means we can try removing more characters, hence updating the lower bound `low` to `mid`. If it's not a subsequence, we update the upper bound `high` to `mid - 1`, meaning we have to try removing fewer characters. We do this until `low < high`, and then return the maximum value of `k = low` which will give us the maximum removable characters where `p` is still a subsequence of `s`.

## A solution in Python

```python
def maximumRemovals(s: str, p: str, removable: List[int]) -> int:
    low, high = 0, len(removable)
    while low < high:
        mid = low + (high - low + 1) // 2
        ss = list(s)
        for i in range(mid):
            ss[removable[i]] = '-'
        j, i = 0, 0
        while i < len(ss) and j < len(p):
            if ss[i] == p[j]:
                j += 1
            i += 1
        if j == len(p):
            low = mid
        else:
            high = mid - 1
    return low
```
The algorithm is basically binary search. We iterate through the removable array and start by removing `mid` (the middle element) number of characters from `s`. Then, we check if `p` is still a subsequence of the modified string. If it's a subsequence, it means we can try removing more characters, hence updating the lower bound `low` to `mid`. If it's not a subsequence, we update the upper bound `high` to `mid - 1`, meaning we have to try removing fewer characters. We do this until `low < high`, and then return the maximum value of `k = low` which will give us the maximum removable characters where `p` is still a subsequence of `s`.

## A solution in Javascript

```javascript
function maximumRemovals(s, p, removable) {
    let low = 0, high = removable.length;
    while (low < high) {
        let mid = low + Math.floor((high - low + 1) / 2);
        let ss = [...s];
        for (let i = 0; i < mid; ++i) {
            ss[removable[i]] = '-';
        }
        let j = 0, i = 0;
        while (i < ss.length && j < p.length) {
            if (ss[i] === p[j]) {
                ++j;
            }
            ++i;
        }
        if (j === p.length) {
            low = mid;
        } else {
            high = mid - 1;
        }
    }
    return low;
}
```
The algorithm is basically binary search. We iterate through the removable array and start by removing `mid` (the middle element) number of characters from `s`. Then, we check if `p` is still a subsequence of the modified string. If it's a subsequence, it means we can try removing more characters, hence updating the lower bound `low` to `mid`. If it's not a subsequence, we update the upper bound `high` to `mid - 1`, meaning we have to try removing fewer characters. We do this until `low < high`, and then return the maximum value of `k = low` which will give us the maximum removable characters where `p` is still a subsequence of `s`.


# Find Missing Observations

- slug: find-missing-observations
- difficulty: Medium

You have observations of `n + m` **6-sided** dice rolls with each face numbered from `1` to `6`. `n` of the observations went missing, and you only have the observations of `m` rolls. Fortunately, you have also calculated the **average value** of the `n + m` rolls.

You are given an integer array `rolls` of length `m` where `rolls[i]` is the value of the `ith` observation. You are also given the two integers `mean` and `n`.

Return _an array of length_ `n` _containing the missing observations such that the **average value** of the_ `n + m` _rolls is **exactly**_ `mean`. If there are multiple valid answers, return _any of them_. If no such array exists, return _an empty array_.

The **average value** of a set of `k` numbers is the sum of the numbers divided by `k`.

Note that `mean` is an integer, so the sum of the `n + m` rolls should be divisible by `n + m`.

**Example 1:**

**Input:** rolls = \[3,2,4,3\], mean = 4, n = 2
**Output:** \[6,6\]
**Explanation:** The mean of all n + m rolls is (3 + 2 + 4 + 3 + 6 + 6) / 6 = 4.

**Example 2:**

**Input:** rolls = \[1,5,6\], mean = 3, n = 4
**Output:** \[2,3,2,2\]
**Explanation:** The mean of all n + m rolls is (1 + 5 + 6 + 2 + 3 + 2 + 2) / 7 = 3.

**Example 3:**

**Input:** rolls = \[1,2,3,4\], mean = 6, n = 4
**Output:** \[\]
**Explanation:** It is impossible for the mean to be 6 no matter what the 4 missing rolls are.

**Constraints:**

*   `m == rolls.length`
*   `1 <= n, m <= 105`
*   `1 <= rolls[i], mean <= 6`

## A solution in Java

```java
import java.util.Arrays;

public int[] earliestAndLatest(int n, int firstPlayer, int secondPlayer) {
    int earliest = 1, latest = 1;
    while ((firstPlayer + secondPlayer) != n + 1 || Math.abs(firstPlayer - secondPlayer) != 1) {
        if ((firstPlayer + secondPlayer) <= n + 1 && (firstPlayer - 1) / 2 == (secondPlayer - 1) / 2) break;
        if ((firstPlayer + secondPlayer) > n + 1) {
            n = (n + 1) / 2;
            firstPlayer = (n + 1) - secondPlayer;
            secondPlayer = (n + 1) - firstPlayer;
        } else {
            firstPlayer = (firstPlayer + 1) / 2;
            secondPlayer = (secondPlayer + 1) / 2;
        }
        earliest++;
        latest++;
    }
    return new int[]{earliest, latest};
}
```
The algorithm starts by initializing the `earliest` and `latest` round values as 1. It then iterates in a while loop until the sum of the player positions is `n + 1` and the absolute difference between their positions is 1 (since they can only compete when they are next to each other). In each iteration, it checks if they are in the same half of the row. If so, break the loop, as they cannot compete earlier. Then, if they are in opposite halves, reflect their position with respect to the middle of the row. Otherwise, update their position by going to the next round. Finally, increment the round numbers `earliest` and `latest`.

The while loop is the core of the algorithm, determining when the two players can meet. The logic within the loop keeps track of the players' positions in subsequent rounds, ensuring that the earliest and latest rounds are updated accordingly.

## A solution in C++

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

vector<int> earliestAndLatest(int n, int firstPlayer, int secondPlayer) {
    int earliest = 1, latest = 1;
    while ((firstPlayer + secondPlayer) != n + 1 || abs(firstPlayer - secondPlayer) != 1) {
        if ((firstPlayer + secondPlayer) <= n + 1 && (firstPlayer - 1) / 2 == (secondPlayer - 1) / 2) break;
        if ((firstPlayer + secondPlayer) > n + 1) {
            n = (n + 1) / 2;
            firstPlayer = (n + 1) - secondPlayer;
            secondPlayer = (n + 1) - firstPlayer;
        } else {
            firstPlayer = (firstPlayer + 1) / 2;
            secondPlayer = (secondPlayer + 1) / 2;
        }
        earliest++;
        latest++;
    }
    return {earliest, latest};
}
```
The algorithm starts by initializing the `earliest` and `latest` round values as 1. It then iterates in a while loop until the sum of the player positions is `n + 1` and the absolute difference between their positions is 1 (since they can only compete when they are next to each other). In each iteration, it checks if they are in the same half of the row. If so, break the loop, as they cannot compete earlier. Then, if they are in opposite halves, reflect their position with respect to the middle of the row. Otherwise, update their position by going to the next round. Finally, increment the round numbers `earliest` and `latest`.

The while loop is the core of the algorithm, determining when the two players can meet. The logic within the loop keeps track of the players' positions in subsequent rounds, ensuring that the earliest and latest rounds are updated accordingly.

## A solution in Python

```python
def earliest_and_latest(n, first_player, second_player):
    earliest, latest = 1, 1
    while (first_player + second_player) != n + 1 or abs(first_player - second_player) != 1:
        if (first_player + second_player) <= n + 1 and (first_player - 1) // 2 == (second_player - 1) // 2:
            break
        if (first_player + second_player) > n + 1:
            n = (n + 1) // 2
            first_player, second_player = (n + 1) - second_player, (n + 1) - first_player
        else:
            first_player = (first_player + 1) // 2
            second_player = (second_player + 1) // 2
        earliest += 1
        latest += 1

    return [earliest, latest]
```
The algorithm starts by initializing the `earliest` and `latest` round values as 1. It then iterates in a while loop until the sum of the player positions is `n + 1` and the absolute difference between their positions is 1 (since they can only compete when they are next to each other). In each iteration, it checks if they are in the same half of the row. If so, break the loop, as they cannot compete earlier. Then, if they are in opposite halves, reflect their position with respect to the middle of the row. Otherwise, update their position by going to the next round. Finally, increment the round numbers `earliest` and `latest`.

The while loop is the core of the algorithm, determining when the two players can meet. The logic within the loop keeps track of the players' positions in subsequent rounds, ensuring that the earliest and latest rounds are updated accordingly.

## A solution in Javascript

```javascript
function earliestAndLatest(n, firstPlayer, secondPlayer) {
    let earliest = 1, latest = 1;
    while ((firstPlayer + secondPlayer) !== n + 1 || Math.abs(firstPlayer - secondPlayer) !== 1) {
        if ((firstPlayer + secondPlayer) <= n + 1 && Math.floor((firstPlayer - 1) / 2) === Math.floor((secondPlayer - 1) / 2)) break;
        if ((firstPlayer + secondPlayer) > n + 1) {
            n = Math.floor((n + 1) / 2);
            [firstPlayer, secondPlayer] = [(n + 1) - secondPlayer, (n + 1) - firstPlayer];
        } else {
            firstPlayer = Math.floor((firstPlayer + 1) / 2);
            secondPlayer = Math.floor((secondPlayer + 1) / 2);
        }
        earliest++;
        latest++;
    }
    return [earliest, latest];
}
```
The algorithm starts by initializing the `earliest` and `latest` round values as 1. It then iterates in a while loop until the sum of the player positions is `n + 1` and the absolute difference between their positions is 1 (since they can only compete when they are next to each other). In each iteration, it checks if they are in the same half of the row. If so, break the loop, as they cannot compete earlier. Then, if they are in opposite halves, reflect their position with respect to the middle of the row. Otherwise, update their position by going to the next round. Finally, increment the round numbers `earliest` and `latest`.

The while loop is the core of the algorithm, determining when the two players can meet. The logic within the loop keeps track of the players' positions in subsequent rounds, ensuring that the earliest and latest rounds are updated accordingly.


# Stone Game IX

- slug: stone-game-ix
- difficulty: Medium

Alice and Bob continue their games with stones. There is a row of n stones, and each stone has an associated value. You are given an integer array `stones`, where `stones[i]` is the **value** of the `ith` stone.

Alice and Bob take turns, with **Alice** starting first. On each turn, the player may remove any stone from `stones`. The player who removes a stone **loses** if the **sum** of the values of **all removed stones** is divisible by `3`. Bob will win automatically if there are no remaining stones (even if it is Alice's turn).

Assuming both players play **optimally**, return `true` _if Alice wins and_ `false` _if Bob wins_.

**Example 1:**

**Input:** stones = \[2,1\]
**Output:** true
**Explanation:** The game will be played as follows:
- Turn 1: Alice can remove either stone.
- Turn 2: Bob removes the remaining stone.
The sum of the removed stones is 1 + 2 = 3 and is divisible by 3. Therefore, Bob loses and Alice wins the game.

**Example 2:**

**Input:** stones = \[2\]
**Output:** false
**Explanation:** Alice will remove the only stone, and the sum of the values on the removed stones is 2.
Since all the stones are removed and the sum of values is not divisible by 3, Bob wins the game.

**Example 3:**

**Input:** stones = \[5,1,2,4,3\]
**Output:** false
**Explanation:** Bob will always win. One possible way for Bob to win is shown below:
- Turn 1: Alice can remove the second stone with value 1. Sum of removed stones = 1.
- Turn 2: Bob removes the fifth stone with value 3. Sum of removed stones = 1 + 3 = 4.
- Turn 3: Alices removes the fourth stone with value 4. Sum of removed stones = 1 + 3 + 4 = 8.
- Turn 4: Bob removes the third stone with value 2. Sum of removed stones = 1 + 3 + 4 + 2 = 10.
- Turn 5: Alice removes the first stone with value 5. Sum of removed stones = 1 + 3 + 4 + 2 + 5 = 15.
Alice loses the game because the sum of the removed stones (15) is divisible by 3. Bob wins the game.

**Constraints:**

*   `1 <= stones.length <= 105`
*   `1 <= stones[i] <= 104`

## A solution in Java

```java
public boolean stoneGameIX(int[] stones) {
    int[] cnt = new int[3];
    for (int s : stones) {
        cnt[s % 3]++;
    }
    return (cnt[1] != 0 && cnt[2] != 0) || (cnt[1] > cnt[2] ? cnt[1] > cnt[2] + 2 : cnt[2] > cnt[1] + 1);
}
```
To solve this problem, we need to count the occurrences of the remainder when dividing each element in the `stones` array by 3. We store them in an array `cnt`, where `cnt[i]` has the count of occurrences of the remainder `i`.

Then, we check if both `cnt[1]` and `cnt[2]` are non-zero or if there is a difference of at least 2 between `cnt[1]` and `cnt[2]`. If either of these conditions are true, Alice wins, otherwise, Bob wins.

- If both `cnt[1]` and `cnt[2]` are non-zero, players always have the chance to take an optimal step so that the sum is not divisible by 3.
- If the difference between `cnt[1]` and `cnt[2]` is at least 2, Alice can win by choosing the correct first step. This ensures either of the players has to take a step which results in the final sum being divisible by 3.

## A solution in C++

```cpp
bool stoneGameIX(vector<int>& stones) {
    int cnt[3] = {0, 0, 0};
    for (int s : stones) {
        cnt[s % 3]++;
    }
    return (cnt[1] && cnt[2]) || (cnt[1] > cnt[2] ? cnt[1] > cnt[2] + 2 : cnt[2] > cnt[1] + 1);
}
```
To solve this problem, we need to count the occurrences of the remainder when dividing each element in the `stones` array by 3. We store them in an array `cnt`, where `cnt[i]` has the count of occurrences of the remainder `i`.

Then, we check if both `cnt[1]` and `cnt[2]` are non-zero or if there is a difference of at least 2 between `cnt[1]` and `cnt[2]`. If either of these conditions are true, Alice wins, otherwise, Bob wins.

- If both `cnt[1]` and `cnt[2]` are non-zero, players always have the chance to take an optimal step so that the sum is not divisible by 3.
- If the difference between `cnt[1]` and `cnt[2]` is at least 2, Alice can win by choosing the correct first step. This ensures either of the players has to take a step which results in the final sum being divisible by 3.

## A solution in Python

```python
def stoneGameIX(stones: List[int]) -> bool:
    cnt = [0, 0, 0]
    for s in stones:
        cnt[s % 3] += 1
    return (cnt[1] and cnt[2]) or (cnt[1] > cnt[2] if cnt[1] > cnt[2] + 2 else cnt[2] > cnt[1] + 1)
```
To solve this problem, we need to count the occurrences of the remainder when dividing each element in the `stones` array by 3. We store them in an array `cnt`, where `cnt[i]` has the count of occurrences of the remainder `i`.

Then, we check if both `cnt[1]` and `cnt[2]` are non-zero or if there is a difference of at least 2 between `cnt[1]` and `cnt[2]`. If either of these conditions are true, Alice wins, otherwise, Bob wins.

- If both `cnt[1]` and `cnt[2]` are non-zero, players always have the chance to take an optimal step so that the sum is not divisible by 3.
- If the difference between `cnt[1]` and `cnt[2]` is at least 2, Alice can win by choosing the correct first step. This ensures either of the players has to take a step which results in the final sum being divisible by 3.

## A solution in Javascript

```javascript
function stoneGameIX(stones) {
    const cnt = [0, 0, 0];
    for (const s of stones) {
        cnt[s % 3]++;
    }
    return (cnt[1] && cnt[2]) || (cnt[1] > cnt[2] ? cnt[1] > cnt[2] + 2 : cnt[2] > cnt[1] + 1);
}
```
To solve this problem, we need to count the occurrences of the remainder when dividing each element in the `stones` array by 3. We store them in an array `cnt`, where `cnt[i]` has the count of occurrences of the remainder `i`.

Then, we check if both `cnt[1]` and `cnt[2]` are non-zero or if there is a difference of at least 2 between `cnt[1]` and `cnt[2]`. If either of these conditions are true, Alice wins, otherwise, Bob wins.

- If both `cnt[1]` and `cnt[2]` are non-zero, players always have the chance to take an optimal step so that the sum is not divisible by 3.
- If the difference between `cnt[1]` and `cnt[2]` is at least 2, Alice can win by choosing the correct first step. This ensures either of the players has to take a step which results in the final sum being divisible by 3.


# Smallest K-Length Subsequence With Occurrences of a Letter

- slug: smallest-k-length-subsequence-with-occurrences-of-a-letter
- difficulty: Hard

You are given a string `s`, an integer `k`, a letter `letter`, and an integer `repetition`.

Return _the **lexicographically smallest** subsequence of_ `s` _of length_ `k` _that has the letter_ `letter` _appear **at least**_ `repetition` _times_. The test cases are generated so that the `letter` appears in `s` **at least** `repetition` times.

A **subsequence** is a string that can be derived from another string by deleting some or no characters without changing the order of the remaining characters.

A string `a` is **lexicographically smaller** than a string `b` if in the first position where `a` and `b` differ, string `a` has a letter that appears earlier in the alphabet than the corresponding letter in `b`.

**Example 1:**

**Input:** s =  "leet ", k = 3, letter =  "e ", repetition = 1
**Output:**  "eet "
**Explanation:** There are four subsequences of length 3 that have the letter 'e' appear at least 1 time:
-  "lee " (from  "**lee**t ")
-  "let " (from  "**le**e**t** ")
-  "let " (from  "**l**e**et** ")
-  "eet " (from  "l**eet** ")
The lexicographically smallest subsequence among them is  "eet ".

**Example 2:**

**Input:** s =  "leetcode ", k = 4, letter =  "e ", repetition = 2
**Output:**  "ecde "
**Explanation:**  "ecde " is the lexicographically smallest subsequence of length 4 that has the letter  "e " appear at least 2 times.

**Example 3:**

**Input:** s =  "bb ", k = 2, letter =  "b ", repetition = 2
**Output:**  "bb "
**Explanation:**  "bb " is the only subsequence of length 2 that has the letter  "b " appear at least 2 times.

**Constraints:**

*   `1 <= repetition <= k <= s.length <= 5 * 104`
*   `s` consists of lowercase English letters.
*   `letter` is a lowercase English letter, and appears in `s` at least `repetition` times.

## A solution in Java

```java
import java.util.*;

public String smallestSubsequence(String s, int k, char letter, int repetition) {
    int n = s.length();
    int remaining = n - k;
    int letterCount = 0;

    ArrayDeque<Character> resQueue = new ArrayDeque<>();
    for (char c : s.toCharArray()) {
        while (!resQueue.isEmpty() && resQueue.peekLast() > c && remaining > 0) {
            if (resQueue.peekLast() == letter) {
                if (letterCount > repetition) {
                    --letterCount;
                    resQueue.pollLast();
                    --remaining;
                }
            } else {
                resQueue.pollLast();
                --remaining;
            }
        }
        if (resQueue.size() < k) {
            if (c == letter) {
                ++letterCount;
            } else if (k - resQueue.size() > repetition - letterCount) {
            } else {
                continue;
            }
            resQueue.offerLast(c);
        }
    }

    StringBuilder sb = new StringBuilder();
    while (!resQueue.isEmpty()) {
        sb.append(resQueue.pollFirst());
    }
    return sb.toString();
}
```
1. Initialize counters for the remaining number of characters to delete and for the count of the target letter.
2. Iterate through each character in the string.
3. For each character, check if the result stack is not empty, its top element is greater than the current character, and we have remaining characters to delete. If true, keep deleting characters from the result while respecting the repetition constraint for the letter.
4. If the result is still not full, push the current character into the result stack according to the repetition constraint.
5. In the end, convert the result stack into a string and return it.

## A solution in C++

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

std::string smallestSubsequence(std::string s, int k, char letter, int repetition) {
    int n = s.size();
    int remaining = n - k;
    int letterCount = 0;

    std::vector<char> res;
    for (char c : s) {
        while (!res.empty() && res.back() > c && remaining > 0) {
            if (res.back() == letter) {
                if (letterCount > repetition) {
                    --letterCount;
                    res.pop_back();
                    --remaining;
                }
            } else {
                res.pop_back();
                --remaining;
            }
        }
        if (res.size() < k) {
            if (c == letter) {
                ++letterCount;
            } else if (k - res.size() > repetition - letterCount) {
            } else {
                continue;
            }
            res.push_back(c);
        }
    }

    return std::string(res.begin(), res.end());
}
```
1. Initialize counters for the remaining number of characters to delete and for the count of the target letter.
2. Iterate through each character in the string.
3. For each character, check if the result stack is not empty, its top element is greater than the current character, and we have remaining characters to delete. If true, keep deleting characters from the result while respecting the repetition constraint for the letter.
4. If the result is still not full, push the current character into the result stack according to the repetition constraint.
5. In the end, convert the result stack into a string and return it.

## A solution in Python

```python
def smallestSubsequence(s, k, letter, repetition):
    n = len(s)
    remaining = n - k
    letter_count = 0

    res = []
    for c in s:
        while res and res[-1] > c and remaining > 0:
            if res[-1] == letter:
                if letter_count > repetition:
                    letter_count -= 1
                    res.pop()
                    remaining -= 1
            else:
                res.pop()
                remaining -= 1
        if len(res) < k:
            if c == letter:
                letter_count += 1
            elif k - len(res) > repetition - letter_count:
            else:
                continue
            res.append(c)

    return ''.join(res)
```
1. Initialize counters for the remaining number of characters to delete and for the count of the target letter.
2. Iterate through each character in the string.
3. For each character, check if the result stack is not empty, its top element is greater than the current character, and we have remaining characters to delete. If true, keep deleting characters from the result while respecting the repetition constraint for the letter.
4. If the result is still not full, push the current character into the result stack according to the repetition constraint.
5. In the end, convert the result stack into a string and return it.

## A solution in Javascript

```javascript
function smallestSubsequence(s, k, letter, repetition) {
    let n = s.length;
    let remaining = n - k;
    let letterCount = 0;

    let res = [];
    for (const c of s) {
        while (res.length && res[res.length - 1] > c && remaining > 0) {
            if (res[res.length - 1] === letter) {
                if (letterCount > repetition) {
                    --letterCount;
                    res.pop();
                    --remaining;
                }
            } else {
                res.pop();
                --remaining;
            }
        }
        if (res.length < k) {
            if (c === letter) {
                ++letterCount;
            } else if (k - res.length > repetition - letterCount) {
            } else {
                continue;
            }
            res.push(c);
        }
    }

    return res.join('');
}
```
1. Initialize counters for the remaining number of characters to delete and for the count of the target letter.
2. Iterate through each character in the string.
3. For each character, check if the result stack is not empty, its top element is greater than the current character, and we have remaining characters to delete. If true, keep deleting characters from the result while respecting the repetition constraint for the letter.
4. If the result is still not full, push the current character into the result stack according to the repetition constraint.
5. In the end, convert the result stack into a string and return it.


# Count Subarrays With More Ones Than Zeros

- slug: count-subarrays-with-more-ones-than-zeros
- difficulty: Medium

You are given a binary array `nums` containing only the integers `0` and `1`. Return _the number of **subarrays** in nums that have **more**_ `1`'_s than_ `0`_'s. Since the answer may be very large, return it **modulo**_ `109 + 7`.

A **subarray** is a contiguous sequence of elements within an array.

**Example 1:**

**Input:** nums = \[0,1,1,0,1\]
**Output:** 9
**Explanation:**
The subarrays of size 1 that have more ones than zeros are: \[1\], \[1\], \[1\]
The subarrays of size 2 that have more ones than zeros are: \[1,1\]
The subarrays of size 3 that have more ones than zeros are: \[0,1,1\], \[1,1,0\], \[1,0,1\]
The subarrays of size 4 that have more ones than zeros are: \[1,1,0,1\]
The subarrays of size 5 that have more ones than zeros are: \[0,1,1,0,1\]

**Example 2:**

**Input:** nums = \[0\]
**Output:** 0
**Explanation:**
No subarrays have more ones than zeros.

**Example 3:**

**Input:** nums = \[1\]
**Output:** 1
**Explanation:**
The subarrays of size 1 that have more ones than zeros are: \[1\]

**Constraints:**

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

## A solution in Java

```java
public int minMoves(int n) {
    int[] dp = new int[n + 1];
    dp[0] = 0;
    dp[1] = 1;

    for (int i = 2; i <= n; i++) {
        dp[i] = i;
        for (int x = 1; x < i; x++) {
            int broken = x - 1;
            int unbroken = i - x;
            dp[i] = Math.min(dp[i], 1 + Math.max(dp[broken], dp[unbroken]));
        }
    }

    return dp[n];
}
```
We can use dynamic programming to solve this problem. Start with two base cases:

1. If there are no floors (n=0), the minimum moves required is 0.
2. If there is only one floor (n=1), the minimum moves required is 1.

Create an array `dp` with `n+1` elements, initializing `dp[0]` to 0 and `dp[1]` to 1.

For each floor `i` from 2 to `n`, start with `dp[i]` as `i`. For each potential drop floor `x` from 1 to `i-1`, we can calculate the number of moves required as the maximum moves between when the egg breaks (`x-1`) and when the egg doesn't break (`i-x`), plus 1 for the current move. Update `dp[i]` as the minimum between its current value and the calculated number of moves.

Once we have processed all floors, `dp[n]` contains the minimum number of moves required to determine floor `f` with certainty.

## A solution in C++

```cpp
int minMoves(int n) {
    int dp[n + 1];
    dp[0] = 0;
    dp[1] = 1;

    for (int i = 2; i <= n; i++) {
        dp[i] = i;
        for (int x = 1; x < i; x++) {
            int broken = x - 1;
            int unbroken = i - x;
            dp[i] = std::min(dp[i], 1 + std::max(dp[broken], dp[unbroken]));
        }
    }

    return dp[n];
}
```
We can use dynamic programming to solve this problem. Start with two base cases:

1. If there are no floors (n=0), the minimum moves required is 0.
2. If there is only one floor (n=1), the minimum moves required is 1.

Create an array `dp` with `n+1` elements, initializing `dp[0]` to 0 and `dp[1]` to 1.

For each floor `i` from 2 to `n`, start with `dp[i]` as `i`. For each potential drop floor `x` from 1 to `i-1`, we can calculate the number of moves required as the maximum moves between when the egg breaks (`x-1`) and when the egg doesn't break (`i-x`), plus 1 for the current move. Update `dp[i]` as the minimum between its current value and the calculated number of moves.

Once we have processed all floors, `dp[n]` contains the minimum number of moves required to determine floor `f` with certainty.

## A solution in Python

```python
def min_moves(n):
    dp = [0, 1] + [0] * (n - 1)

    for i in range(2, n + 1):
        dp[i] = i
        for x in range(1, i):
            broken = x - 1
            unbroken = i - x
            dp[i] = min(dp[i], 1 + max(dp[broken], dp[unbroken]))

    return dp[n]
```
We can use dynamic programming to solve this problem. Start with two base cases:

1. If there are no floors (n=0), the minimum moves required is 0.
2. If there is only one floor (n=1), the minimum moves required is 1.

Create an array `dp` with `n+1` elements, initializing `dp[0]` to 0 and `dp[1]` to 1.

For each floor `i` from 2 to `n`, start with `dp[i]` as `i`. For each potential drop floor `x` from 1 to `i-1`, we can calculate the number of moves required as the maximum moves between when the egg breaks (`x-1`) and when the egg doesn't break (`i-x`), plus 1 for the current move. Update `dp[i]` as the minimum between its current value and the calculated number of moves.

Once we have processed all floors, `dp[n]` contains the minimum number of moves required to determine floor `f` with certainty.

## A solution in Javascript

```javascript
function minMoves(n) {
    const dp = new Array(n + 1);
    dp[0] = 0;
    dp[1] = 1;

    for (let i = 2; i <= n; i++) {
        dp[i] = i;
        for (let x = 1; x < i; x++) {
            const broken = x - 1;
            const unbroken = i - x;
            dp[i] = Math.min(dp[i], 1 + Math.max(dp[broken], dp[unbroken]));
        }
    }

    return dp[n];
}
```
We can use dynamic programming to solve this problem. Start with two base cases:

1. If there are no floors (n=0), the minimum moves required is 0.
2. If there is only one floor (n=1), the minimum moves required is 1.

Create an array `dp` with `n+1` elements, initializing `dp[0]` to 0 and `dp[1]` to 1.

For each floor `i` from 2 to `n`, start with `dp[i]` as `i`. For each potential drop floor `x` from 1 to `i-1`, we can calculate the number of moves required as the maximum moves between when the egg breaks (`x-1`) and when the egg doesn't break (`i-x`), plus 1 for the current move. Update `dp[i]` as the minimum between its current value and the calculated number of moves.

Once we have processed all floors, `dp[n]` contains the minimum number of moves required to determine floor `f` with certainty.


# Two Out of Three

- slug: two-out-of-three
- difficulty: Easy

Given three integer arrays `nums1`, `nums2`, and `nums3`, return _a **distinct** array containing all the values that are present in **at least two** out of the three arrays. You may return the values in **any** order_.

**Example 1:**

**Input:** nums1 = \[1,1,3,2\], nums2 = \[2,3\], nums3 = \[3\]
**Output:** \[3,2\]
**Explanation:** The values that are present in at least two arrays are:
- 3, in all three arrays.
- 2, in nums1 and nums2.

**Example 2:**

**Input:** nums1 = \[3,1\], nums2 = \[2,3\], nums3 = \[1,2\]
**Output:** \[2,3,1\]
**Explanation:** The values that are present in at least two arrays are:
- 2, in nums2 and nums3.
- 3, in nums1 and nums2.
- 1, in nums1 and nums3.

**Example 3:**

**Input:** nums1 = \[1,2,2\], nums2 = \[4,3,3\], nums3 = \[5\]
**Output:** \[\]
**Explanation:** No value is present in at least two arrays.

**Constraints:**

*   `1 <= nums1.length, nums2.length, nums3.length <= 100`
*   `1 <= nums1[i], nums2[j], nums3[k] <= 100`

## A solution in Java

```java
public String largestOdd(String num) {
    for (int i = 0; i < num.length(); ++i) {
        if ((num.charAt(i) - '0') % 2 == 1) {
            return num.substring(0, i + 1);
        }
    }
    return "";
}
```
The algorithm used iterates through the input string `num`. For each character, it checks if it's an odd digit (by subtracting '0' and mod-ing 2 to check if it's equal to 1).

If an odd digit is found, it returns the substring from the beginning of the string to the odd digit (inclusive) as the largest odd integer substring.

If no odd digit is found, it returns an empty string.

## A solution in C++

```cpp
std::string largestOdd(std::string num) {
    for (int i = 0; i < num.length(); ++i) {
        if ((num[i] - '0') % 2 == 1) {
            return num.substr(0, i + 1);
        }
    }
    return "";
}
```
The algorithm used iterates through the input string `num`. For each character, it checks if it's an odd digit (by subtracting '0' and mod-ing 2 to check if it's equal to 1).

If an odd digit is found, it returns the substring from the beginning of the string to the odd digit (inclusive) as the largest odd integer substring.

If no odd digit is found, it returns an empty string.

## A solution in Python

```python
def largest_odd(num: str) -> str:
    for i in range(len(num)):
        if (int(num[i]) % 2) == 1:
            return num[:i + 1]
    return ""
```
The algorithm used iterates through the input string `num`. For each character, it checks if it's an odd digit (by subtracting '0' and mod-ing 2 to check if it's equal to 1).

If an odd digit is found, it returns the substring from the beginning of the string to the odd digit (inclusive) as the largest odd integer substring.

If no odd digit is found, it returns an empty string.

## A solution in Javascript

```javascript
function largestOdd(num) {
    for (let i = 0; i < num.length; ++i) {
        if ((num[i] - '0') % 2 === 1) {
            return num.substr(0, i + 1);
        }
    }
    return "";
}
```
The algorithm used iterates through the input string `num`. For each character, it checks if it's an odd digit (by subtracting '0' and mod-ing 2 to check if it's equal to 1).

If an odd digit is found, it returns the substring from the beginning of the string to the odd digit (inclusive) as the largest odd integer substring.

If no odd digit is found, it returns an empty string.


# Minimum Operations to Make a Uni-Value Grid

- slug: minimum-operations-to-make-a-uni-value-grid
- difficulty: Medium

You are given a 2D integer `grid` of size `m x n` and an integer `x`. In one operation, you can **add** `x` to or **subtract** `x` from any element in the `grid`.

A **uni-value grid** is a grid where all the elements of it are equal.

Return _the **minimum** number of operations to make the grid **uni-value**_. If it is not possible, return `-1`.

**Example 1:**

**Input:** grid = \[\[2,4\],\[6,8\]\], x = 2
**Output:** 4
**Explanation:** We can make every element equal to 4 by doing the following:
- Add x to 2 once.
- Subtract x from 6 once.
- Subtract x from 8 twice.
A total of 4 operations were used.

**Example 2:**

**Input:** grid = \[\[1,5\],\[2,3\]\], x = 1
**Output:** 5
**Explanation:** We can make every element equal to 3.

**Example 3:**

**Input:** grid = \[\[1,2\],\[3,4\]\], x = 2
**Output:** -1
**Explanation:** It is impossible to make every element equal.

**Constraints:**

*   `m == grid.length`
*   `n == grid[i].length`
*   `1 <= m, n <= 105`
*   `1 <= m * n <= 105`
*   `1 <= x, grid[i][j] <= 104`

## A solution in Java

```java
public int fullRoundsPlayed(String loginTime, String logoutTime) {
    int loginHour = Integer.parseInt(loginTime.substring(0, 2));
    int loginMinute = Integer.parseInt(loginTime.substring(3, 5));
    int logoutHour = Integer.parseInt(logoutTime.substring(0, 2));
    int logoutMinute = Integer.parseInt(logoutTime.substring(3, 5));

    if ((logoutHour * 60 + logoutMinute) < (loginHour * 60 + loginMinute)) {
        logoutHour += 24;
    }

    int rounds = (logoutHour * 60 + logoutMinute - (loginHour * 60 + loginMinute)) / 15;
    return rounds;
}
```
1. Parse hours and minutes for both login and logout time.
2. If logout time is earlier than login time (i.e., played through midnight), add 24 hours to the logout hour.
3. Calculate the number of minutes played by taking the difference between logout and login times.
4. Divide the difference by 15 to get the number of full rounds played and return the result.

## A solution in C++

```cpp
#include <string>

int fullRoundsPlayed(const std::string& loginTime, const std::string& logoutTime) {
    int loginHour = std::stoi(loginTime.substr(0, 2));
    int loginMinute = std::stoi(loginTime.substr(3, 2));
    int logoutHour = std::stoi(logoutTime.substr(0, 2));
    int logoutMinute = std::stoi(logoutTime.substr(3, 2));

    if ((logoutHour * 60 + logoutMinute) < (loginHour * 60 + loginMinute)) {
        logoutHour += 24;
    }

    int rounds = (logoutHour * 60 + logoutMinute - (loginHour * 60 + loginMinute)) / 15;
    return rounds;
}
```
1. Parse hours and minutes for both login and logout time.
2. If logout time is earlier than login time (i.e., played through midnight), add 24 hours to the logout hour.
3. Calculate the number of minutes played by taking the difference between logout and login times.
4. Divide the difference by 15 to get the number of full rounds played and return the result.

## A solution in Python

```python
def full_rounds_played(login_time, logout_time):
    login_hour, login_minute = map(int, login_time.split(':'))
    logout_hour, logout_minute = map(int, logout_time.split(':'))

    if (logout_hour * 60 + logout_minute) < (login_hour * 60 + login_minute):
        logout_hour += 24

    rounds = (logout_hour * 60 + logout_minute - (login_hour * 60 + login_minute)) // 15
    return rounds
```
1. Parse hours and minutes for both login and logout time.
2. If logout time is earlier than login time (i.e., played through midnight), add 24 hours to the logout hour.
3. Calculate the number of minutes played by taking the difference between logout and login times.
4. Divide the difference by 15 to get the number of full rounds played and return the result.

## A solution in Javascript

```javascript
function fullRoundsPlayed(loginTime, logoutTime) {
    const loginHour = parseInt(loginTime.slice(0, 2));
    const loginMinute = parseInt(loginTime.slice(3, 5));
    const logoutHour = parseInt(logoutTime.slice(0, 2));
    const logoutMinute = parseInt(logoutTime.slice(3, 5));

    if ((logoutHour * 60 + logoutMinute) < (loginHour * 60 + loginMinute)) {
        logoutHour += 24;
    }

    const rounds = (logoutHour * 60 + logoutMinute - (loginHour * 60 + loginMinute)) / 15;
    return rounds;
}
```
1. Parse hours and minutes for both login and logout time.
2. If logout time is earlier than login time (i.e., played through midnight), add 24 hours to the logout hour.
3. Calculate the number of minutes played by taking the difference between logout and login times.
4. Divide the difference by 15 to get the number of full rounds played and return the result.


# Stock Price Fluctuation

- slug: stock-price-fluctuation
- difficulty: Medium

You are given a stream of **records** about a particular stock. Each record contains a **timestamp** and the corresponding **price** of the stock at that timestamp.

Unfortunately due to the volatile nature of the stock market, the records do not come in order. Even worse, some records may be incorrect. Another record with the same timestamp may appear later in the stream **correcting** the price of the previous wrong record.

Design an algorithm that:

*   **Updates** the price of the stock at a particular timestamp, **correcting** the price from any previous records at the timestamp.
*   Finds the **latest price** of the stock based on the current records. The **latest price** is the price at the latest timestamp recorded.
*   Finds the **maximum price** the stock has been based on the current records.
*   Finds the **minimum price** the stock has been based on the current records.

Implement the `StockPrice` class:

*   `StockPrice()` Initializes the object with no price records.
*   `void update(int timestamp, int price)` Updates the `price` of the stock at the given `timestamp`.
*   `int current()` Returns the **latest price** of the stock.
*   `int maximum()` Returns the **maximum price** of the stock.
*   `int minimum()` Returns the **minimum price** of the stock.

**Example 1:**

**Input**
\[ "StockPrice ",  "update ",  "update ",  "current ",  "maximum ",  "update ",  "maximum ",  "update ",  "minimum "\]
\[\[\], \[1, 10\], \[2, 5\], \[\], \[\], \[1, 3\], \[\], \[4, 2\], \[\]\]
**Output**
\[null, null, null, 5, 10, null, 5, null, 2\]

**Explanation**
StockPrice stockPrice = new StockPrice();
stockPrice.update(1, 10); // Timestamps are \[1\] with corresponding prices \[10\].
stockPrice.update(2, 5);  // Timestamps are \[1,2\] with corresponding prices \[10,5\].
stockPrice.current();     // return 5, the latest timestamp is 2 with the price being 5.
stockPrice.maximum();     // return 10, the maximum price is 10 at timestamp 1.
stockPrice.update(1, 3);  // The previous timestamp 1 had the wrong price, so it is updated to 3.
                          // Timestamps are \[1,2\] with corresponding prices \[3,5\].
stockPrice.maximum();     // return 5, the maximum price is 5 after the correction.
stockPrice.update(4, 2);  // Timestamps are \[1,2,4\] with corresponding prices \[3,5,2\].
stockPrice.minimum();     // return 2, the minimum price is 2 at timestamp 4.

**Constraints:**

*   `1 <= timestamp, price <= 109`
*   At most `105` calls will be made **in total** to `update`, `current`, `maximum`, and `minimum`.
*   `current`, `maximum`, and `minimum` will be called **only after** `update` has been called **at least once**.

## A solution in Java

```java
import java.util.*;

public int[] min_absolute_difference(int[] nums, int[][] queries) {
    int[] result = new int[queries.length];

    for (int i = 0; i < queries.length; i++) {
        int left = queries[i][0];
        int right = queries[i][1];
        TreeSet<Integer> unique = new TreeSet<>();

        for (int j = left; j <= right; j++)
            unique.add(nums[j]);

        if (unique.size() == 1) {
            result[i] = -1;
        } else {
            int min_diff = Integer.MAX_VALUE;
            for (Iterator<Integer> it = unique.iterator(); it.hasNext(); ) {
                int curr = (int) it.next();
                if (!it.hasNext()) break;
                int next = (int) it.next();
                min_diff = Math.min(min_diff, next - curr);
                it.previous();
            }

            result[i] = min_diff;
        }
    }

    return result;
}
```
1. Create an empty result list.
2. Loop through all the queries: for each query:
   1. Get the left and right indexes.
   2. Create a set of unique elements between the left and right indexes.
   3. If there is only one unique element, the minimum difference is -1, add it to the result list.
   4. Otherwise, sort the unique elements and find the minimum difference between adjacent elements. Add the minimum difference to the result list.
3. Return the result list.

## A solution in C++

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

std::vector<int> min_absolute_difference(std::vector<int>& nums, std::vector<std::vector<int>>& queries) {
    std::vector<int> result;

    for (std::vector<int> query : queries) {
        int left = query[0];
        int right = query[1];
        std::set<int> unique;

        for (int i = left; i <= right; ++i)
            unique.insert(nums[i]);

        if (unique.size() == 1) {
            result.push_back(-1);
        } else {
            int min_diff = INT_MAX;
            for (auto it = std::next(unique.begin()); it != unique.end(); ++it)
                min_diff = std::min(min_diff, *it - *std::prev(it));

            result.push_back(min_diff);
        }
    }

    return result;
}
```
1. Create an empty result list.
2. Loop through all the queries: for each query:
   1. Get the left and right indexes.
   2. Create a set of unique elements between the left and right indexes.
   3. If there is only one unique element, the minimum difference is -1, add it to the result list.
   4. Otherwise, sort the unique elements and find the minimum difference between adjacent elements. Add the minimum difference to the result list.
3. Return the result list.

## A solution in Python

```python
def min_absolute_difference(nums, queries):
    result = []

    for query in queries:
        left, right = query
        unique = list(set(nums[left:right + 1]))

        if len(unique) == 1:
            result.append(-1)
        else:
            unique.sort()
            min_diff = float('inf')
            for i in range(1, len(unique)):
                min_diff = min(min_diff, unique[i] - unique[i - 1])

            result.append(min_diff)

    return result
```
1. Create an empty result list.
2. Loop through all the queries: for each query:
   1. Get the left and right indexes.
   2. Create a set of unique elements between the left and right indexes.
   3. If there is only one unique element, the minimum difference is -1, add it to the result list.
   4. Otherwise, sort the unique elements and find the minimum difference between adjacent elements. Add the minimum difference to the result list.
3. Return the result list.

## A solution in Javascript

```javascript
function min_absolute_difference(nums, queries) {
    const result = [];

    for (const query of queries) {
        const left = query[0];
        const right = query[1];
        const unique = new Set(nums.slice(left, right + 1));

        if (unique.size === 1) {
            result.push(-1);
        } else {
            const sorted = Array.from(unique).sort((a, b) => a - b);
            let min_diff = Number.MAX_SAFE_INTEGER;
            for (let i = 1; i < sorted.length; i++)
                min_diff = Math.min(min_diff, sorted[i] - sorted[i - 1]);

            result.push(min_diff);
        }
    }

    return result;
}
```
1. Create an empty result list.
2. Loop through all the queries: for each query:
   1. Get the left and right indexes.
   2. Create a set of unique elements between the left and right indexes.
   3. If there is only one unique element, the minimum difference is -1, add it to the result list.
   4. Otherwise, sort the unique elements and find the minimum difference between adjacent elements. Add the minimum difference to the result list.
3. Return the result list.


# Partition Array Into Two Arrays to Minimize Sum Difference

- slug: partition-array-into-two-arrays-to-minimize-sum-difference
- difficulty: Hard

You are given an integer array `nums` of `2 * n` integers. You need to partition `nums` into **two** arrays of length `n` to **minimize the absolute difference** of the **sums** of the arrays. To partition `nums`, put each element of `nums` into **one** of the two arrays.

Return _the **minimum** possible absolute difference_.

**Example 1:**

**Input:** nums = \[3,9,7,3\]
**Output:** 2
**Explanation:** One optimal partition is: \[3,9\] and \[7,3\].
The absolute difference between the sums of the arrays is abs((3 + 9) - (7 + 3)) = 2.

**Example 2:**

**Input:** nums = \[-36,36\]
**Output:** 72
**Explanation:** One optimal partition is: \[-36\] and \[36\].
The absolute difference between the sums of the arrays is abs((-36) - (36)) = 72.

**Example 3:**

**Input:** nums = \[2,-1,0,4,-2,-9\]
**Output:** 0
**Explanation:** One optimal partition is: \[2,4,-9\] and \[-1,0,-2\].
The absolute difference between the sums of the arrays is abs((2 + 4 + -9) - (-1 + 0 + -2)) = 0.

**Constraints:**

*   `1 <= n <= 15`
*   `nums.length == 2 * n`
*   `-107 <= nums[i] <= 107`

## A solution in Java

```java
public int countSubIslands(int[][] grid1, int[][] grid2) {
    int count = 0;

    for (int i = 0; i < grid1.length; i++) {
        for (int j = 0; j < grid1[0].length; j++) {
            if (grid2[i][j] == 1) {
                boolean[] isSubIsland = new boolean[1];
                isSubIsland[0] = true;
                dfs(grid1, grid2, i, j, isSubIsland);
                if (isSubIsland[0]) {
                    count++;
                }
            }
        }
    }

    return count;
}

private void dfs(int[][] grid1, int[][] grid2, int i, int j, boolean[] isSubIsland) {
    if (i < 0 || i >= grid1.length || j < 0 || j >= grid1[0].length || grid2[i][j] == 0) {
        return;
    }

    if (grid1[i][j] == 0) {
        isSubIsland[0] = false;
    }

    grid2[i][j] = 0;

    dfs(grid1, grid2, i + 1, j, isSubIsland);
    dfs(grid1, grid2, i - 1, j, isSubIsland);
    dfs(grid1, grid2, i, j + 1, isSubIsland);
    dfs(grid1, grid2, i, j - 1, isSubIsland);
}
```
The algorithm uses Depth-First Search (DFS) to traverse the islands in `grid2`. For each cell in `grid2` that has a value of 1 (representing land), it checks if it can be a sub-island by performing DFS.

Within the DFS search, if the corresponding cell in `grid1` has a value of 0, it indicates that the part of the island being traversed in `grid2` is not a subset of the island in `grid1`. In this case, the variable `isSubIsland` is set to `false`. During the search, it also marks the visited cells in `grid2` as 0 to avoid checking them multiple times. If the entire `dfs` returns `true`, then it is considered as a sub-island, and the count is incremented.

In the end, the total sub-island count is returned.

## A solution in C++

```cpp
#include <vector>

void dfs(std::vector<std::vector<int>>& grid1, std::vector<std::vector<int>>& grid2, int i, int j, bool& isSubIsland) {
    if (i < 0 || i >= grid1.size() || j < 0 || j >= grid1[0].size() || grid2[i][j] == 0) {
        return;
    }

    if (grid1[i][j] == 0) {
        isSubIsland = false;
    }

    grid2[i][j] = 0;

    dfs(grid1, grid2, i + 1, j, isSubIsland);
    dfs(grid1, grid2, i - 1, j, isSubIsland);
    dfs(grid1, grid2, i, j + 1, isSubIsland);
    dfs(grid1, grid2, i, j - 1, isSubIsland);
}

int countSubIslands(std::vector<std::vector<int>>& grid1, std::vector<std::vector<int>>& grid2) {
    int count = 0;

    for (int i = 0; i < grid1.size(); ++i) {
        for (int j = 0; j < grid1[0].size(); ++j) {
            if (grid2[i][j] == 1) {
                bool isSubIsland = true;
                dfs(grid1, grid2, i, j, isSubIsland);
                if (isSubIsland) {
                    ++count;
                }
            }
        }
    }

    return count;
}
```
The algorithm uses Depth-First Search (DFS) to traverse the islands in `grid2`. For each cell in `grid2` that has a value of 1 (representing land), it checks if it can be a sub-island by performing DFS.

Within the DFS search, if the corresponding cell in `grid1` has a value of 0, it indicates that the part of the island being traversed in `grid2` is not a subset of the island in `grid1`. In this case, the variable `isSubIsland` is set to `false`. During the search, it also marks the visited cells in `grid2` as 0 to avoid checking them multiple times. If the entire `dfs` returns `true`, then it is considered as a sub-island, and the count is incremented.

In the end, the total sub-island count is returned.

## A solution in Python

```python
def countSubIslands(grid1, grid2):
    def dfs(i, j):
        if i < 0 or i >= len(grid1) or j < 0 or j >= len(grid1[0]) or grid2[i][j] == 0:
            return True

        grid2[i][j] = 0

        isSubIsland = grid1[i][j] == 1
        isSubIsland &= dfs(i + 1, j)
        isSubIsland &= dfs(i - 1, j)
        isSubIsland &= dfs(i, j + 1)
        isSubIsland &= dfs(i, j - 1)

        return isSubIsland

    count = 0

    for i in range(len(grid1)):
        for j in range(len(grid1[0])):
            if grid2[i][j] == 1 and dfs(i, j):
                count += 1

    return count
```
The algorithm uses Depth-First Search (DFS) to traverse the islands in `grid2`. For each cell in `grid2` that has a value of 1 (representing land), it checks if it can be a sub-island by performing DFS.

Within the DFS search, if the corresponding cell in `grid1` has a value of 0, it indicates that the part of the island being traversed in `grid2` is not a subset of the island in `grid1`. In this case, the variable `isSubIsland` is set to `false`. During the search, it also marks the visited cells in `grid2` as 0 to avoid checking them multiple times. If the entire `dfs` returns `true`, then it is considered as a sub-island, and the count is incremented.

In the end, the total sub-island count is returned.

## A solution in Javascript

```javascript
function countSubIslands(grid1, grid2) {
    function dfs(i, j) {
        if (i < 0 || i >= grid1.length || j < 0 || j >= grid1[0].length || grid2[i][j] === 0) {
            return true;
        }

        grid2[i][j] = 0;

        let isSubIsland = grid1[i][j] === 1;
        isSubIsland &= dfs(i + 1, j) ? 1 : 0;
        isSubIsland &= dfs(i - 1, j) ? 1 : 0;
        isSubIsland &= dfs(i, j + 1) ? 1 : 0;
        isSubIsland &= dfs(i, j - 1) ? 1 : 0;

        return isSubIsland;
    }

    let count = 0;

    for (let i = 0; i < grid1.length; i++) {
        for (let j = 0; j < grid1[0].length; j++) {
            if (grid2[i][j] === 1 && dfs(i, j)) {
                count++;
            }
        }
    }

    return count;
}
```
The algorithm uses Depth-First Search (DFS) to traverse the islands in `grid2`. For each cell in `grid2` that has a value of 1 (representing land), it checks if it can be a sub-island by performing DFS.

Within the DFS search, if the corresponding cell in `grid1` has a value of 0, it indicates that the part of the island being traversed in `grid2` is not a subset of the island in `grid1`. In this case, the variable `isSubIsland` is set to `false`. During the search, it also marks the visited cells in `grid2` as 0 to avoid checking them multiple times. If the entire `dfs` returns `true`, then it is considered as a sub-island, and the count is incremented.

In the end, the total sub-island count is returned.


# Maximum Alternating Subarray Sum

- slug: maximum-alternating-subarray-sum
- difficulty: Medium

A **subarray** of a **0-indexed** integer array is a contiguous **non-empty** sequence of elements within an array.

The **alternating subarray sum** of a subarray that ranges from index `i` to `j` (**inclusive**, `0 <= i <= j < nums.length`) is `nums[i] - nums[i+1] + nums[i+2] - ... +/- nums[j]`.

Given a **0-indexed** integer array `nums`, return _the **maximum alternating subarray sum** of any subarray of_ `nums`.

**Example 1:**

**Input:** nums = \[3,-1,1,2\]
**Output:** 5
**Explanation:**
The subarray \[3,-1,1\] has the largest alternating subarray sum.
The alternating subarray sum is 3 - (-1) + 1 = 5.

**Example 2:**

**Input:** nums = \[2,2,2,2,2\]
**Output:** 2
**Explanation:**
The subarrays \[2\], \[2,2,2\], and \[2,2,2,2,2\] have the largest alternating subarray sum.
The alternating subarray sum of \[2\] is 2.
The alternating subarray sum of \[2,2,2\] is 2 - 2 + 2 = 2.
The alternating subarray sum of \[2,2,2,2,2\] is 2 - 2 + 2 - 2 + 2 = 2.

**Example 3:**

**Input:** nums = \[1\]
**Output:** 1
**Explanation:**
There is only one non-empty subarray, which is \[1\].
The alternating subarray sum is 1.

**Constraints:**

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

## A solution in Java

```java
public int maxAlternatingSum(int[] nums) {
    long odd = 0, even = 0;
    for (int num : nums) {
        long newOdd = Math.max(even + num, odd);
        even = Math.max(odd - num, even);
        odd = newOdd;
    }
    return (int)odd;
}
```
We will use dynamic programming approach to solve this problem. We will keep track of two variables: `odd` and `even`, which represent the maximum alternating subarray sum ending at odd and even indices, respectively. We will loop through the input array `nums` and update `odd` and `even`. For each number in the array, the new maximum subarray sum ending at odd index is maximum of previous maximum subarray sum ending at even index plus current number, and previous maximum subarray sum ending at odd index. Similarly, the new maximum subarray sum ending at even index is maximum of previous maximum subarray sum ending at odd index minus current number, and previous maximum subarray sum ending at even index. At the end of the loop, `odd` stores the maximum alternating subarray sum of the input array.

## A solution in C++

```cpp
int maxAlternatingSum(vector<int>& nums) {
    long odd = 0, even = 0;
    for (int num: nums) {
        long newOdd = max(even + num, odd);
        even = max(odd - num, even);
        odd = newOdd;
    }
    return odd;
}
```
We will use dynamic programming approach to solve this problem. We will keep track of two variables: `odd` and `even`, which represent the maximum alternating subarray sum ending at odd and even indices, respectively. We will loop through the input array `nums` and update `odd` and `even`. For each number in the array, the new maximum subarray sum ending at odd index is maximum of previous maximum subarray sum ending at even index plus current number, and previous maximum subarray sum ending at odd index. Similarly, the new maximum subarray sum ending at even index is maximum of previous maximum subarray sum ending at odd index minus current number, and previous maximum subarray sum ending at even index. At the end of the loop, `odd` stores the maximum alternating subarray sum of the input array.

## A solution in Python

```python
def maxAlternatingSum(nums):
    odd, even = 0, 0
    for num in nums:
        newOdd = max(even + num, odd)
        even = max(odd - num, even)
        odd = newOdd
    return odd
```
We will use dynamic programming approach to solve this problem. We will keep track of two variables: `odd` and `even`, which represent the maximum alternating subarray sum ending at odd and even indices, respectively. We will loop through the input array `nums` and update `odd` and `even`. For each number in the array, the new maximum subarray sum ending at odd index is maximum of previous maximum subarray sum ending at even index plus current number, and previous maximum subarray sum ending at odd index. Similarly, the new maximum subarray sum ending at even index is maximum of previous maximum subarray sum ending at odd index minus current number, and previous maximum subarray sum ending at even index. At the end of the loop, `odd` stores the maximum alternating subarray sum of the input array.

## A solution in Javascript

```javascript
function maxAlternatingSum(nums) {
    let odd = 0, even = 0;
    for (const num of nums) {
        const newOdd = Math.max(even + num, odd);
        even = Math.max(odd - num, even);
        odd = newOdd;
    }
    return odd;
}
```
We will use dynamic programming approach to solve this problem. We will keep track of two variables: `odd` and `even`, which represent the maximum alternating subarray sum ending at odd and even indices, respectively. We will loop through the input array `nums` and update `odd` and `even`. For each number in the array, the new maximum subarray sum ending at odd index is maximum of previous maximum subarray sum ending at even index plus current number, and previous maximum subarray sum ending at odd index. Similarly, the new maximum subarray sum ending at even index is maximum of previous maximum subarray sum ending at odd index minus current number, and previous maximum subarray sum ending at even index. At the end of the loop, `odd` stores the maximum alternating subarray sum of the input array.


# Minimum Number of Moves to Seat Everyone

- slug: minimum-number-of-moves-to-seat-everyone
- difficulty: Easy

There are `n` seats and `n` students in a room. You are given an array `seats` of length `n`, where `seats[i]` is the position of the `ith` seat. You are also given the array `students` of length `n`, where `students[j]` is the position of the `jth` student.

You may perform the following move any number of times:

*   Increase or decrease the position of the `ith` student by `1` (i.e., moving the `ith` student from position `x` to `x + 1` or `x - 1`)

Return _the **minimum number of moves** required to move each student to a seat_ _such that no two students are in the same seat._

Note that there may be **multiple** seats or students in the **same** position at the beginning.

**Example 1:**

**Input:** seats = \[3,1,5\], students = \[2,7,4\]
**Output:** 4
**Explanation:** The students are moved as follows:
- The first student is moved from from position 2 to position 1 using 1 move.
- The second student is moved from from position 7 to position 5 using 2 moves.
- The third student is moved from from position 4 to position 3 using 1 move.
In total, 1 + 2 + 1 = 4 moves were used.

**Example 2:**

**Input:** seats = \[4,1,5,9\], students = \[1,3,2,6\]
**Output:** 7
**Explanation:** The students are moved as follows:
- The first student is not moved.
- The second student is moved from from position 3 to position 4 using 1 move.
- The third student is moved from from position 2 to position 5 using 3 moves.
- The fourth student is moved from from position 6 to position 9 using 3 moves.
In total, 0 + 1 + 3 + 3 = 7 moves were used.

**Example 3:**

**Input:** seats = \[2,2,6,6\], students = \[1,3,2,6\]
**Output:** 4
**Explanation:** Note that there are two seats at position 2 and two seats at position 6.
The students are moved as follows:
- The first student is moved from from position 1 to position 2 using 1 move.
- The second student is moved from from position 3 to position 6 using 3 moves.
- The third student is not moved.
- The fourth student is not moved.
In total, 1 + 3 + 0 + 0 = 4 moves were used.

**Constraints:**

*   `n == seats.length == students.length`
*   `1 <= n <= 100`
*   `1 <= seats[i], students[j] <= 100`

## A solution in Java

```java
public int countSquareTriples(int n) {
    int count = 0;
    for (int a = 1; a <= n; a++) {
        for (int b = a; b <= n; b++) {
            int c = (int) Math.sqrt(a * a + b * b);
            if (c * c == a * a + b * b && c <= n) {
                count++;
            }
        }
    }
    return count;
}
```
1. Initialize the count of square triples to 0.
2. Start two nested loops with variables a and b ranging from 1 to n, inclusive.
3. Inside the inner loop, calculate c as the square root of a² + b², rounded down to the nearest integer, and check if c² equals a² + b² and c is less than or equal to n.
4. If the condition is true, increment the count of square triples.
5. Repeat steps 2-4 for all values of a and b.
6. Return the count of square triples.

## A solution in C++

```cpp
#include <cmath>

int countSquareTriples(int n) {
    int count = 0;
    for (int a = 1; a <= n; a++) {
        for (int b = a; b <= n; b++) {
            int c = std::sqrt(a * a + b * b);
            if (c * c == a * a + b * b && c <= n) {
                count++;
            }
        }
    }
    return count;
}
```
1. Initialize the count of square triples to 0.
2. Start two nested loops with variables a and b ranging from 1 to n, inclusive.
3. Inside the inner loop, calculate c as the square root of a² + b², rounded down to the nearest integer, and check if c² equals a² + b² and c is less than or equal to n.
4. If the condition is true, increment the count of square triples.
5. Repeat steps 2-4 for all values of a and b.
6. Return the count of square triples.

## A solution in Python

```python
def count_square_triples(n):
    count = 0
    for a in range(1, n + 1):
        for b in range(a, n + 1):
            c = int((a * a + b * b)**0.5)
            if c * c == a * a + b * b and c <= n:
                count += 1
    return count
```
1. Initialize the count of square triples to 0.
2. Start two nested loops with variables a and b ranging from 1 to n, inclusive.
3. Inside the inner loop, calculate c as the square root of a² + b², rounded down to the nearest integer, and check if c² equals a² + b² and c is less than or equal to n.
4. If the condition is true, increment the count of square triples.
5. Repeat steps 2-4 for all values of a and b.
6. Return the count of square triples.

## A solution in Javascript

```javascript
function countSquareTriples(n) {
    let count = 0;
    for (let a = 1; a <= n; a++) {
        for (let b = a; b <= n; b++) {
            let c = Math.sqrt(a * a + b * b);
            if (c * c === a * a + b * b && c <= n) {
                count++;
            }
        }
    }
    return count;
}
```
1. Initialize the count of square triples to 0.
2. Start two nested loops with variables a and b ranging from 1 to n, inclusive.
3. Inside the inner loop, calculate c as the square root of a² + b², rounded down to the nearest integer, and check if c² equals a² + b² and c is less than or equal to n.
4. If the condition is true, increment the count of square triples.
5. Repeat steps 2-4 for all values of a and b.
6. Return the count of square triples.


# Remove Colored Pieces if Both Neighbors are the Same Color

- slug: remove-colored-pieces-if-both-neighbors-are-the-same-color
- difficulty: Medium

There are `n` pieces arranged in a line, and each piece is colored either by `'A'` or by `'B'`. You are given a string `colors` of length `n` where `colors[i]` is the color of the `ith` piece.

Alice and Bob are playing a game where they take **alternating turns** removing pieces from the line. In this game, Alice moves **first**.

*   Alice is only allowed to remove a piece colored `'A'` if **both its neighbors** are also colored `'A'`. She is **not allowed** to remove pieces that are colored `'B'`.
*   Bob is only allowed to remove a piece colored `'B'` if **both its neighbors** are also colored `'B'`. He is **not allowed** to remove pieces that are colored `'A'`.
*   Alice and Bob **cannot** remove pieces from the edge of the line.
*   If a player cannot make a move on their turn, that player **loses** and the other player **wins**.

Assuming Alice and Bob play optimally, return `true` _if Alice wins, or return_ `false` _if Bob wins_.

**Example 1:**

**Input:** colors =  "AAABABB "
**Output:** true
**Explanation:**
AAABABB -> AABABB
Alice moves first.
She removes the second 'A' from the left since that is the only 'A' whose neighbors are both 'A'.

Now it's Bob's turn.
Bob cannot make a move on his turn since there are no 'B's whose neighbors are both 'B'.
Thus, Alice wins, so return true.

**Example 2:**

**Input:** colors =  "AA "
**Output:** false
**Explanation:**
Alice has her turn first.
There are only two 'A's and both are on the edge of the line, so she cannot move on her turn.
Thus, Bob wins, so return false.

**Example 3:**

**Input:** colors =  "ABBBBBBBAAA "
**Output:** false
**Explanation:**
ABBBBBBBAAA -> ABBBBBBBAA
Alice moves first.
Her only option is to remove the second to last 'A' from the right.

ABBBBBBBAA -> ABBBBBBAA
Next is Bob's turn.
He has many options for which 'B' piece to remove. He can pick any.

On Alice's second turn, she has no more pieces that she can remove.
Thus, Bob wins, so return false.

**Constraints:**

*   `1 <= colors.length <= 105`
*   `colors` consists of only the letters `'A'` and `'B'`

## A solution in Java

```java
import java.util.*;

public int nearestExit(char[][] maze, int[] entrance) {
    int m = maze.length;
    int n = maze[0].length;
    int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    Queue<int[]> q = new LinkedList<>();
    maze[entrance[0]][entrance[1]] = '+';
    q.offer(new int[]{entrance[0], entrance[1]});
    int steps = 0;

    while (!q.isEmpty()) {
        int size = q.size();
        for (int i = 0; i < size; ++i) {
            int[] cur = q.poll();
            int x = cur[0];
            int y = cur[1];
            if ((x == 0 || x == m - 1 || y == 0 || y == n - 1) && (x != entrance[0] || y != entrance[1]))
                return steps;

            for (int[] dir : directions) {
                int xx = x + dir[0];
                int yy = y + dir[1];
                if (xx >= 0 && xx < m && yy >= 0 && yy < n && maze[xx][yy] == '.') {
                    maze[xx][yy] = '+';
                    q.offer(new int[]{xx, yy});
                }
            }
        }
        ++steps;
    }

    return -1;
}
```
The algorithm uses Breadth-First Search (BFS) to traverse the maze. It first marks the entrance as a wall ('+'). Then it adds the entrance coordinates to a queue. We also declare a variable to keep track of steps.

While the queue is not empty, we iterate through each level of the BFS tree, processing each cell at a given depth. We check if the current cell is at the border of the maze and not the entrance cell. If so, we return the current number of steps.

If the current cell does not satisfy the exit condition, we explore its adjacent cells. We iterate through each possible direction (up, down, left, and right) and calculate the next cell's coordinates. If the next cell is inside the maze and not a wall, we mark the next cell as a wall ('+') and add it to the queue. After processing all cells at the current depth, we increment the steps.

If the BFS is completed and there is no valid exit, return -1.

## A solution in C++

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

int nearestExit(vector<vector<char>>& maze, vector<int>& entrance) {
    int m = maze.size();
    int n = maze[0].size();
    vector<vector<int>> directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    queue<pair<int, int>> q;
    maze[entrance[0]][entrance[1]] = '+';
    q.push({entrance[0], entrance[1]});
    int steps = 0;

    while (!q.empty()) {
        int size = q.size();
        for (int i = 0; i < size; ++i) {
            pair<int, int> cur = q.front(); q.pop();
            int x = cur.first;
            int y = cur.second;
            if ((x == 0 || x == m - 1 || y == 0 || y == n - 1) && (x != entrance[0] || y != entrance[1]))
                return steps;

            for (auto dir : directions) {
                int xx = x + dir[0];
                int yy = y + dir[1];
                if (xx >= 0 && xx < m && yy >= 0 && yy < n && maze[xx][yy] == '.') {
                    maze[xx][yy] = '+';
                    q.push({xx, yy});
                }
            }
        }
        ++steps;
    }

    return -1;
}
```
The algorithm uses Breadth-First Search (BFS) to traverse the maze. It first marks the entrance as a wall ('+'). Then it adds the entrance coordinates to a queue. We also declare a variable to keep track of steps.

While the queue is not empty, we iterate through each level of the BFS tree, processing each cell at a given depth. We check if the current cell is at the border of the maze and not the entrance cell. If so, we return the current number of steps.

If the current cell does not satisfy the exit condition, we explore its adjacent cells. We iterate through each possible direction (up, down, left, and right) and calculate the next cell's coordinates. If the next cell is inside the maze and not a wall, we mark the next cell as a wall ('+') and add it to the queue. After processing all cells at the current depth, we increment the steps.

If the BFS is completed and there is no valid exit, return -1.

## A solution in Python

```python
from collections import deque

def nearest_exit(maze, entrance):
    m, n = len(maze), len(maze[0])
    directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
    q = deque()
    maze[entrance[0]][entrance[1]] = '+'
    q.append((entrance[0], entrance[1]))
    steps = 0

    while q:
        size = len(q)
        for _ in range(size):
            x, y = q.popleft()
            if (x == 0 or x == m - 1 or y == 0 or y == n - 1) and (x != entrance[0] or y != entrance[1]):
                return steps

            for dir in directions:
                xx, yy = x + dir[0], y + dir[1]
                if 0 <= xx < m and 0 <= yy < n and maze[xx][yy] == '.':
                    maze[xx][yy] = '+'
                    q.append((xx, yy))
        steps += 1

    return -1
```
The algorithm uses Breadth-First Search (BFS) to traverse the maze. It first marks the entrance as a wall ('+'). Then it adds the entrance coordinates to a queue. We also declare a variable to keep track of steps.

While the queue is not empty, we iterate through each level of the BFS tree, processing each cell at a given depth. We check if the current cell is at the border of the maze and not the entrance cell. If so, we return the current number of steps.

If the current cell does not satisfy the exit condition, we explore its adjacent cells. We iterate through each possible direction (up, down, left, and right) and calculate the next cell's coordinates. If the next cell is inside the maze and not a wall, we mark the next cell as a wall ('+') and add it to the queue. After processing all cells at the current depth, we increment the steps.

If the BFS is completed and there is no valid exit, return -1.

## A solution in Javascript

```javascript
function nearestExit(maze, entrance) {
    const m = maze.length;
    const n = maze[0].length;
    const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]];
    const q = [];
    maze[entrance[0]][entrance[1]] = '+';
    q.push([entrance[0], entrance[1]]);
    let steps = 0;

    while (q.length > 0) {
        const size = q.length;
        for (let i = 0; i < size; ++i) {
            const [x, y] = q.shift();
            if ((x === 0 || x === m - 1 || y === 0 || y === n - 1) && (x !== entrance[0] || y !== entrance[1]))
                return steps;

            for (const dir of directions) {
                const xx = x + dir[0];
                const yy = y + dir[1];
                if (xx >= 0 && xx < m && yy >= 0 && yy < n && maze[xx][yy] === '.') {
                    maze[xx][yy] = '+';
                    q.push([xx, yy]);
                }
            }
        }
        ++steps;
    }

    return -1;
}
```
The algorithm uses Breadth-First Search (BFS) to traverse the maze. It first marks the entrance as a wall ('+'). Then it adds the entrance coordinates to a queue. We also declare a variable to keep track of steps.

While the queue is not empty, we iterate through each level of the BFS tree, processing each cell at a given depth. We check if the current cell is at the border of the maze and not the entrance cell. If so, we return the current number of steps.

If the current cell does not satisfy the exit condition, we explore its adjacent cells. We iterate through each possible direction (up, down, left, and right) and calculate the next cell's coordinates. If the next cell is inside the maze and not a wall, we mark the next cell as a wall ('+') and add it to the queue. After processing all cells at the current depth, we increment the steps.

If the BFS is completed and there is no valid exit, return -1.


# The Time When the Network Becomes Idle

- slug: the-time-when-the-network-becomes-idle
- difficulty: Medium

There is a network of `n` servers, labeled from `0` to `n - 1`. You are given a 2D integer array `edges`, where `edges[i] = [ui, vi]` indicates there is a message channel between servers `ui` and `vi`, and they can pass **any** number of messages to **each other** directly in **one** second. You are also given a **0-indexed** integer array `patience` of length `n`.

All servers are **connected**, i.e., a message can be passed from one server to any other server(s) directly or indirectly through the message channels.

The server labeled `0` is the **master** server. The rest are **data** servers. Each data server needs to send its message to the master server for processing and wait for a reply. Messages move between servers **optimally**, so every message takes the **least amount of time** to arrive at the master server. The master server will process all newly arrived messages **instantly** and send a reply to the originating server via the **reversed path** the message had gone through.

At the beginning of second `0`, each data server sends its message to be processed. Starting from second `1`, at the **beginning** of **every** second, each data server will check if it has received a reply to the message it sent (including any newly arrived replies) from the master server:

*   If it has not, it will **resend** the message periodically. The data server `i` will resend the message every `patience[i]` second(s), i.e., the data server `i` will resend the message if `patience[i]` second(s) have **elapsed** since the **last** time the message was sent from this server.
*   Otherwise, **no more resending** will occur from this server.

The network becomes **idle** when there are **no** messages passing between servers or arriving at servers.

Return _the **earliest second** starting from which the network becomes **idle**_.

**Example 1:**

**Input:** edges = \[\[0,1\],\[1,2\]\], patience = \[0,2,1\]
**Output:** 8
**Explanation:**
At (the beginning of) second 0,
- Data server 1 sends its message (denoted 1A) to the master server.
- Data server 2 sends its message (denoted 2A) to the master server.

At second 1,
- Message 1A arrives at the master server. Master server processes message 1A instantly and sends a reply 1A back.
- Server 1 has not received any reply. 1 second (1 < patience\[1\] = 2) elapsed since this server has sent the message, therefore it does not resend the message.
- Server 2 has not received any reply. 1 second (1 == patience\[2\] = 1) elapsed since this server has sent the message, therefore it resends the message (denoted 2B).

At second 2,
- The reply 1A arrives at server 1. No more resending will occur from server 1.
- Message 2A arrives at the master server. Master server processes message 2A instantly and sends a reply 2A back.
- Server 2 resends the message (denoted 2C).
...
At second 4,
- The reply 2A arrives at server 2. No more resending will occur from server 2.
...
At second 7, reply 2D arrives at server 2.

Starting from the beginning of the second 8, there are no messages passing between servers or arriving at servers.
This is the time when the network becomes idle.

**Example 2:**

**Input:** edges = \[\[0,1\],\[0,2\],\[1,2\]\], patience = \[0,10,10\]
**Output:** 3
**Explanation:** Data servers 1 and 2 receive a reply back at the beginning of second 2.
From the beginning of the second 3, the network becomes idle.

**Constraints:**

*   `n == patience.length`
*   `2 <= n <= 105`
*   `patience[0] == 0`
*   `1 <= patience[i] <= 105` for `1 <= i < n`
*   `1 <= edges.length <= min(105, n * (n - 1) / 2)`
*   `edges[i].length == 2`
*   `0 <= ui, vi < n`
*   `ui != vi`
*   There are no duplicate edges.
*   Each server can directly or indirectly reach another server.

## A solution in Java

```java
public boolean sumGame(String num) {
    int n = num.length();
    int sum1 = 0, sum2 = 0, cnt1 = 0, cnt2 = 0;

    for (int i = 0; i < n / 2; i++) {
        if (num.charAt(i) == '?') cnt1++;
        else sum1 += num.charAt(i) - '0';
    }

    for (int i = n / 2; i < n; i++) {
        if (num.charAt(i) == '?') cnt2++;
        else sum2 += num.charAt(i) - '0';
    }

    return ((sum1 - sum2) != ((cnt2 - cnt1) / 2) * 9);
}
```
The algorithm starts by initializing variables for the lengths of `num`, the sums of the first and second half of `num`, and the count of '?' in the first and second half of `num`.

For each half of the string `num`, we iterate through and check if the current character is '?'. If it is, we increment the corresponding '?' counter. If not, we add the integer value `num[i]` to the corresponding sum.

To check if Alice will win, we compute `(sum1 - sum2)` and compare it to `((cnt2 - cnt1) / 2) * 9`. If they are not equal, Alice will win, and we return `true`. If they are equal, Bob will win, and we return `false`. This calculation is based on the fact that an optimal play will create the biggest difference possible between the sums; players will add 9 (the maximum digit) to their sum when allowed.

In the JavaScript version, we use `Math.floor` to achieve integer division for the false case check.

## A solution in C++

```cpp
bool sumGame(string num) {
    int n = num.size();
    int sum1 = 0, sum2 = 0, cnt1 = 0, cnt2 = 0;

    for (int i = 0; i < n / 2; i++) {
        if (num[i] == '?') cnt1++;
        else sum1 += num[i] - '0';
    }

    for (int i = n / 2; i < n; i++) {
        if (num[i] == '?') cnt2++;
        else sum2 += num[i] - '0';
    }

    return ((sum1 - sum2) != ((cnt2 - cnt1) / 2) * 9);
}
```
The algorithm starts by initializing variables for the lengths of `num`, the sums of the first and second half of `num`, and the count of '?' in the first and second half of `num`.

For each half of the string `num`, we iterate through and check if the current character is '?'. If it is, we increment the corresponding '?' counter. If not, we add the integer value `num[i]` to the corresponding sum.

To check if Alice will win, we compute `(sum1 - sum2)` and compare it to `((cnt2 - cnt1) / 2) * 9`. If they are not equal, Alice will win, and we return `true`. If they are equal, Bob will win, and we return `false`. This calculation is based on the fact that an optimal play will create the biggest difference possible between the sums; players will add 9 (the maximum digit) to their sum when allowed.

In the JavaScript version, we use `Math.floor` to achieve integer division for the false case check.

## A solution in Python

```python
def sumGame(num: str) -> bool:
    n = len(num)
    sum1, sum2, cnt1, cnt2 = 0, 0, 0, 0

    for i in range(n // 2):
        if num[i] == '?': cnt1 += 1
        else: sum1 += int(num[i])

    for i in range(n // 2, n):
        if num[i] == '?': cnt2 += 1
        else: sum2 += int(num[i])

    return (sum1 - sum2) != ((cnt2 - cnt1) // 2) * 9
```
The algorithm starts by initializing variables for the lengths of `num`, the sums of the first and second half of `num`, and the count of '?' in the first and second half of `num`.

For each half of the string `num`, we iterate through and check if the current character is '?'. If it is, we increment the corresponding '?' counter. If not, we add the integer value `num[i]` to the corresponding sum.

To check if Alice will win, we compute `(sum1 - sum2)` and compare it to `((cnt2 - cnt1) / 2) * 9`. If they are not equal, Alice will win, and we return `true`. If they are equal, Bob will win, and we return `false`. This calculation is based on the fact that an optimal play will create the biggest difference possible between the sums; players will add 9 (the maximum digit) to their sum when allowed.

In the JavaScript version, we use `Math.floor` to achieve integer division for the false case check.

## A solution in Javascript

```javascript
function sumGame(num) {
    let n = num.length;
    let sum1 = 0, sum2 = 0, cnt1 = 0, cnt2 = 0;

    for (let i = 0; i < n / 2; i++) {
        if (num[i] === '?') cnt1++;
        else sum1 += parseInt(num[i]);
    }

    for (let i = n / 2; i < n; i++) {
        if (num[i] === '?') cnt2++;
        else sum2 += parseInt(num[i]);
    }

    return (sum1 - sum2) !== Math.floor((cnt2 - cnt1) / 2) * 9;
}
```
The algorithm starts by initializing variables for the lengths of `num`, the sums of the first and second half of `num`, and the count of '?' in the first and second half of `num`.

For each half of the string `num`, we iterate through and check if the current character is '?'. If it is, we increment the corresponding '?' counter. If not, we add the integer value `num[i]` to the corresponding sum.

To check if Alice will win, we compute `(sum1 - sum2)` and compare it to `((cnt2 - cnt1) / 2) * 9`. If they are not equal, Alice will win, and we return `true`. If they are equal, Bob will win, and we return `false`. This calculation is based on the fact that an optimal play will create the biggest difference possible between the sums; players will add 9 (the maximum digit) to their sum when allowed.

In the JavaScript version, we use `Math.floor` to achieve integer division for the false case check.


# Kth Smallest Product of Two Sorted Arrays

- slug: kth-smallest-product-of-two-sorted-arrays
- difficulty: Hard

Given two **sorted 0-indexed** integer arrays `nums1` and `nums2` as well as an integer `k`, return _the_ `kth` _(**1-based**) smallest product of_ `nums1[i] * nums2[j]` _where_ `0 <= i < nums1.length` _and_ `0 <= j < nums2.length`.

**Example 1:**

**Input:** nums1 = \[2,5\], nums2 = \[3,4\], k = 2
**Output:** 8
**Explanation:** The 2 smallest products are:
- nums1\[0\] \* nums2\[0\] = 2 \* 3 = 6
- nums1\[0\] \* nums2\[1\] = 2 \* 4 = 8
The 2nd smallest product is 8.

**Example 2:**

**Input:** nums1 = \[-4,-2,0,3\], nums2 = \[2,4\], k = 6
**Output:** 0
**Explanation:** The 6 smallest products are:
- nums1\[0\] \* nums2\[1\] = (-4) \* 4 = -16
- nums1\[0\] \* nums2\[0\] = (-4) \* 2 = -8
- nums1\[1\] \* nums2\[1\] = (-2) \* 4 = -8
- nums1\[1\] \* nums2\[0\] = (-2) \* 2 = -4
- nums1\[2\] \* nums2\[0\] = 0 \* 2 = 0
- nums1\[2\] \* nums2\[1\] = 0 \* 4 = 0
The 6th smallest product is 0.

**Example 3:**

**Input:** nums1 = \[-2,-1,0,1,2\], nums2 = \[-3,-1,2,4,5\], k = 3
**Output:** -6
**Explanation:** The 3 smallest products are:
- nums1\[0\] \* nums2\[4\] = (-2) \* 5 = -10
- nums1\[0\] \* nums2\[3\] = (-2) \* 4 = -8
- nums1\[4\] \* nums2\[0\] = 2 \* (-3) = -6
The 3rd smallest product is -6.

**Constraints:**

*   `1 <= nums1.length, nums2.length <= 5 * 104`
*   `-105 <= nums1[i], nums2[j] <= 105`
*   `1 <= k <= nums1.length * nums2.length`
*   `nums1` and `nums2` are sorted.

## A solution in Java

```java
import java.util.*;

class Solution {
    public int minCost(int maxTime, int[][] edges, int[] passingFees) {
        int n = passingFees.length;
        List<List<int[]>> graph = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            graph.add(new ArrayList<>());
        }
        for (int[] edge : edges) {
            graph.get(edge[0]).add(new int[]{edge[1], edge[2]});
            graph.get(edge[1]).add(new int[]{edge[0], edge[2]});
        }

        int[][] dp = new int[n][maxTime + 1];
        for (int i = 0; i < n; i++) {
            Arrays.fill(dp[i], Integer.MAX_VALUE);
        }
        dp[0][0] = passingFees[0];

        PriorityQueue<int[]> pq = new PriorityQueue<>(Comparator.comparingInt(arr -> arr[2]));
        pq.offer(new int[]{0, 0, passingFees[0]});

        while (!pq.isEmpty()) {
            int[] cur = pq.poll();
            int time = cur[0], city = cur[1], cost = cur[2];
            if (city == n - 1) {
                return cost;
            }

            for (int[] neighbor : graph.get(city)) {
                int next_time = time + neighbor[1];
                if (next_time > maxTime) continue;

                int new_cost = cost + passingFees[neighbor[0]];
                if (new_cost < dp[neighbor[0]][next_time]) {
                    dp[neighbor[0]][next_time] = new_cost;
                    pq.offer(new int[]{next_time, neighbor[0], new_cost});
                }
            }
        }
        return -1;
    }
}
```
We will use a variation of Dijkstra's algorithm to find the minimum journey cost. Create adjacency list representation of the given graph. Initialize `dp[][`] as an `n * (maxTime + 1)` array storing the minimum cost to reach the ith city within a given time j. Initially, set `dp[0][0]` as the value of passingFees[0] since we're at city 0.

We use a priority queue to store nodes with the current time, city, and cost in that moment. To achieve this, we implement a min-heap where nodes are sorted based on their cost. Push the initial state (0, 0, passingFees[0]) into the min-heap. Now for each iteration, take the top node (which has the minimum cost), and for each neighbor of this city, check the required time for the next step. If it's under maxTime, calculate a new cost for reaching that neighbor city.

If the new calculated cost for reaching that neighbor city is less than the current value of `dp[neighbor][next_time]`, update its value and push the new state (next_time, neighbor, new_cost) into the min-heap.

Repeat this process until your min-heap becomes empty or you find a suitable path to the last city (index n-1). If you reach the final city, you can return the cost of that state, otherwise return -1, which is an indication that there is no possible path within the given maxTime.

## A solution in C++

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

using namespace std;

int minCost(int maxTime, vector<vector<int>>& edges, vector<int>& passingFees) {
    int n = passingFees.size();
    vector<vector<pair<int, int>>> graph(n);
    for (const auto& edge : edges) {
        graph[edge[0]].emplace_back(edge[1], edge[2]);
        graph[edge[1]].emplace_back(edge[0], edge[2]);
    }

    vector<vector<int>> dp(n, vector<int>(maxTime + 1, INT_MAX));
    dp[0][0] = passingFees[0];
    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;
    pq.emplace(0, 0, passingFees[0]);

    while (!pq.empty()) {
        auto [time, city, cost] = pq.top();
        pq.pop();
        if (city == n - 1) {
            return cost;
        }
        for (const auto& [neighbor, t] : graph[city]) {
            int next_time = time + t;
            if (next_time > maxTime) continue;
            int new_cost = cost + passingFees[neighbor];
            if (new_cost < dp[neighbor][next_time]) {
                dp[neighbor][next_time] = new_cost;
                pq.emplace(next_time, neighbor, new_cost);
            }
        }
    }

    return -1;
}
```
We will use a variation of Dijkstra's algorithm to find the minimum journey cost. Create adjacency list representation of the given graph. Initialize `dp[][`] as an `n * (maxTime + 1)` array storing the minimum cost to reach the ith city within a given time j. Initially, set `dp[0][0]` as the value of passingFees[0] since we're at city 0.

We use a priority queue to store nodes with the current time, city, and cost in that moment. To achieve this, we implement a min-heap where nodes are sorted based on their cost. Push the initial state (0, 0, passingFees[0]) into the min-heap. Now for each iteration, take the top node (which has the minimum cost), and for each neighbor of this city, check the required time for the next step. If it's under maxTime, calculate a new cost for reaching that neighbor city.

If the new calculated cost for reaching that neighbor city is less than the current value of `dp[neighbor][next_time]`, update its value and push the new state (next_time, neighbor, new_cost) into the min-heap.

Repeat this process until your min-heap becomes empty or you find a suitable path to the last city (index n-1). If you reach the final city, you can return the cost of that state, otherwise return -1, which is an indication that there is no possible path within the given maxTime.

## A solution in Python

```python
import heapq
from collections import defaultdict

def minCost(maxTime, edges, passingFees):
    n = len(passingFees)
    graph = defaultdict(list)
    for x, y, time in edges:
        graph[x].append((y, time))
        graph[y].append((x, time))

    dp = [[float('inf')] * (maxTime + 1) for _ in range(n)]
    dp[0][0] = passingFees[0]

    pq = [(0, 0, passingFees[0])]
    while pq:
        time, city, cost = heapq.heappop(pq)
        if city == n - 1:
            return cost

        for neighbor, t in graph[city]:
            next_time = time + t
            if next_time > maxTime:
                continue

            new_cost = cost + passingFees[neighbor]
            if new_cost < dp[neighbor][next_time]:
                dp[neighbor][next_time] = new_cost
                heapq.heappush(pq, (next_time, neighbor, new_cost))

    return -1
```
We will use a variation of Dijkstra's algorithm to find the minimum journey cost. Create adjacency list representation of the given graph. Initialize `dp[][`] as an `n * (maxTime + 1)` array storing the minimum cost to reach the ith city within a given time j. Initially, set `dp[0][0]` as the value of passingFees[0] since we're at city 0.

We use a priority queue to store nodes with the current time, city, and cost in that moment. To achieve this, we implement a min-heap where nodes are sorted based on their cost. Push the initial state (0, 0, passingFees[0]) into the min-heap. Now for each iteration, take the top node (which has the minimum cost), and for each neighbor of this city, check the required time for the next step. If it's under maxTime, calculate a new cost for reaching that neighbor city.

If the new calculated cost for reaching that neighbor city is less than the current value of `dp[neighbor][next_time]`, update its value and push the new state (next_time, neighbor, new_cost) into the min-heap.

Repeat this process until your min-heap becomes empty or you find a suitable path to the last city (index n-1). If you reach the final city, you can return the cost of that state, otherwise return -1, which is an indication that there is no possible path within the given maxTime.

## A solution in Javascript

```javascript
function minCost(maxTime, edges, passingFees) {
    const n = passingFees.length;
    const graph = new Array(n).fill(null).map(() => []);
    for (const edge of edges) {
        graph[edge[0]].push([edge[1], edge[2]]);
        graph[edge[1]].push([edge[0], edge[2]]);
    }

    const dp = new Array(n).fill(null).map(() => new Array(maxTime + 1).fill(Infinity));
    dp[0][0] = passingFees[0];

    const pq = [[0, 0, passingFees[0]]];
    while (pq.length > 0) {
        pq.sort((a, b) => a[2] - b[2]);
        const [time, city, cost] = pq.shift();
        if (city === n - 1) {
            return cost;
        }

        for (const [neighbor, t] of graph[city]) {
            const next_time = time + t;
            if (next_time > maxTime) continue;

            const new_cost = cost + passingFees[neighbor];
            if (new_cost < dp[neighbor][next_time]) {
                dp[neighbor][next_time] = new_cost;
                pq.push([next_time, neighbor, new_cost]);
            }
        }
    }

    return -1;
}
```
We will use a variation of Dijkstra's algorithm to find the minimum journey cost. Create adjacency list representation of the given graph. Initialize `dp[][`] as an `n * (maxTime + 1)` array storing the minimum cost to reach the ith city within a given time j. Initially, set `dp[0][0]` as the value of passingFees[0] since we're at city 0.

We use a priority queue to store nodes with the current time, city, and cost in that moment. To achieve this, we implement a min-heap where nodes are sorted based on their cost. Push the initial state (0, 0, passingFees[0]) into the min-heap. Now for each iteration, take the top node (which has the minimum cost), and for each neighbor of this city, check the required time for the next step. If it's under maxTime, calculate a new cost for reaching that neighbor city.

If the new calculated cost for reaching that neighbor city is less than the current value of `dp[neighbor][next_time]`, update its value and push the new state (next_time, neighbor, new_cost) into the min-heap.

Repeat this process until your min-heap becomes empty or you find a suitable path to the last city (index n-1). If you reach the final city, you can return the cost of that state, otherwise return -1, which is an indication that there is no possible path within the given maxTime.