# Count Lattice Points Inside a Circle

- slug: count-lattice-points-inside-a-circle
- difficulty: Medium

Given a 2D integer array `circles` where `circles[i] = [xi, yi, ri]` represents the center `(xi, yi)` and radius `ri` of the `ith` circle drawn on a grid, return _the **number of lattice points**_ _that are present inside **at least one** circle_.

**Note:**

*   A **lattice point** is a point with integer coordinates.
*   Points that lie **on the circumference of a circle** are also considered to be inside it.

**Example 1:**

**Input:** circles = \[\[2,2,1\]\]
**Output:** 5
**Explanation:**
The figure above shows the given circle.
The lattice points present inside the circle are (1, 2), (2, 1), (2, 2), (2, 3), and (3, 2) and are shown in green.
Other points such as (1, 1) and (1, 3), which are shown in red, are not considered inside the circle.
Hence, the number of lattice points present inside at least one circle is 5.

**Example 2:**

**Input:** circles = \[\[2,2,2\],\[3,4,1\]\]
**Output:** 16
**Explanation:**
The figure above shows the given circles.
There are exactly 16 lattice points which are present inside at least one circle.
Some of them are (0, 2), (2, 0), (2, 4), (3, 2), and (4, 4).

**Constraints:**

*   `1 <= circles.length <= 200`
*   `circles[i].length == 3`
*   `1 <= xi, yi <= 100`
*   `1 <= ri <= min(xi, yi)`

## A solution in Java

```java
int countSequences(int[] differences, int lower, int upper) {
    int count = 0, n = differences.length;
    int[] hidden = new int[n + 1];

    hidden[0] = lower;
    while (true) {
        boolean valid = true;
        for (int i = 1; i <= n; i++) {
            hidden[i] = hidden[i - 1] + differences[i - 1];
            if (hidden[i] < lower || hidden[i] > upper) {
                valid = false;
                break;
            }
        }
        if (valid) count++;

        if (hidden[0] == upper) break;
        hidden[0]++;
    }
    return count;
}
```
We initialize a `count` variable to keep track of the number of valid hidden sequences found so far, and an `n` variable to store the length of the `differences` array. Then, we create a `hidden` array, initialized with the `lower` value as the first element, and run a while loop until the first element of `hidden` is equal to the `upper` value.

Inside the loop, we set a `valid` variable to true, and iterate through each index `i` of length `n + 1`. At each iteration, we calculate the difference between consecutive hidden sequence elements using `differences[i - 1]`. If the resulting value is outside the range `[lower, upper]`, set `valid` to false and break the loop.

After iterating through all elements, if `valid` is still true, increment the `count` variable. At the end of the while loop, increment the value of the first element of `hidden`. The loop will continue until the first element of `hidden` is equal to the `upper` value. Finally, return the `count` variable, which holds the number of possible hidden sequences.

## A solution in C++

```cpp
#include <vector>

int countSequences(std::vector<int> &differences, int lower, int upper) {
    int count = 0, n = differences.size();
    std::vector<int> hidden(n + 1);

    hidden[0] = lower;
    while (true) {
        bool valid = 1;
        for (int i = 1; i <= n; i++) {
            hidden[i] = hidden[i - 1] + differences[i - 1];
            if (hidden[i] < lower || hidden[i] > upper) {
                valid = 0;
                break;
            }
        }
        if (valid) count++;

        if (hidden[0] == upper) break;
        hidden[0]++;
    }
    return count;
}
```
We initialize a `count` variable to keep track of the number of valid hidden sequences found so far, and an `n` variable to store the length of the `differences` array. Then, we create a `hidden` array, initialized with the `lower` value as the first element, and run a while loop until the first element of `hidden` is equal to the `upper` value.

Inside the loop, we set a `valid` variable to true, and iterate through each index `i` of length `n + 1`. At each iteration, we calculate the difference between consecutive hidden sequence elements using `differences[i - 1]`. If the resulting value is outside the range `[lower, upper]`, set `valid` to false and break the loop.

After iterating through all elements, if `valid` is still true, increment the `count` variable. At the end of the while loop, increment the value of the first element of `hidden`. The loop will continue until the first element of `hidden` is equal to the `upper` value. Finally, return the `count` variable, which holds the number of possible hidden sequences.

## A solution in Python

```python
def count_sequences(differences, lower, upper):
    count = 0
    n = len(differences)
    hidden = [0] * (n + 1)

    hidden[0] = lower
    while True:
        valid = True
        for i in range(1, n + 1):
            hidden[i] = hidden[i - 1] + differences[i - 1]
            if hidden[i] < lower or hidden[i] > upper:
                valid = False
                break
        if valid: count += 1

        if hidden[0] == upper: break
        hidden[0] += 1

    return count
```
We initialize a `count` variable to keep track of the number of valid hidden sequences found so far, and an `n` variable to store the length of the `differences` array. Then, we create a `hidden` array, initialized with the `lower` value as the first element, and run a while loop until the first element of `hidden` is equal to the `upper` value.

Inside the loop, we set a `valid` variable to true, and iterate through each index `i` of length `n + 1`. At each iteration, we calculate the difference between consecutive hidden sequence elements using `differences[i - 1]`. If the resulting value is outside the range `[lower, upper]`, set `valid` to false and break the loop.

After iterating through all elements, if `valid` is still true, increment the `count` variable. At the end of the while loop, increment the value of the first element of `hidden`. The loop will continue until the first element of `hidden` is equal to the `upper` value. Finally, return the `count` variable, which holds the number of possible hidden sequences.

## A solution in Javascript

```javascript
function countSequences(differences, lower, upper) {
    let count = 0, n = differences.length;
    let hidden = new Array(n + 1);

    hidden[0] = lower;
    while (true) {
        let valid = true;
        for (let i = 1; i <= n; i++) {
            hidden[i] = hidden[i - 1] + differences[i - 1];
            if (hidden[i] < lower || hidden[i] > upper) {
                valid = false;
                break;
            }
        }
        if (valid) count++;

        if (hidden[0] === upper) break;
        hidden[0]++;
    }
    return count;
}
```
We initialize a `count` variable to keep track of the number of valid hidden sequences found so far, and an `n` variable to store the length of the `differences` array. Then, we create a `hidden` array, initialized with the `lower` value as the first element, and run a while loop until the first element of `hidden` is equal to the `upper` value.

Inside the loop, we set a `valid` variable to true, and iterate through each index `i` of length `n + 1`. At each iteration, we calculate the difference between consecutive hidden sequence elements using `differences[i - 1]`. If the resulting value is outside the range `[lower, upper]`, set `valid` to false and break the loop.

After iterating through all elements, if `valid` is still true, increment the `count` variable. At the end of the while loop, increment the value of the first element of `hidden`. The loop will continue until the first element of `hidden` is equal to the `upper` value. Finally, return the `count` variable, which holds the number of possible hidden sequences.


# Count Number of Rectangles Containing Each Point

- slug: count-number-of-rectangles-containing-each-point
- difficulty: Medium

You are given a 2D integer array `rectangles` where `rectangles[i] = [li, hi]` indicates that `ith` rectangle has a length of `li` and a height of `hi`. You are also given a 2D integer array `points` where `points[j] = [xj, yj]` is a point with coordinates `(xj, yj)`.

The `ith` rectangle has its **bottom-left corner** point at the coordinates `(0, 0)` and its **top-right corner** point at `(li, hi)`.

Return _an integer array_ `count` _of length_ `points.length` _where_ `count[j]` _is the number of rectangles that **contain** the_ `jth` _point._

The `ith` rectangle **contains** the `jth` point if `0 <= xj <= li` and `0 <= yj <= hi`. Note that points that lie on the **edges** of a rectangle are also considered to be contained by that rectangle.

**Example 1:**

**Input:** rectangles = \[\[1,2\],\[2,3\],\[2,5\]\], points = \[\[2,1\],\[1,4\]\]
**Output:** \[2,1\]
**Explanation:**
The first rectangle contains no points.
The second rectangle contains only the point (2, 1).
The third rectangle contains the points (2, 1) and (1, 4).
The number of rectangles that contain the point (2, 1) is 2.
The number of rectangles that contain the point (1, 4) is 1.
Therefore, we return \[2, 1\].

**Example 2:**

**Input:** rectangles = \[\[1,1\],\[2,2\],\[3,3\]\], points = \[\[1,3\],\[1,1\]\]
**Output:** \[1,3\]
**Explanation:**
The first rectangle contains only the point (1, 1).
The second rectangle contains only the point (1, 1).
The third rectangle contains the points (1, 3) and (1, 1).
The number of rectangles that contain the point (1, 3) is 1.
The number of rectangles that contain the point (1, 1) is 3.
Therefore, we return \[1, 3\].

**Constraints:**

*   `1 <= rectangles.length, points.length <= 5 * 104`
*   `rectangles[i].length == points[j].length == 2`
*   `1 <= li, xj <= 109`
*   `1 <= hi, yj <= 100`
*   All the `rectangles` are **unique**.
*   All the `points` are **unique**.

## A solution in Java

```java
import java.util.*;

class Solution {
    public int[][] kHighestRankedItems(int[][] grid, int[] pricing, int[] start, int k) {
        int m = grid.length, n = grid[0].length;
        int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
        List<int[]> res = new ArrayList<>();
        PriorityQueue<int[]> pq = new PriorityQueue<>(Comparator.comparingInt(a -> a[0] * 1000000 - a[1]));
        boolean[][] visited = new boolean[m][n];

        pq.offer(new int[]{0, -grid[start[0]][start[1]], start[0], start[1]});
        visited[start[0]][start[1]] = true;

        while (!pq.isEmpty() && k > 0) {
            int size = pq.size();
            for (int i = 0; i < size; i++) {
                int[] curr = pq.poll();
                int steps = curr[0], price = -curr[1], row = curr[2], col = curr[3];

                if (price >= pricing[0] && price <= pricing[1]) {
                    res.add(new int[]{row, col});
                    k--;
                }

                for (int[] direction : directions) {
                    int newRow = row + direction[0];
                    int newCol = col + direction[1];
                    if (newRow >= 0 && newRow < m && newCol >= 0 && newCol < n && !visited[newRow][newCol]) {
                        visited[newRow][newCol] = true;
                        pq.offer(new int[]{steps + 1, -grid[newRow][newCol], newRow, newCol});
                    }
                }
            }
        }

        int[][] result = new int[res.size()][2];
        for (int i = 0; i < res.size(); i++) {
            result[i] = res.get(i);
        }
        return result;
    }
}
```
The algorithm uses a priority queue (min-heap) for visiting nodes sorted by the number of steps first and the price of the item second. In each iteration, we pop the element with the highest priority (meaning the lowest number of steps to reach and highest price) and process the reachable nodes. If the popped element's price is within the given price range, we add the position to the result list, and decrease k. We continue this process until there are no more elements in the priority queue or k reaches 0.

We use a visited matrix to track visited cells and avoid visiting them again.

The time complexity of the algorithm is O(m * n * log(m * n)) since we have at most m * n elements in the priority queue.

## A solution in C++

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

vector<vector<int>> kHighestRankedItems(vector<vector<int>>& grid, vector<int>& pricing, vector<int>& start, int k) {
    int m = grid.size(), n = grid[0].size();
    vector<vector<int>> directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    vector<vector<int>> res;
    priority_queue<vector<int>, vector<vector<int>>, greater<vector<int>>> pq;
    vector<vector<bool>> visited(m, vector<bool>(n));

    pq.push({0, -grid[start[0]][start[1]], start[0], start[1]});
    visited[start[0]][start[1]] = true;

    while (!pq.empty() && k > 0) {
        int size = pq.size();
        for (int i = 0; i < size; i++) {
            auto curr = pq.top();
            pq.pop();
            int steps = curr[0], price = -curr[1], row = curr[2], col = curr[3];

            if (price >= pricing[0] && price <= pricing[1]) {
                res.push_back({row, col});
                k--;
            }

            for (const auto& direction : directions) {
                int newRow = row + direction[0];
                int newCol = col + direction[1];
                if (newRow >= 0 && newRow < m && newCol >= 0 && newCol < n && !visited[newRow][newCol]) {
                    visited[newRow][newCol] = true;
                    pq.push({steps + 1, -grid[newRow][newCol], newRow, newCol});
                }
            }
        }
    }

    return res;
}
```
The algorithm uses a priority queue (min-heap) for visiting nodes sorted by the number of steps first and the price of the item second. In each iteration, we pop the element with the highest priority (meaning the lowest number of steps to reach and highest price) and process the reachable nodes. If the popped element's price is within the given price range, we add the position to the result list, and decrease k. We continue this process until there are no more elements in the priority queue or k reaches 0.

We use a visited matrix to track visited cells and avoid visiting them again.

The time complexity of the algorithm is O(m * n * log(m * n)) since we have at most m * n elements in the priority queue.

## A solution in Python

```python
from heapq import heappush, heappop

def kHighestRankedItems(grid, pricing, start, k):
    m, n = len(grid), len(grid[0])
    directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
    res = []
    pq = []
    visited = [[False for _ in range(n)] for _ in range(m)]

    heappush(pq, (0, -grid[start[0]][start[1]], start[0], start[1]))
    visited[start[0]][start[1]] = True

    while pq and k > 0:
        size = len(pq)
        for _ in range(size):
            curr = heappop(pq)
            steps, price, row, col = curr

            if pricing[0] <= -price <= pricing[1]:
                res.append([row, col])
                k -= 1

            for dr, dc in directions:
                newRow, newCol = row + dr, col + dc
                if 0 <= newRow < m and 0 <= newCol < n and not visited[newRow][newCol]:
                    visited[newRow][newCol] = True
                    heappush(pq, (steps + 1, -grid[newRow][newCol], newRow, newCol))

    return res
```
The algorithm uses a priority queue (min-heap) for visiting nodes sorted by the number of steps first and the price of the item second. In each iteration, we pop the element with the highest priority (meaning the lowest number of steps to reach and highest price) and process the reachable nodes. If the popped element's price is within the given price range, we add the position to the result list, and decrease k. We continue this process until there are no more elements in the priority queue or k reaches 0.

We use a visited matrix to track visited cells and avoid visiting them again.

The time complexity of the algorithm is O(m * n * log(m * n)) since we have at most m * n elements in the priority queue.

## A solution in Javascript

```javascript
function kHighestRankedItems(grid, pricing, start, k) {
    const m = grid.length, n = grid[0].length;
    const directions = [[1, 0], [-1, 0], [0, 1], [0, -1]];
    const res = [];
    const pq = [];
    const visited = Array.from({length: m}, () => Array(n).fill(false));

    pq.push([0, -grid[start[0]][start[1]], start[0], start[1]]);
    visited[start[0]][start[1]] = true;

    while (pq.length > 0 && k > 0) {
        const size = pq.length;
        for (let i = 0; i < size; i++) {
            const curr = pq.shift();
            const [steps, price, row, col] = curr;

            if (price >= pricing[0] && price <= pricing[1]) {
                res.push([row, col]);
                k--;
            }

            for (const [dr, dc] of directions) {
                const newRow = row + dr, newCol = col + dc;
                if (newRow >= 0 && newRow < m && newCol >= 0 && newCol < n && !visited[newRow][newCol]) {
                    visited[newRow][newCol] = true;
                    pq.push([steps + 1, -grid[newRow][newCol], newRow, newCol]);
                }
            }
        }
        pq.sort(([aSteps, aPrice], [bSteps, bPrice]) => aSteps * 1000000 - aPrice - (bSteps * 1000000 - bPrice));
    }

    return res;
}
```
The algorithm uses a priority queue (min-heap) for visiting nodes sorted by the number of steps first and the price of the item second. In each iteration, we pop the element with the highest priority (meaning the lowest number of steps to reach and highest price) and process the reachable nodes. If the popped element's price is within the given price range, we add the position to the result list, and decrease k. We continue this process until there are no more elements in the priority queue or k reaches 0.

We use a visited matrix to track visited cells and avoid visiting them again.

The time complexity of the algorithm is O(m * n * log(m * n)) since we have at most m * n elements in the priority queue.


# Number of Flowers in Full Bloom

- slug: number-of-flowers-in-full-bloom
- difficulty: Hard

You are given a **0-indexed** 2D integer array `flowers`, where `flowers[i] = [starti, endi]` means the `ith` flower will be in **full bloom** from `starti` to `endi` (**inclusive**). You are also given a **0-indexed** integer array `people` of size `n`, where `poeple[i]` is the time that the `ith` person will arrive to see the flowers.

Return _an integer array_ `answer` _of size_ `n`_, where_ `answer[i]` _is the **number** of flowers that are in full bloom when the_ `ith` _person arrives._

**Example 1:**

**Input:** flowers = \[\[1,6\],\[3,7\],\[9,12\],\[4,13\]\], poeple = \[2,3,7,11\]
**Output:** \[1,2,2,2\]
**Explanation:** The figure above shows the times when the flowers are in full bloom and when the people arrive.
For each person, we return the number of flowers in full bloom during their arrival.

**Example 2:**

**Input:** flowers = \[\[1,10\],\[3,3\]\], poeple = \[3,3,2\]
**Output:** \[2,2,1\]
**Explanation:** The figure above shows the times when the flowers are in full bloom and when the people arrive.
For each person, we return the number of flowers in full bloom during their arrival.

**Constraints:**

*   `1 <= flowers.length <= 5 * 104`
*   `flowers[i].length == 2`
*   `1 <= starti <= endi <= 109`
*   `1 <= people.length <= 5 * 104`
*   `1 <= people[i] <= 109`

## A solution in Java

```java
public class Solution {
    final static int MOD = 1000000007;

    public static int corridorWays(String corridor) {
        int n = corridor.length();
        int[] dp = new int[n + 1];
        dp[0] = 1;

        int seats = 0;
        for (int i = 0; i < n; i++) {
            if (corridor.charAt(i) == 'S') {
                seats++;
                if (seats % 2 == 0) {
                    dp[i + 1] = dp[Math.max(0, i - 1)];
                }
                dp[i + 1] = (dp[i] + dp[i + 1]) % MOD;
            } else {
                dp[i + 1] = dp[i];
            }
        }

        return dp[n];
    }
}
```
The algorithm uses dynamic programming to calculate the number of ways to divide the corridor. We use an array `dp` of length `n + 1`, where `dp[i]` represents the number of ways to divide the section of the corridor from index `0` to index `i - 1`. The base case is `dp[0] = 1`, as there is always one way to divide the empty corridor.

The main loop iterates through the corridor, updating the `dp` array depending on whether the element at index `i` is a seat ('S') or a plant ('P'). If the element is a seat, we first count the number of seats encountered so far (stored in the variable `seats`). If the number of seats is even, we update `dp[i + 1]` to `dp[max(0, i - 1)]`. Then, we add `dp[i]` to `dp[i + 1]` and take the remainder modulo `10^9 + 7`. If the element is a plant, we simply set `dp[i + 1]` to `dp[i]`.

Finally, we return the result `dp[n]`.

## A solution in C++

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

const int MOD = 1e9 + 7;

int corridorWays(string corridor) {
    int n = corridor.size();
    vector<int> dp(n + 1, 0);
    dp[0] = 1;

    int seats = 0;
    for (int i = 0; i < n; i++) {
        if (corridor[i] == 'S') {
            seats++;
            if (seats % 2 == 0) {
                dp[i + 1] = dp[max(0, i - 1)];
            }
            dp[i + 1] = (dp[i + 1] + dp[i]) % MOD;
        } else {
            dp[i + 1] = dp[i];
        }
    }

    return dp[n];
}
```
The algorithm uses dynamic programming to calculate the number of ways to divide the corridor. We use an array `dp` of length `n + 1`, where `dp[i]` represents the number of ways to divide the section of the corridor from index `0` to index `i - 1`. The base case is `dp[0] = 1`, as there is always one way to divide the empty corridor.

The main loop iterates through the corridor, updating the `dp` array depending on whether the element at index `i` is a seat ('S') or a plant ('P'). If the element is a seat, we first count the number of seats encountered so far (stored in the variable `seats`). If the number of seats is even, we update `dp[i + 1]` to `dp[max(0, i - 1)]`. Then, we add `dp[i]` to `dp[i + 1]` and take the remainder modulo `10^9 + 7`. If the element is a plant, we simply set `dp[i + 1]` to `dp[i]`.

Finally, we return the result `dp[n]`.

## A solution in Python

```python
MOD = 10**9 + 7

def corridor_ways(corridor):
    n = len(corridor)
    dp = [0] * (n + 1)
    dp[0] = 1

    seats = 0
    for i in range(n):
        if corridor[i] == 'S':
            seats += 1
            if seats % 2 == 0:
                dp[i + 1] = dp[max(0, i - 1)]
            dp[i + 1] = (dp[i] + dp[i + 1]) % MOD
        else:
            dp[i + 1] = dp[i]

    return dp[n]
```
The algorithm uses dynamic programming to calculate the number of ways to divide the corridor. We use an array `dp` of length `n + 1`, where `dp[i]` represents the number of ways to divide the section of the corridor from index `0` to index `i - 1`. The base case is `dp[0] = 1`, as there is always one way to divide the empty corridor.

The main loop iterates through the corridor, updating the `dp` array depending on whether the element at index `i` is a seat ('S') or a plant ('P'). If the element is a seat, we first count the number of seats encountered so far (stored in the variable `seats`). If the number of seats is even, we update `dp[i + 1]` to `dp[max(0, i - 1)]`. Then, we add `dp[i]` to `dp[i + 1]` and take the remainder modulo `10^9 + 7`. If the element is a plant, we simply set `dp[i + 1]` to `dp[i]`.

Finally, we return the result `dp[n]`.

## A solution in Javascript

```javascript
const MOD = 10**9 + 7;

function corridorWays(corridor) {
    const n = corridor.length;
    let dp = new Array(n + 1).fill(0);
    dp[0] = 1;

    let seats = 0;
    for (let i = 0; i < n; i++) {
        if (corridor[i] === 'S') {
            seats++;
            if (seats % 2 === 0) {
                dp[i + 1] = dp[Math.max(0, i - 1)];
            }
            dp[i + 1] = (dp[i] + dp[i + 1]) % MOD;
        } else {
            dp[i + 1] = dp[i];
        }
    }

    return dp[n];
}
```
The algorithm uses dynamic programming to calculate the number of ways to divide the corridor. We use an array `dp` of length `n + 1`, where `dp[i]` represents the number of ways to divide the section of the corridor from index `0` to index `i - 1`. The base case is `dp[0] = 1`, as there is always one way to divide the empty corridor.

The main loop iterates through the corridor, updating the `dp` array depending on whether the element at index `i` is a seat ('S') or a plant ('P'). If the element is a seat, we first count the number of seats encountered so far (stored in the variable `seats`). If the number of seats is even, we update `dp[i + 1]` to `dp[max(0, i - 1)]`. Then, we add `dp[i]` to `dp[i + 1]` and take the remainder modulo `10^9 + 7`. If the element is a plant, we simply set `dp[i + 1]` to `dp[i]`.

Finally, we return the result `dp[n]`.


# Design Video Sharing Platform

- slug: design-video-sharing-platform
- difficulty: Hard

You have a video sharing platform where users can upload and delete videos. Each `video` is a **string** of digits, where the `ith` digit of the string represents the content of the video at minute `i`. For example, the first digit represents the content at minute `0` in the video, the second digit represents the content at minute `1` in the video, and so on. Viewers of videos can also like and dislike videos. Internally, the platform keeps track of the **number of views, likes, and dislikes** on each video.

When a video is uploaded, it is associated with the smallest available integer `videoId` starting from `0`. Once a video is deleted, the `videoId` associated with that video can be reused for another video.

Implement the `VideoSharingPlatform` class:

*   `VideoSharingPlatform()` Initializes the object.
*   `int upload(String video)` The user uploads a `video`. Return the `videoId` associated with the video.
*   `void remove(int videoId)` If there is a video associated with `videoId`, remove the video.
*   `String watch(int videoId, int startMinute, int endMinute)` If there is a video associated with `videoId`, increase the number of views on the video by `1` and return the substring of the video string starting at `startMinute` and ending at `min(endMinute, video.length - 1``)` (**inclusive**). Otherwise, return `"-1 "`.
*   `void like(int videoId)` Increases the number of likes on the video associated with `videoId` by `1` if there is a video associated with `videoId`.
*   `void dislike(int videoId)` Increases the number of dislikes on the video associated with `videoId` by `1` if there is a video associated with `videoId`.
*   `int[] getLikesAndDislikes(int videoId)` Return a **0-indexed** integer array `values` of length `2` where `values[0]` is the number of likes and `values[1]` is the number of dislikes on the video associated with `videoId`. If there is no video associated with `videoId`, return `[-1]`.
*   `int getViews(int videoId)` Return the number of views on the video associated with `videoId`, if there is no video associated with `videoId`, return `-1`.

**Example 1:**

**Input**
\[ "VideoSharingPlatform ",  "upload ",  "upload ",  "remove ",  "remove ",  "upload ",  "watch ",  "watch ",  "like ",  "dislike ",  "dislike ",  "getLikesAndDislikes ",  "getViews "\]
\[\[\], \[ "123 "\], \[ "456 "\], \[4\], \[0\], \[ "789 "\], \[1, 0, 5\], \[1, 0, 1\], \[1\], \[1\], \[1\], \[1\], \[1\]\]
**Output**
\[null, 0, 1, null, null, 0,  "456 ",  "45 ", null, null, null, \[1, 2\], 2\]

**Explanation**
VideoSharingPlatform videoSharingPlatform = new VideoSharingPlatform();
videoSharingPlatform.upload( "123 ");          // The smallest available videoId is 0, so return 0.
videoSharingPlatform.upload( "456 ");          // The smallest available `videoId` is 1, so return 1.
videoSharingPlatform.remove(4);              // There is no video associated with videoId 4, so do nothing.
videoSharingPlatform.remove(0);              // Remove the video associated with videoId 0.
videoSharingPlatform.upload( "789 ");          // Since the video associated with videoId 0 was deleted,
                                             // 0 is the smallest available `videoId`, so return 0.
videoSharingPlatform.watch(1, 0, 5);         // The video associated with videoId 1 is  "456 ".
                                             // The video from minute 0 to min(5, 3 - 1) = 2 is  "456 ", so return  "453 ".
videoSharingPlatform.watch(1, 0, 1);         // The video associated with videoId 1 is  "456 ".
                                             // The video from minute 0 to min(1, 3 - 1) = 1 is  "45 ", so return  "45 ".
videoSharingPlatform.like(1);                // Increase the number of likes on the video associated with videoId 1.
videoSharingPlatform.dislike(1);             // Increase the number of dislikes on the video associated with videoId 1.
videoSharingPlatform.dislike(1);             // Increase the number of dislikes on the video associated with videoId 1.
videoSharingPlatform.getLikesAndDislikes(1); // There is 1 like and 2 dislikes on the video associated with videoId 1, so return \[1, 2\].
videoSharingPlatform.getViews(1);            // The video associated with videoId 1 has 2 views, so return 2.

**Example 2:**

**Input**
\[ "VideoSharingPlatform ",  "remove ",  "watch ",  "like ",  "dislike ",  "getLikesAndDislikes ",  "getViews "\]
\[\[\], \[0\], \[0, 0, 1\], \[0\], \[0\], \[0\], \[0\]\]
**Output**
\[null, null,  "-1 ", null, null, \[-1\], -1\]

**Explanation**
VideoSharingPlatform videoSharingPlatform = new VideoSharingPlatform();
videoSharingPlatform.remove(0);              // There is no video associated with videoId 0, so do nothing.
videoSharingPlatform.watch(0, 0, 1);         // There is no video associated with videoId 0, so return  "-1 ".
videoSharingPlatform.like(0);                // There is no video associated with videoId 0, so do nothing.
videoSharingPlatform.dislike(0);             // There is no video associated with videoId 0, so do nothing.
videoSharingPlatform.getLikesAndDislikes(0); // There is no video associated with videoId 0, so return \[-1\].
videoSharingPlatform.getViews(0);            // There is no video associated with videoId 0, so return -1.

**Constraints:**

*   `1 <= video.length <= 105`
*   The sum of `video.length` over all calls to `upload` does not exceed `105`
*   `video` consists of digits.
*   `0 <= videoId <= 105`
*   `0 <= startMinute < endMinute < 105`
*   `startMinute < video.length`
*   The sum of `endMinute - startMinute` over all calls to `watch` does not exceed `105`.
*   At most `105` calls **in total** will be made to all functions.

## A solution in Java

```java
import java.util.HashSet;

public boolean isValidMatrix(int[][] matrix) {
    int n = matrix.length;
    for (int i = 0; i < n; ++i) {
        HashSet<Integer> row = new HashSet<>(), col = new HashSet<>();
        for (int j = 0; j < n; ++j) {
            row.add(matrix[i][j]);
            col.add(matrix[j][i]);
        }
        if (row.size() != n || col.size() != n)
            return false;
    }
    return true;
}
```
The algorithm iterates through each row and column of the matrix. For each row and column, we use a set to store the unique elements. Then, we check if the sizes of the row and column sets are equal to the matrix size `n`. If they are not equal, this means that the row or column does not contain all integers from 1 to n (inclusive), and we return false. If the loop completes successfully and all row and column sets have size `n`, the matrix is valid, and we return true.

## A solution in C++

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

bool isValidMatrix(std::vector<std::vector<int>>& matrix) {
    int n = matrix.size();
    for (int i = 0; i < n; ++i) {
        std::unordered_set<int> row, col;
        for (int j = 0; j < n; ++j) {
            row.insert(matrix[i][j]);
            col.insert(matrix[j][i]);
        }
        if (row.size() != n || col.size() != n)
            return false;
    }
    return true;
}
```
The algorithm iterates through each row and column of the matrix. For each row and column, we use a set to store the unique elements. Then, we check if the sizes of the row and column sets are equal to the matrix size `n`. If they are not equal, this means that the row or column does not contain all integers from 1 to n (inclusive), and we return false. If the loop completes successfully and all row and column sets have size `n`, the matrix is valid, and we return true.

## A solution in Python

```python
def isValidMatrix(matrix):
    n = len(matrix)
    for i in range(n):
        row = set(matrix[i])
        col = set(matrix[j][i] for j in range(n))
        if len(row) != n or len(col) != n:
            return False
    return True
```
The algorithm iterates through each row and column of the matrix. For each row and column, we use a set to store the unique elements. Then, we check if the sizes of the row and column sets are equal to the matrix size `n`. If they are not equal, this means that the row or column does not contain all integers from 1 to n (inclusive), and we return false. If the loop completes successfully and all row and column sets have size `n`, the matrix is valid, and we return true.

## A solution in Javascript

```javascript
function isValidMatrix(matrix) {
    const n = matrix.length;
    for (let i = 0; i < n; ++i) {
        const row = new Set(), col = new Set();
        for (let j = 0; j < n; ++j) {
            row.add(matrix[i][j]);
            col.add(matrix[j][i]);
        }
        if (row.size !== n || col.size !== n)
            return false;
    }
    return true;
}
```
The algorithm iterates through each row and column of the matrix. For each row and column, we use a set to store the unique elements. Then, we check if the sizes of the row and column sets are equal to the matrix size `n`. If they are not equal, this means that the row or column does not contain all integers from 1 to n (inclusive), and we return false. If the loop completes successfully and all row and column sets have size `n`, the matrix is valid, and we return true.


# Count Prefixes of a Given String

- slug: count-prefixes-of-a-given-string
- difficulty: Easy

You are given a string array `words` and a string `s`, where `words[i]` and `s` comprise only of **lowercase English letters**.

Return _the **number of strings** in_ `words` _that are a **prefix** of_ `s`.

A **prefix** of a string is a substring that occurs at the beginning of the string. A **substring** is a contiguous sequence of characters within a string.

**Example 1:**

**Input:** words = \[ "a ", "b ", "c ", "ab ", "bc ", "abc "\], s =  "abc "
**Output:** 3
**Explanation:**
The strings in words which are a prefix of s =  "abc " are:
 "a ",  "ab ", and  "abc ".
Thus the number of strings in words which are a prefix of s is 3.

**Example 2:**

**Input:** words = \[ "a ", "a "\], s =  "aa "
**Output:** 2
**Explanation:**
Both of the strings are a prefix of s.
Note that the same string can occur multiple times in words, and it should be counted each time.

**Constraints:**

*   `1 <= words.length <= 1000`
*   `1 <= words[i].length, s.length <= 10`
*   `words[i]` and `s` consist of lowercase English letters **only**.

## A solution in Java

```java
public int minSwaps(int[] nums) {
    int ones = 0, maxOnes = 0, currOnes = 0, left = 0;

    for (int num : nums) {
        ones += num;
    }

    for (int right = 0; right < nums.length; ++right) {
        currOnes += nums[right];

        if (right - left + 1 > ones) {
            currOnes -= nums[left];
            ++left;
        }

        maxOnes = Math.max(maxOnes, currOnes);
    }

    return ones - maxOnes;
}
```
1. Count the total number of 1's in the array and store this value in the `ones` variable.
2. Initialize variables `maxOnes`, `currOnes`, and `left` to 0. These will be used to keep track of the maximum number of 1's in a range and our current window.
3. Loop through the array using the `right` variable.
4. Add the value in `nums[right]` to `currOnes`.
5. Check if the window size (between `right` and `left`) is greater than the total number of 1's.
6. If it is, remove the value at `nums[left]` from `currOnes`, then increment `left` to reduce our window size.
7. Update the `maxOnes` variable to store the maximum value between itself and `currOnes`.
8. After looping through the entire array, subtract `maxOnes` from the total `ones`. The result is the minimum number of swaps needed.

## A solution in C++

```cpp
int minSwaps(vector<int>& nums) {
    int ones = 0, maxOnes = 0, currOnes = 0, left = 0;

    for (int num : nums) {
        ones += num;
    }

    for (int right = 0; right < nums.size(); ++right) {
        currOnes += nums[right];

        if (right - left + 1 > ones) {
            currOnes -= nums[left];
            ++left;
        }

        maxOnes = max(maxOnes, currOnes);
    }

    return ones - maxOnes;
}
```
1. Count the total number of 1's in the array and store this value in the `ones` variable.
2. Initialize variables `maxOnes`, `currOnes`, and `left` to 0. These will be used to keep track of the maximum number of 1's in a range and our current window.
3. Loop through the array using the `right` variable.
4. Add the value in `nums[right]` to `currOnes`.
5. Check if the window size (between `right` and `left`) is greater than the total number of 1's.
6. If it is, remove the value at `nums[left]` from `currOnes`, then increment `left` to reduce our window size.
7. Update the `maxOnes` variable to store the maximum value between itself and `currOnes`.
8. After looping through the entire array, subtract `maxOnes` from the total `ones`. The result is the minimum number of swaps needed.

## A solution in Python

```python
def minSwaps(nums):
    ones = maxOnes = currOnes = left = 0

    for num in nums:
        ones += num

    for right in range(len(nums)):
        currOnes += nums[right]

        if right - left + 1 > ones:
            currOnes -= nums[left]
            left += 1

        maxOnes = max(maxOnes, currOnes)

    return ones - maxOnes
```
1. Count the total number of 1's in the array and store this value in the `ones` variable.
2. Initialize variables `maxOnes`, `currOnes`, and `left` to 0. These will be used to keep track of the maximum number of 1's in a range and our current window.
3. Loop through the array using the `right` variable.
4. Add the value in `nums[right]` to `currOnes`.
5. Check if the window size (between `right` and `left`) is greater than the total number of 1's.
6. If it is, remove the value at `nums[left]` from `currOnes`, then increment `left` to reduce our window size.
7. Update the `maxOnes` variable to store the maximum value between itself and `currOnes`.
8. After looping through the entire array, subtract `maxOnes` from the total `ones`. The result is the minimum number of swaps needed.

## A solution in Javascript

```javascript
function minSwaps(nums) {
    let ones = 0, maxOnes = 0, currOnes = 0, left = 0;

    for (let num of nums) {
        ones += num;
    }

    for (let right = 0; right < nums.length; ++right) {
        currOnes += nums[right];

        if (right - left + 1 > ones) {
            currOnes -= nums[left];
            ++left;
        }

        maxOnes = Math.max(maxOnes, currOnes);
    }

    return ones - maxOnes;
}
```
1. Count the total number of 1's in the array and store this value in the `ones` variable.
2. Initialize variables `maxOnes`, `currOnes`, and `left` to 0. These will be used to keep track of the maximum number of 1's in a range and our current window.
3. Loop through the array using the `right` variable.
4. Add the value in `nums[right]` to `currOnes`.
5. Check if the window size (between `right` and `left`) is greater than the total number of 1's.
6. If it is, remove the value at `nums[left]` from `currOnes`, then increment `left` to reduce our window size.
7. Update the `maxOnes` variable to store the maximum value between itself and `currOnes`.
8. After looping through the entire array, subtract `maxOnes` from the total `ones`. The result is the minimum number of swaps needed.


# Minimum Average Difference

- slug: minimum-average-difference
- difficulty: Medium

You are given a **0-indexed** integer array `nums` of length `n`.

The **average difference** of the index `i` is the **absolute** **difference** between the average of the **first** `i + 1` elements of `nums` and the average of the **last** `n - i - 1` elements. Both averages should be **rounded down** to the nearest integer.

Return _the index with the **minimum average difference**_. If there are multiple such indices, return the **smallest** one.

**Note:**

*   The **absolute difference** of two numbers is the absolute value of their difference.
*   The **average** of `n` elements is the **sum** of the `n` elements divided (**integer division**) by `n`.
*   The average of `0` elements is considered to be `0`.

**Example 1:**

**Input:** nums = \[2,5,3,9,5,3\]
**Output:** 3
**Explanation:**
- The average difference of index 0 is: |2 / 1 - (5 + 3 + 9 + 5 + 3) / 5| = |2 / 1 - 25 / 5| = |2 - 5| = 3.
- The average difference of index 1 is: |(2 + 5) / 2 - (3 + 9 + 5 + 3) / 4| = |7 / 2 - 20 / 4| = |3 - 5| = 2.
- The average difference of index 2 is: |(2 + 5 + 3) / 3 - (9 + 5 + 3) / 3| = |10 / 3 - 17 / 3| = |3 - 5| = 2.
- The average difference of index 3 is: |(2 + 5 + 3 + 9) / 4 - (5 + 3) / 2| = |19 / 4 - 8 / 2| = |4 - 4| = 0.
- The average difference of index 4 is: |(2 + 5 + 3 + 9 + 5) / 5 - 3 / 1| = |24 / 5 - 3 / 1| = |4 - 3| = 1.
- The average difference of index 5 is: |(2 + 5 + 3 + 9 + 5 + 3) / 6 - 0| = |27 / 6 - 0| = |4 - 0| = 4.
The average difference of index 3 is the minimum average difference so return 3.

**Example 2:**

**Input:** nums = \[0\]
**Output:** 0
**Explanation:**
The only index is 0 so return 0.
The average difference of index 0 is: |0 / 1 - 0| = |0 - 0| = 0.

**Constraints:**

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

## A solution in Java

```java
import java.util.List;

public int countConvertibleWords(List<String> startWords, List<String> targetWords) {
    int count = 0;
    for (String target : targetWords) {
        for (String start : startWords) {
            if (start.length() + 1 == target.length() && target.startsWith(start)) {
                count++;
                break;
            }
        }
    }
    return count;
}
```
The algorithm consists of iterating through the list of targetWords while also iterating through the list of startWords. We check if the length of the current startWord plus one is equal to the length of the current targetWord, which indicates that we can add an English letter to startWord to make it equal to the targetWord. Additionally, we check if targetWord starts with the startWord. If both conditions are met, we increase the count and break out of the inner loop. Finally, we return the count.

## A solution in C++

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

int countConvertibleWords(std::vector<std::string>& startWords, std::vector<std::string>& targetWords) {
    int count = 0;
    for (const auto& target : targetWords) {
        for (const auto& start : startWords) {
            if (start.length() + 1 == target.length() && target.substr(0, start.length()) == start) {
                count++;
                break;
            }
        }
    }
    return count;
}
```
The algorithm consists of iterating through the list of targetWords while also iterating through the list of startWords. We check if the length of the current startWord plus one is equal to the length of the current targetWord, which indicates that we can add an English letter to startWord to make it equal to the targetWord. Additionally, we check if targetWord starts with the startWord. If both conditions are met, we increase the count and break out of the inner loop. Finally, we return the count.

## A solution in Python

```python
def count_convertible_words(start_words, target_words):
    count = 0
    for target in target_words:
        for start in start_words:
            if len(start) + 1 == len(target) and target.startswith(start):
                count += 1
                break
    return count
```
The algorithm consists of iterating through the list of targetWords while also iterating through the list of startWords. We check if the length of the current startWord plus one is equal to the length of the current targetWord, which indicates that we can add an English letter to startWord to make it equal to the targetWord. Additionally, we check if targetWord starts with the startWord. If both conditions are met, we increase the count and break out of the inner loop. Finally, we return the count.

## A solution in Javascript

```javascript
function countConvertibleWords(startWords, targetWords) {
    let count = 0;
    for (const target of targetWords) {
        for (const start of startWords) {
            if (start.length + 1 === target.length && target.startsWith(start)) {
                count++;
                break;
            }
        }
    }
    return count;
}
```
The algorithm consists of iterating through the list of targetWords while also iterating through the list of startWords. We check if the length of the current startWord plus one is equal to the length of the current targetWord, which indicates that we can add an English letter to startWord to make it equal to the targetWord. Additionally, we check if targetWord starts with the startWord. If both conditions are met, we increase the count and break out of the inner loop. Finally, we return the count.


# Count Unguarded Cells in the Grid

- slug: count-unguarded-cells-in-the-grid
- difficulty: Medium

You are given two integers `m` and `n` representing a **0-indexed** `m x n` grid. You are also given two 2D integer arrays `guards` and `walls` where `guards[i] = [rowi, coli]` and `walls[j] = [rowj, colj]` represent the positions of the `ith` guard and `jth` wall respectively.

A guard can see **every** cell in the four cardinal directions (north, east, south, or west) starting from their position unless **obstructed** by a wall or another guard. A cell is **guarded** if there is **at least** one guard that can see it.

Return _the number of unoccupied cells that are **not** **guarded**._

**Example 1:**

**Input:** m = 4, n = 6, guards = \[\[0,0\],\[1,1\],\[2,3\]\], walls = \[\[0,1\],\[2,2\],\[1,4\]\]
**Output:** 7
**Explanation:** The guarded and unguarded cells are shown in red and green respectively in the above diagram.
There are a total of 7 unguarded cells, so we return 7.

**Example 2:**

**Input:** m = 3, n = 3, guards = \[\[1,1\]\], walls = \[\[0,1\],\[1,0\],\[2,1\],\[1,2\]\]
**Output:** 4
**Explanation:** The unguarded cells are shown in green in the above diagram.
There are a total of 4 unguarded cells, so we return 4.

**Constraints:**

*   `1 <= m, n <= 105`
*   `2 <= m * n <= 105`
*   `1 <= guards.length, walls.length <= 5 * 104`
*   `2 <= guards.length + walls.length <= m * n`
*   `guards[i].length == walls[j].length == 2`
*   `0 <= rowi, rowj < m`
*   `0 <= coli, colj < n`
*   All the positions in `guards` and `walls` are **unique**.

## A solution in Java

```java
import java.util.*;

public int earliestBloomingDay(int[] plantTime, int[] growTime) {
    Integer[] bloomTime = new Integer[plantTime.length];
    for (int i = 0; i < plantTime.length; i++) {
        bloomTime[i] = plantTime[i] + growTime[i];
    }
    Arrays.sort(bloomTime);
    int earliestDay = 0;
    for (int i = 0; i < bloomTime.length; i++) {
        earliestDay = Math.max(earliestDay, bloomTime[i]);
        earliestDay++;
    }
    return earliestDay;
}
```
The algorithm computes the bloom time of each flower by adding its respective plant and grow times. It stores these bloom times in an array called `bloomTime`.

Next, it sorts the `bloomTime` array in ascending order.

The algorithm then goes through the sorted `bloomTime` array and finds the maximum value between the current `earliestDay` and `bloomTime[i]`. The variable `earliestDay` is incremented at each step to account for planting a new seed each day. Finally, it returns the earliest possible day where all seeds are blooming.

## A solution in C++

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

int earliestBloomingDay(std::vector<int>& plantTime, std::vector<int>& growTime) {
    std::vector<int> bloomTime;
    for (size_t i = 0; i < plantTime.size(); i++) {
        bloomTime.push_back(plantTime[i] + growTime[i]);
    }
    std::sort(bloomTime.begin(), bloomTime.end());
    int earliestDay = 0;
    for (size_t i = 0; i < bloomTime.size(); i++) {
        earliestDay = std::max(earliestDay, bloomTime[i]);
        earliestDay++;
    }
    return earliestDay;
}
```
The algorithm computes the bloom time of each flower by adding its respective plant and grow times. It stores these bloom times in an array called `bloomTime`.

Next, it sorts the `bloomTime` array in ascending order.

The algorithm then goes through the sorted `bloomTime` array and finds the maximum value between the current `earliestDay` and `bloomTime[i]`. The variable `earliestDay` is incremented at each step to account for planting a new seed each day. Finally, it returns the earliest possible day where all seeds are blooming.

## A solution in Python

```python
def earliest_blooming_day(plant_time, grow_time):
    bloom_time = [plant_time[i] + grow_time[i] for i in range(len(plant_time))]
    bloom_time.sort()
    earliest_day = 0
    for i in bloom_time:
        earliest_day = max(earliest_day, i)
        earliest_day += 1
    return earliest_day
```
The algorithm computes the bloom time of each flower by adding its respective plant and grow times. It stores these bloom times in an array called `bloomTime`.

Next, it sorts the `bloomTime` array in ascending order.

The algorithm then goes through the sorted `bloomTime` array and finds the maximum value between the current `earliestDay` and `bloomTime[i]`. The variable `earliestDay` is incremented at each step to account for planting a new seed each day. Finally, it returns the earliest possible day where all seeds are blooming.

## A solution in Javascript

```javascript
function earliestBloomingDay(plantTime, growTime) {
    let bloomTime = plantTime.map((t, i) => t + growTime[i]);
    bloomTime.sort((a, b) => a - b);
    let earliestDay = 0;
    for (let i = 0; i < bloomTime.length; i++) {
        earliestDay = Math.max(earliestDay, bloomTime[i]);
        earliestDay++;
    }
    return earliestDay;
}
```
The algorithm computes the bloom time of each flower by adding its respective plant and grow times. It stores these bloom times in an array called `bloomTime`.

Next, it sorts the `bloomTime` array in ascending order.

The algorithm then goes through the sorted `bloomTime` array and finds the maximum value between the current `earliestDay` and `bloomTime[i]`. The variable `earliestDay` is incremented at each step to account for planting a new seed each day. Finally, it returns the earliest possible day where all seeds are blooming.


# Escape the Spreading Fire

- slug: escape-the-spreading-fire
- difficulty: Hard

You are given a **0-indexed** 2D integer array `grid` of size `m x n` which represents a field. Each cell has one of three values:

*   `0` represents grass,
*   `1` represents fire,
*   `2` represents a wall that you and fire cannot pass through.

You are situated in the top-left cell, `(0, 0)`, and you want to travel to the safehouse at the bottom-right cell, `(m - 1, n - 1)`. Every minute, you may move to an **adjacent** grass cell. **After** your move, every fire cell will spread to all **adjacent** cells that are not walls.

Return _the **maximum** number of minutes that you can stay in your initial position before moving while still safely reaching the safehouse_. If this is impossible, return `-1`. If you can **always** reach the safehouse regardless of the minutes stayed, return `109`.

Note that even if the fire spreads to the safehouse immediately after you have reached it, it will be counted as safely reaching the safehouse.

A cell is **adjacent** to another cell if the former is directly north, east, south, or west of the latter (i.e., their sides are touching).

**Example 1:**

**Input:** grid = \[\[0,2,0,0,0,0,0\],\[0,0,0,2,2,1,0\],\[0,2,0,0,1,2,0\],\[0,0,2,2,2,0,2\],\[0,0,0,0,0,0,0\]\]
**Output:** 3
**Explanation:** The figure above shows the scenario where you stay in the initial position for 3 minutes.
You will still be able to safely reach the safehouse.
Staying for more than 3 minutes will not allow you to safely reach the safehouse.

**Example 2:**

**Input:** grid = \[\[0,0,0,0\],\[0,1,2,0\],\[0,2,0,0\]\]
**Output:** -1
**Explanation:** The figure above shows the scenario where you immediately move towards the safehouse.
Fire will spread to any cell you move towards and it is impossible to safely reach the safehouse.
Thus, -1 is returned.

**Example 3:**

**Input:** grid = \[\[0,0,0\],\[2,2,0\],\[1,2,0\]\]
**Output:** 1000000000
**Explanation:** The figure above shows the initial grid.
Notice that the fire is contained by walls and you will always be able to safely reach the safehouse.
Thus, 109 is returned.

**Constraints:**

*   `m == grid.length`
*   `n == grid[i].length`
*   `2 <= m, n <= 300`
*   `4 <= m * n <= 2 * 104`
*   `grid[i][j]` is either `0`, `1`, or `2`.
*   `grid[0][0] == grid[m - 1][n - 1] == 0`

## A solution in Java

```java
import java.util.*;

class Solution {
    private static final int[] dx = {0, 1, 0, -1};
    private static final int[] dy = {1, 0, -1, 0};

    public int getMaxSafeMinutes(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;

        int[][] dist = new int[m][n];
        for (int i = 0; i < m; i++) {
            Arrays.fill(dist[i], -1);
        }
        Queue<int[]> q = new ArrayDeque<>();

        if (grid[m - 1][n - 1] != 1) {
            dist[m - 1][n - 1] = 0;
            q.add(new int[]{m - 1, n - 1});
        }

        while (!q.isEmpty()) {
            int[] curr = q.poll();
            int x = curr[0];
            int y = curr[1];
            for (int d = 0; d < 4; d++) {
                int nx = x + dx[d];
                int ny = y + dy[d];
                if (nx >= 0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] == 0 && dist[nx][ny] == -1) {
                    dist[nx][ny] = dist[x][y] + 1;
                    q.add(new int[]{nx, ny});
                }
            }
        }

        if (dist[0][0] == -1) return -1;

        int res = 0;
        for (int test = dist[0][0]; test < 1e9; test++) {
            boolean ok = true;
            for (int x = 0; x < m; x++) {
                for (int y = 0; y < n; y++) {
                    if (grid[x][y] == 1) {
...
```
The algorithm first calculates the distance from every cell to the safehouse. This is done with Breadth-First Search (BFS) from the safehouse, treating only grass cells as reachable. Cells in the dist matrix marked with -1 are either unreachable or walls/fire cells.

Next, the algorithm iterates through possible time steps (test) that the character could wait, starting from the time required to reach the safehouse without waiting (dist[0][0]). For each time step, the algorithm checks if the character could complete the path to the safehouse without encountering fire. The character is safe from fire only if the fire is separated by a wall (grid[nx][ny] == 2). As soon as there is no wall between the fire and the character, the algorithm breaks the loop and returns the current minimum waiting time.

In case the character never encounters fire on the path to the safehouse, the algorithm returns 10^9 (always safe). If the character can't reach the safehouse at all, the algorithm returns -1.

Please note that this solution may have slight variations or differences in syntax and style between languages to adapt to their specific requirements and best practices.

## A solution in C++

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

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};

int getMaxSafeMinutes(vector<vector<int>>& grid) {
    int m = grid.size();
    int n = grid[0].size();

    vector<vector<int>> dist(m, vector<int>(n, -1));
    queue<pair<int, int>> q;

    if (grid[m - 1][n - 1] != 1) {
        dist[m - 1][n - 1] = 0;
        q.push({m - 1, n - 1});
    }

    while (!q.empty()) {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        for (int d = 0; d < 4; d++) {
            int nx = x + dx[d];
            int ny = y + dy[d];
            if (nx >= 0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] == 0 && dist[nx][ny] == -1) {
                dist[nx][ny] = dist[x][y] + 1;
                q.push({nx, ny});
            }
        }
    }

    if (dist[0][0] == -1) return -1;

    int res = 0;
    for (int test = dist[0][0]; test < (int)1e9; test++) {
        bool ok = true;
        for (int x = 0; x < m; x++) {
            for (int y = 0; y < n; y++) {
                if (grid[x][y] == 1) {
...
```
The algorithm first calculates the distance from every cell to the safehouse. This is done with Breadth-First Search (BFS) from the safehouse, treating only grass cells as reachable. Cells in the dist matrix marked with -1 are either unreachable or walls/fire cells.

Next, the algorithm iterates through possible time steps (test) that the character could wait, starting from the time required to reach the safehouse without waiting (dist[0][0]). For each time step, the algorithm checks if the character could complete the path to the safehouse without encountering fire. The character is safe from fire only if the fire is separated by a wall (grid[nx][ny] == 2). As soon as there is no wall between the fire and the character, the algorithm breaks the loop and returns the current minimum waiting time.

In case the character never encounters fire on the path to the safehouse, the algorithm returns 10^9 (always safe). If the character can't reach the safehouse at all, the algorithm returns -1.

Please note that this solution may have slight variations or differences in syntax and style between languages to adapt to their specific requirements and best practices.

## A solution in Python

```python
from collections import deque

dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

def getMaxSafeMinutes(grid):
    m, n = len(grid), len(grid[0])
    dist = [[-1 for _ in range(n)] for _ in range(m)]
    q = deque()

    if grid[m - 1][n - 1] != 1:
        dist[m - 1][n - 1] = 0
        q.append((m - 1, n - 1))

    while q:
        x, y = q.popleft()
        for d in range(4):
            nx, ny = x + dx[d], y + dy[d]
            if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] == 0 and dist[nx][ny] == -1:
                dist[nx][ny] = dist[x][y] + 1
                q.append((nx, ny))

    if dist[0][0] == -1:
        return -1

    res = 0
    for test in range(dist[0][0], int(1e9)):
        ok = True
        for x in range(m):
            for y in range(n):
                if grid[x][y] == 1:
                    for d in range(4):
                        nx, ny = x + dx[d], y + dy[d]
                        if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] == 2:
                            break
                    else:
                        ok = False
                        break
        if ok:
            res = test
        else:
            break
    return res
```
The algorithm first calculates the distance from every cell to the safehouse. This is done with Breadth-First Search (BFS) from the safehouse, treating only grass cells as reachable. Cells in the dist matrix marked with -1 are either unreachable or walls/fire cells.

Next, the algorithm iterates through possible time steps (test) that the character could wait, starting from the time required to reach the safehouse without waiting (dist[0][0]). For each time step, the algorithm checks if the character could complete the path to the safehouse without encountering fire. The character is safe from fire only if the fire is separated by a wall (grid[nx][ny] == 2). As soon as there is no wall between the fire and the character, the algorithm breaks the loop and returns the current minimum waiting time.

In case the character never encounters fire on the path to the safehouse, the algorithm returns 10^9 (always safe). If the character can't reach the safehouse at all, the algorithm returns -1.

Please note that this solution may have slight variations or differences in syntax and style between languages to adapt to their specific requirements and best practices.

## A solution in Javascript

```javascript
const dx = [0, 1, 0, -1];
const dy = [1, 0, -1, 0];

function getMaxSafeMinutes(grid) {
    const m = grid.length;
    const n = grid[0].length;
    const dist = Array.from({length: m}, () => Array(n).fill(-1));
    const q = [];

    if (grid[m - 1][n - 1] !== 1) {
        dist[m - 1][n - 1] = 0;
        q.push([m - 1, n - 1]);
    }

    while (q.length > 0) {
        const [x, y] = q.shift();
        for (let d = 0; d < 4; d++) {
            const nx = x + dx[d];
            const ny = y + dy[d];
            if (nx >= 0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] === 0 && dist[nx][ny] === -1) {
                dist[nx][ny] = dist[x][y] + 1;
                q.push([nx, ny]);
            }
        }
    }

    if (dist[0][0] === -1) return -1;

    let res = 0;
    for (let test = dist[0][0]; test < 1e9; test++) {
        let ok = true;
        for (let x = 0; x < m; x++) {
            for (let y = 0; y < n; y++) {
                if (grid[x][y] === 1) {
                    for (let d = 0; d < 4; d++) {
                        const nx = x + dx[d];
                        const ny = y + dy[d];
                        if (nx >= 0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] === 2) {
                            break;
                        }
                    }
                    if (d === 4) {
                        ok = false;
                        break;
                    }
                }
            }
            if (!ok) break;
        }
        if (ok) {
            res = test;
        } else {
            break;
        }
    }
    return res;
}
```
The algorithm first calculates the distance from every cell to the safehouse. This is done with Breadth-First Search (BFS) from the safehouse, treating only grass cells as reachable. Cells in the dist matrix marked with -1 are either unreachable or walls/fire cells.

Next, the algorithm iterates through possible time steps (test) that the character could wait, starting from the time required to reach the safehouse without waiting (dist[0][0]). For each time step, the algorithm checks if the character could complete the path to the safehouse without encountering fire. The character is safe from fire only if the fire is separated by a wall (grid[nx][ny] == 2). As soon as there is no wall between the fire and the character, the algorithm breaks the loop and returns the current minimum waiting time.

In case the character never encounters fire on the path to the safehouse, the algorithm returns 10^9 (always safe). If the character can't reach the safehouse at all, the algorithm returns -1.

Please note that this solution may have slight variations or differences in syntax and style between languages to adapt to their specific requirements and best practices.


# Remove Digit From Number to Maximize Result

- slug: remove-digit-from-number-to-maximize-result
- difficulty: Easy

You are given a string `number` representing a **positive integer** and a character `digit`.

Return _the resulting string after removing **exactly one occurrence** of_ `digit` _from_ `number` _such that the value of the resulting string in **decimal** form is **maximized**_. The test cases are generated such that `digit` occurs at least once in `number`.

**Example 1:**

**Input:** number =  "123 ", digit =  "3 "
**Output:**  "12 "
**Explanation:** There is only one '3' in  "123 ". After removing '3', the result is  "12 ".

**Example 2:**

**Input:** number =  "1231 ", digit =  "1 "
**Output:**  "231 "
**Explanation:** We can remove the first '1' to get  "231 " or remove the second '1' to get  "123 ".
Since 231 > 123, we return  "231 ".

**Example 3:**

**Input:** number =  "551 ", digit =  "5 "
**Output:**  "51 "
**Explanation:** We can remove either the first or second '5' from  "551 ".
Both result in the string  "51 ".

**Constraints:**

*   `2 <= number.length <= 100`
*   `number` consists of digits from `'1'` to `'9'`.
*   `digit` is a digit from `'1'` to `'9'`.
*   `digit` occurs at least once in `number`.

## A solution in Java

```java
public String maxNumberAfterRemoveDigit(String number, char digit) {
    int index = number.indexOf(digit);
    return number.substring(0, index) + number.substring(index + 1);
}
```
The algorithm for all the implementations is as follows:

1. Find the index of the first occurrence of the `digit` in the `number` string.
2. Make a copy of the `number` string (this is done implicitly for Java, Python, and JavaScript when manipulating strings), removing the digit at the found index.
3. Return the new string as the result.

In all language implementations, we first use string methods like `find`, `indexOf`, or `search` to find the index of the first occurrence of the digit in the number string. After that, we create a new string by removing the digit at that index using different string methods like `erase` (in C++), `substring` (in Java), string slicing (in Python), or `slice` method (in JavaScript).

The time complexity for this algorithm is O(n) where n is the length of the number string. This is because finding the index of the digit and removing the digit from the string takes linear time.

## A solution in C++

```cpp
std::string maxNumberAfterRemoveDigit(const std::string& number, const char digit) {
    size_t index = number.find(digit);
    std::string result = number;
    result.erase(index, 1);
    return result;
}
```
The algorithm for all the implementations is as follows:

1. Find the index of the first occurrence of the `digit` in the `number` string.
2. Make a copy of the `number` string (this is done implicitly for Java, Python, and JavaScript when manipulating strings), removing the digit at the found index.
3. Return the new string as the result.

In all language implementations, we first use string methods like `find`, `indexOf`, or `search` to find the index of the first occurrence of the digit in the number string. After that, we create a new string by removing the digit at that index using different string methods like `erase` (in C++), `substring` (in Java), string slicing (in Python), or `slice` method (in JavaScript).

The time complexity for this algorithm is O(n) where n is the length of the number string. This is because finding the index of the digit and removing the digit from the string takes linear time.

## A solution in Python

```python
def max_number_after_remove_digit(number: str, digit: str) -> str:
    index = number.find(digit)
    return number[:index] + number[index + 1:]
```
The algorithm for all the implementations is as follows:

1. Find the index of the first occurrence of the `digit` in the `number` string.
2. Make a copy of the `number` string (this is done implicitly for Java, Python, and JavaScript when manipulating strings), removing the digit at the found index.
3. Return the new string as the result.

In all language implementations, we first use string methods like `find`, `indexOf`, or `search` to find the index of the first occurrence of the digit in the number string. After that, we create a new string by removing the digit at that index using different string methods like `erase` (in C++), `substring` (in Java), string slicing (in Python), or `slice` method (in JavaScript).

The time complexity for this algorithm is O(n) where n is the length of the number string. This is because finding the index of the digit and removing the digit from the string takes linear time.

## A solution in Javascript

```javascript
function maxNumberAfterRemoveDigit(number, digit) {
    const index = number.indexOf(digit);
    return number.slice(0, index) + number.slice(index + 1);
}
```
The algorithm for all the implementations is as follows:

1. Find the index of the first occurrence of the `digit` in the `number` string.
2. Make a copy of the `number` string (this is done implicitly for Java, Python, and JavaScript when manipulating strings), removing the digit at the found index.
3. Return the new string as the result.

In all language implementations, we first use string methods like `find`, `indexOf`, or `search` to find the index of the first occurrence of the digit in the number string. After that, we create a new string by removing the digit at that index using different string methods like `erase` (in C++), `substring` (in Java), string slicing (in Python), or `slice` method (in JavaScript).

The time complexity for this algorithm is O(n) where n is the length of the number string. This is because finding the index of the digit and removing the digit from the string takes linear time.


# Minimum Consecutive Cards to Pick Up

- slug: minimum-consecutive-cards-to-pick-up
- difficulty: Medium

You are given an integer array `cards` where `cards[i]` represents the **value** of the `ith` card. A pair of cards are **matching** if the cards have the **same** value.

Return _the **minimum** number of **consecutive** cards you have to pick up to have a pair of **matching** cards among the picked cards._ If it is impossible to have matching cards, return `-1`.

**Example 1:**

**Input:** cards = \[3,4,2,3,4,7\]
**Output:** 4
**Explanation:** We can pick up the cards \[3,4,2,3\] which contain a matching pair of cards with value 3. Note that picking up the cards \[4,2,3,4\] is also optimal.

**Example 2:**

**Input:** cards = \[1,0,5,3\]
**Output:** -1
**Explanation:** There is no way to pick up a set of consecutive cards that contain a pair of matching cards.

**Constraints:**

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

## A solution in Java

```java
import java.util.ArrayList;

public ArrayList<String> partitionString(String s, int k, char fill) {
    ArrayList<String> partitions = new ArrayList<>();
    StringBuilder currentPartition = new StringBuilder();
    for(char c : s.toCharArray()) {
        currentPartition.append(c);
        if(currentPartition.length() == k) {
            partitions.add(currentPartition.toString());
            currentPartition.setLength(0); // clear the contents
        }
    }
    if(currentPartition.length() != 0) {
        while(currentPartition.length() < k) {
            currentPartition.append(fill);
        }
        partitions.add(currentPartition.toString());
    }
    return partitions;
}
```
The algorithm follows this procedure:
1. Initialize an empty list to store the partitioned groups.
2. Initialize an empty string to represent the current partition.
3. Iterate through each character in the input string:
   a. Append the character to the current partition.
   b. If the current partition reaches the specified size `k`, add it to the list of partitioned groups and reset the current partition.
4. After the iteration, if the current partition is not empty, fill it with the fill character until it reaches the specified size `k`, then add to the list of partitioned groups.
5. Return the final list of partitioned groups.

## A solution in C++

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

std::vector<std::string> partition_string(const std::string& s, int k, char fill) {
    std::vector<std::string> partitions;
    std::string current_partition;
    for(char c : s) {
        current_partition += c;
        if(current_partition.size() == k) {
            partitions.push_back(current_partition);
            current_partition.clear();
        }
    }
    if(!current_partition.empty()) {
        current_partition += std::string(k - current_partition.size(), fill);
        partitions.push_back(current_partition);
    }
    return partitions;
}
```
The algorithm follows this procedure:
1. Initialize an empty list to store the partitioned groups.
2. Initialize an empty string to represent the current partition.
3. Iterate through each character in the input string:
   a. Append the character to the current partition.
   b. If the current partition reaches the specified size `k`, add it to the list of partitioned groups and reset the current partition.
4. After the iteration, if the current partition is not empty, fill it with the fill character until it reaches the specified size `k`, then add to the list of partitioned groups.
5. Return the final list of partitioned groups.

## A solution in Python

```python
def partition_string(s, k, fill):
    partitions = []
    current_partition = ''
    for c in s:
        current_partition += c
        if len(current_partition) == k:
            partitions.append(current_partition)
            current_partition = ''
    if current_partition:
        current_partition += fill * (k - len(current_partition))
        partitions.append(current_partition)
    return partitions
```
The algorithm follows this procedure:
1. Initialize an empty list to store the partitioned groups.
2. Initialize an empty string to represent the current partition.
3. Iterate through each character in the input string:
   a. Append the character to the current partition.
   b. If the current partition reaches the specified size `k`, add it to the list of partitioned groups and reset the current partition.
4. After the iteration, if the current partition is not empty, fill it with the fill character until it reaches the specified size `k`, then add to the list of partitioned groups.
5. Return the final list of partitioned groups.

## A solution in Javascript

```javascript
function partitionString(s, k, fill) {
    const partitions = [];
    let currentPartition = '';
    for (const c of s) {
        currentPartition += c;
        if (currentPartition.length === k) {
            partitions.push(currentPartition);
            currentPartition = '';
        }
    }
    if (currentPartition.length > 0) {
        currentPartition += fill.repeat(k - currentPartition.length);
        partitions.push(currentPartition);
    }
    return partitions;
}
```
The algorithm follows this procedure:
1. Initialize an empty list to store the partitioned groups.
2. Initialize an empty string to represent the current partition.
3. Iterate through each character in the input string:
   a. Append the character to the current partition.
   b. If the current partition reaches the specified size `k`, add it to the list of partitioned groups and reset the current partition.
4. After the iteration, if the current partition is not empty, fill it with the fill character until it reaches the specified size `k`, then add to the list of partitioned groups.
5. Return the final list of partitioned groups.


# K Divisible Elements Subarrays

- slug: k-divisible-elements-subarrays
- difficulty: Medium

Given an integer array `nums` and two integers `k` and `p`, return _the number of **distinct subarrays** which have **at most**_ `k` _elements divisible by_ `p`.

Two arrays `nums1` and `nums2` are said to be **distinct** if:

*   They are of **different** lengths, or
*   There exists **at least** one index `i` where `nums1[i] != nums2[i]`.

A **subarray** is defined as a **non-empty** contiguous sequence of elements in an array.

**Example 1:**

**Input:** nums = \[**2**,3,3,**2**,**2**\], k = 2, p = 2
**Output:** 11
**Explanation:**
The elements at indices 0, 3, and 4 are divisible by p = 2.
The 11 distinct subarrays which have at most k = 2 elements divisible by 2 are:
\[2\], \[2,3\], \[2,3,3\], \[2,3,3,2\], \[3\], \[3,3\], \[3,3,2\], \[3,3,2,2\], \[3,2\], \[3,2,2\], and \[2,2\].
Note that the subarrays \[2\] and \[3\] occur more than once in nums, but they should each be counted only once.
The subarray \[2,3,3,2,2\] should not be counted because it has 3 elements that are divisible by 2.

**Example 2:**

**Input:** nums = \[1,2,3,4\], k = 4, p = 1
**Output:** 10
**Explanation:**
All element of nums are divisible by p = 1.
Also, every subarray of nums will have at most 4 elements that are divisible by 1.
Since all subarrays are distinct, the total number of subarrays satisfying all the constraints is 10.

**Constraints:**

*   `1 <= nums.length <= 200`
*   `1 <= nums[i], p <= 200`
*   `1 <= k <= nums.length`

**Follow up:**

Can you solve this problem in O(n2) time complexity?

## A solution in Java

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

public List<Integer> highestScoreDivisions(int[] nums) {
    int count0 = 0, count1 = 0;
    for (int n : nums) {
        if (n == 1) count1++;
    }

    int maxScore = -1, currentScore = 0;
    List<Integer> result = new ArrayList<>();
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] == 0) {
            currentScore++;
        } else {
            count1--;
        }

        if (currentScore > maxScore) {
            maxScore = currentScore;
            result.clear();
            result.add(i);
        } else if (currentScore == maxScore) {
            result.add(i);
        }
    }
    return result;
}
```
1. Initialize two counters, one for counting the number of 0's (count0) and one for counting the number of 1's (count1). Traverse through nums and count the number of 1's.
2. Initialize a variable (maxScore) to keep track of the maximum division score found so far, and a variable (currentScore) for the current division score calculation.
3. Initialize an empty result list to store indices with the highest division score.
4. Traverse through nums
   a. If the element is 0, increment currentScore.
   b. If the element is 1, decrement count1 (as it is moving from the right-side array to the left-side array).
   c. If the currentScore is greater than maxScore, update maxScore to current_score, clear the result list, and add the current index to the result list.
   d. If the currentScore is equal to maxScore, add the current index to the result list.
5. Return the result list with indices of the highest division scores.

## A solution in C++

```cpp
#include <vector>

std::vector<int> highestScoreDivisions(std::vector<int>& nums) {
    int count0 = 0, count1 = 0;
    for (int n : nums) {
        if (n == 1) count1++;
    }

    int maxScore = -1, currentScore = 0;
    std::vector<int> result;
    for (int i = 0; i < nums.size(); i++) {
        if (nums[i] == 0) {
            currentScore++;
        } else {
            count1--;
        }

        if (currentScore > maxScore) {
            maxScore = currentScore;
            result.clear();
            result.push_back(i);
        } else if (currentScore == maxScore) {
            result.push_back(i);
        }
    }
    return result;
}
```
1. Initialize two counters, one for counting the number of 0's (count0) and one for counting the number of 1's (count1). Traverse through nums and count the number of 1's.
2. Initialize a variable (maxScore) to keep track of the maximum division score found so far, and a variable (currentScore) for the current division score calculation.
3. Initialize an empty result list to store indices with the highest division score.
4. Traverse through nums
   a. If the element is 0, increment currentScore.
   b. If the element is 1, decrement count1 (as it is moving from the right-side array to the left-side array).
   c. If the currentScore is greater than maxScore, update maxScore to current_score, clear the result list, and add the current index to the result list.
   d. If the currentScore is equal to maxScore, add the current index to the result list.
5. Return the result list with indices of the highest division scores.

## A solution in Python

```python
def highestScoreDivisions(nums):
    count0, count1 = 0, 0
    for n in nums:
        if n == 1:
            count1 += 1

    max_score, current_score = -1, 0
    result = []
    for i, n in enumerate(nums):
        if n == 0:
            current_score += 1
        else:
            count1 -= 1

        if current_score > max_score:
            max_score = current_score
            result = [i]
        elif current_score == max_score:
            result.append(i)

    return result
```
1. Initialize two counters, one for counting the number of 0's (count0) and one for counting the number of 1's (count1). Traverse through nums and count the number of 1's.
2. Initialize a variable (maxScore) to keep track of the maximum division score found so far, and a variable (currentScore) for the current division score calculation.
3. Initialize an empty result list to store indices with the highest division score.
4. Traverse through nums
   a. If the element is 0, increment currentScore.
   b. If the element is 1, decrement count1 (as it is moving from the right-side array to the left-side array).
   c. If the currentScore is greater than maxScore, update maxScore to current_score, clear the result list, and add the current index to the result list.
   d. If the currentScore is equal to maxScore, add the current index to the result list.
5. Return the result list with indices of the highest division scores.

## A solution in Javascript

```javascript
function highestScoreDivisions(nums) {
    let count0 = 0, count1 = 0;
    for (let n of nums) {
        if (n === 1) count1++;
    }

    let maxScore = -1, currentScore = 0;
    let result = [];
    for (let i = 0; i < nums.length; i++) {
        if (nums[i] === 0) {
            currentScore++;
        } else {
            count1--;
        }

        if (currentScore > maxScore) {
            maxScore = currentScore;
            result = [i];
        } else if (currentScore === maxScore) {
            result.push(i);
        }
    }
    return result;
}
```
1. Initialize two counters, one for counting the number of 0's (count0) and one for counting the number of 1's (count1). Traverse through nums and count the number of 1's.
2. Initialize a variable (maxScore) to keep track of the maximum division score found so far, and a variable (currentScore) for the current division score calculation.
3. Initialize an empty result list to store indices with the highest division score.
4. Traverse through nums
   a. If the element is 0, increment currentScore.
   b. If the element is 1, decrement count1 (as it is moving from the right-side array to the left-side array).
   c. If the currentScore is greater than maxScore, update maxScore to current_score, clear the result list, and add the current index to the result list.
   d. If the currentScore is equal to maxScore, add the current index to the result list.
5. Return the result list with indices of the highest division scores.


# Total Appeal of A String

- slug: total-appeal-of-a-string
- difficulty: Hard

The **appeal** of a string is the number of **distinct** characters found in the string.

*   For example, the appeal of `"abbca "` is `3` because it has `3` distinct characters: `'a'`, `'b'`, and `'c'`.

Given a string `s`, return _the **total appeal of all of its **substrings**.**_

A **substring** is a contiguous sequence of characters within a string.

**Example 1:**

**Input:** s =  "abbca "
**Output:** 28
**Explanation:** The following are the substrings of  "abbca ":
- Substrings of length 1:  "a ",  "b ",  "b ",  "c ",  "a " have an appeal of 1, 1, 1, 1, and 1 respectively. The sum is 5.
- Substrings of length 2:  "ab ",  "bb ",  "bc ",  "ca " have an appeal of 2, 1, 2, and 2 respectively. The sum is 7.
- Substrings of length 3:  "abb ",  "bbc ",  "bca " have an appeal of 2, 2, and 3 respectively. The sum is 7.
- Substrings of length 4:  "abbc ",  "bbca " have an appeal of 3 and 3 respectively. The sum is 6.
- Substrings of length 5:  "abbca " has an appeal of 3. The sum is 3.
The total sum is 5 + 7 + 7 + 6 + 3 = 28.

**Example 2:**

**Input:** s =  "code "
**Output:** 20
**Explanation:** The following are the substrings of  "code ":
- Substrings of length 1:  "c ",  "o ",  "d ",  "e " have an appeal of 1, 1, 1, and 1 respectively. The sum is 4.
- Substrings of length 2:  "co ",  "od ",  "de " have an appeal of 2, 2, and 2 respectively. The sum is 6.
- Substrings of length 3:  "cod ",  "ode " have an appeal of 3 and 3 respectively. The sum is 6.
- Substrings of length 4:  "code " has an appeal of 4. The sum is 4.
The total sum is 4 + 6 + 6 + 4 = 20.

**Constraints:**

*   `1 <= s.length <= 105`
*   `s` consists of lowercase English letters.

## A solution in Java

```java
public int maxPoints(int[][] questions) {
    int n = questions.length;
    int[] dp = new int[n + 1];

    for (int i = n - 1; i >= 0; i--) {
        int skip_next = i + questions[i][1];
        dp[i] = Math.max(dp[i + 1], questions[i][0] + (skip_next < n ? dp[skip_next] : 0));
    }

    return dp[0];
}
```
We use dynamic programming to solve the problem. We create an array `dp` of size `n+1` to store the maximum points we can earn for each question. We initialize the array elements to 0.

We iterate through the questions in reverse order, starting from the last question. For each question `i`, we calculate the index `skip_next` by adding the current index and the `brainpower` value of the question. We update the `dp[i]` value with the maximum between `dp[i+1]` (if we skip the current question) and `questions[i][0] + (dp[skip_next] if skip_next < n else 0)` (if we solve the current question).

Finally, we return the maximum points we can earn, which is stored in `dp[0]`.

## A solution in C++

```cpp
int maxPoints(vector<vector<int>>& questions) {
    int n = questions.size();
    vector<int> dp(n + 1, 0);

    for (int i = n - 1; i >= 0; i--) {
        int skip_next = i + questions[i][1];
        dp[i] = max(dp[i + 1], questions[i][0] + (skip_next < n ? dp[skip_next] : 0));
    }

    return dp[0];
}
```
We use dynamic programming to solve the problem. We create an array `dp` of size `n+1` to store the maximum points we can earn for each question. We initialize the array elements to 0.

We iterate through the questions in reverse order, starting from the last question. For each question `i`, we calculate the index `skip_next` by adding the current index and the `brainpower` value of the question. We update the `dp[i]` value with the maximum between `dp[i+1]` (if we skip the current question) and `questions[i][0] + (dp[skip_next] if skip_next < n else 0)` (if we solve the current question).

Finally, we return the maximum points we can earn, which is stored in `dp[0]`.

## A solution in Python

```python
def max_points(questions):
    n = len(questions)
    dp = [0] * (n + 1)

    for i in range(n - 1, -1, -1):
        skip_next = i + questions[i][1]
        dp[i] = max(dp[i + 1], questions[i][0] + (dp[skip_next] if skip_next < n else 0))

    return dp[0]
```
We use dynamic programming to solve the problem. We create an array `dp` of size `n+1` to store the maximum points we can earn for each question. We initialize the array elements to 0.

We iterate through the questions in reverse order, starting from the last question. For each question `i`, we calculate the index `skip_next` by adding the current index and the `brainpower` value of the question. We update the `dp[i]` value with the maximum between `dp[i+1]` (if we skip the current question) and `questions[i][0] + (dp[skip_next] if skip_next < n else 0)` (if we solve the current question).

Finally, we return the maximum points we can earn, which is stored in `dp[0]`.

## A solution in Javascript

```javascript
function maxPoints(questions) {
    const n = questions.length;
    const dp = new Array(n + 1).fill(0);

    for (let i = n - 1; i >= 0; i--) {
        const skip_next = i + questions[i][1];
        dp[i] = Math.max(dp[i + 1], questions[i][0] + (skip_next < n ? dp[skip_next] : 0));
    }

    return dp[0];
}
```
We use dynamic programming to solve the problem. We create an array `dp` of size `n+1` to store the maximum points we can earn for each question. We initialize the array elements to 0.

We iterate through the questions in reverse order, starting from the last question. For each question `i`, we calculate the index `skip_next` by adding the current index and the `brainpower` value of the question. We update the `dp[i]` value with the maximum between `dp[i+1]` (if we skip the current question) and `questions[i][0] + (dp[skip_next] if skip_next < n else 0)` (if we solve the current question).

Finally, we return the maximum points we can earn, which is stored in `dp[0]`.


# Make Array Non-decreasing or Non-increasing

- slug: make-array-non-decreasing-or-non-increasing
- difficulty: Hard

You are given a **0-indexed** integer array `nums`. In one operation, you can:

*   Choose an index `i` in the range `0 <= i < nums.length`
*   Set `nums[i]` to `nums[i] + 1` **or** `nums[i] - 1`

Return _the **minimum** number of operations to make_ `nums` _**non-decreasing** or **non-increasing**._

**Example 1:**

**Input:** nums = \[3,2,4,5,0\]
**Output:** 4
**Explanation:**
One possible way to turn nums into non-increasing order is to:
- Add 1 to nums\[1\] once so that it becomes 3.
- Subtract 1 from nums\[2\] once so it becomes 3.
- Subtract 1 from nums\[3\] twice so it becomes 3.
After doing the 4 operations, nums becomes \[3,3,3,3,0\] which is in non-increasing order.
Note that it is also possible to turn nums into \[4,4,4,4,0\] in 4 operations.
It can be proven that 4 is the minimum number of operations needed.

**Example 2:**

**Input:** nums = \[2,2,3,4\]
**Output:** 0
**Explanation:** nums is already in non-decreasing order, so no operations are needed and we return 0.

**Example 3:**

**Input:** nums = \[0\]
**Output:** 0
**Explanation:** nums is already in non-decreasing order, so no operations are needed and we return 0.

**Constraints:**

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

**Follow up:** Can you solve it in `O(n*log(n))` time complexity?

## A solution in Java

```java
import java.util.Arrays;

public int maxRunningTime(int n, int[] batteries) {
    Arrays.sort(batteries);
    int total_time = 0;
    for (int i = batteries.length - 1; i >= batteries.length - n; --i) {
        total_time += batteries[i];
    }
    return total_time / n;
}
```
1. Sort the batteries array in descending order, so that the largest batteries are at the beginning of the array.
2. Calculate the total time by summing up the values of the first n elements in the sorted batteries array. This works because we pick the largest batteries to use first, thereby maximizing the amount of time the computers can run simultaneously.
3. Divide the total time by n to get the maximum number of minutes that all the computers can run simultaneously.

## A solution in C++

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

int maxRunningTime(int n, vector<int>& batteries) {
    sort(batteries.begin(), batteries.end(), greater<int>());
    int total_time = 0;
    for (int i = 0; i < n; ++i) {
        total_time += batteries[i];
    }
    return total_time / n;
}
```
1. Sort the batteries array in descending order, so that the largest batteries are at the beginning of the array.
2. Calculate the total time by summing up the values of the first n elements in the sorted batteries array. This works because we pick the largest batteries to use first, thereby maximizing the amount of time the computers can run simultaneously.
3. Divide the total time by n to get the maximum number of minutes that all the computers can run simultaneously.

## A solution in Python

```python
def max_running_time(n, batteries):
    batteries.sort(reverse=True)
    total_time = sum(batteries[:n])
    return total_time // n
```
1. Sort the batteries array in descending order, so that the largest batteries are at the beginning of the array.
2. Calculate the total time by summing up the values of the first n elements in the sorted batteries array. This works because we pick the largest batteries to use first, thereby maximizing the amount of time the computers can run simultaneously.
3. Divide the total time by n to get the maximum number of minutes that all the computers can run simultaneously.

## A solution in Javascript

```javascript
function maxRunningTime(n, batteries) {
    batteries.sort((a, b) => b - a);
    let total_time = 0;
    for (let i = 0; i < n; i++) {
        total_time += batteries[i];
    }
    return Math.floor(total_time / n);
}
```
1. Sort the batteries array in descending order, so that the largest batteries are at the beginning of the array.
2. Calculate the total time by summing up the values of the first n elements in the sorted batteries array. This works because we pick the largest batteries to use first, thereby maximizing the amount of time the computers can run simultaneously.
3. Divide the total time by n to get the maximum number of minutes that all the computers can run simultaneously.


# Largest 3-Same-Digit Number in String

- slug: largest-3-same-digit-number-in-string
- difficulty: Easy

You are given a string `num` representing a large integer. An integer is **good** if it meets the following conditions:

*   It is a **substring** of `num` with length `3`.
*   It consists of only one unique digit.

Return _the **maximum good** integer as a **string** or an empty string_ `" "` _if no such integer exists_.

Note:

*   A **substring** is a contiguous sequence of characters within a string.
*   There may be **leading zeroes** in `num` or a good integer.

**Example 1:**

**Input:** num =  "6**777**133339 "
**Output:**  "777 "
**Explanation:** There are two distinct good integers:  "777 " and  "333 ".
 "777 " is the largest, so we return  "777 ".

**Example 2:**

**Input:** num =  "23**000**19 "
**Output:**  "000 "
**Explanation:**  "000 " is the only good integer.

**Example 3:**

**Input:** num =  "42352338 "
**Output:**  " "
**Explanation:** No substring of length 3 consists of only one unique digit. Therefore, there are no good integers.

**Constraints:**

*   `3 <= num.length <= 1000`
*   `num` only consists of digits.

## A solution in Java

```java
int splitAndMinimize(int num) {
    int a = num / 1000;
    int b = (num % 1000) / 100;
    int c = (num % 100) / 10;
    int d = num % 10;
    return ((a * 10 + c) * 10 + b) * 10 + d;
}
```
First, we split the given four-digit number 'num' into its individual digits a, b, c, and d.
Then, we create two new numbers by changing the positioning of the digits in the following manner:

- new1 = a*10 + c (i.e., the first and the third digits of the original number)
- new2 = b*10 + d (i.e., the second and the fourth digits of the original number)

Finally, we return the sum of these two new numbers as the minimum possible sum of new1 and new2.

## A solution in C++

```cpp
int splitAndMinimize(int num) {
    int a = num / 1000;
    int b = (num % 1000) / 100;
    int c = (num % 100) / 10;
    int d = num % 10;
    return ((a * 10 + c) * 10 + b) * 10 + d;
}
```
First, we split the given four-digit number 'num' into its individual digits a, b, c, and d.
Then, we create two new numbers by changing the positioning of the digits in the following manner:

- new1 = a*10 + c (i.e., the first and the third digits of the original number)
- new2 = b*10 + d (i.e., the second and the fourth digits of the original number)

Finally, we return the sum of these two new numbers as the minimum possible sum of new1 and new2.

## A solution in Python

```python
def split_and_minimize(num):
    a = num // 1000
    b = (num % 1000) // 100
    c = (num % 100) // 10
    d = num % 10
    return ((a * 10 + c) * 10 + b) * 10 + d
```
First, we split the given four-digit number 'num' into its individual digits a, b, c, and d.
Then, we create two new numbers by changing the positioning of the digits in the following manner:

- new1 = a*10 + c (i.e., the first and the third digits of the original number)
- new2 = b*10 + d (i.e., the second and the fourth digits of the original number)

Finally, we return the sum of these two new numbers as the minimum possible sum of new1 and new2.

## A solution in Javascript

```javascript
function splitAndMinimize(num) {
    let a = Math.floor(num / 1000);
    let b = Math.floor((num % 1000) / 100);
    let c = Math.floor((num % 100) / 10);
    let d = num % 10;
    return ((a * 10 + c) * 10 + b) * 10 + d;
}
```
First, we split the given four-digit number 'num' into its individual digits a, b, c, and d.
Then, we create two new numbers by changing the positioning of the digits in the following manner:

- new1 = a*10 + c (i.e., the first and the third digits of the original number)
- new2 = b*10 + d (i.e., the second and the fourth digits of the original number)

Finally, we return the sum of these two new numbers as the minimum possible sum of new1 and new2.