# Find Latest Group of Size M

- slug: find-latest-group-of-size-m
- difficulty: Medium

Given an array `arr` that represents a permutation of numbers from `1` to `n`.

You have a binary string of size `n` that initially has all its bits set to zero. At each step `i` (assuming both the binary string and `arr` are 1-indexed) from `1` to `n`, the bit at position `arr[i]` is set to `1`.

You are also given an integer `m`. Find the latest step at which there exists a group of ones of length `m`. A group of ones is a contiguous substring of `1`'s such that it cannot be extended in either direction.

Return _the latest step at which there exists a group of ones of length **exactly**_ `m`. _If no such group exists, return_ `-1`.

**Example 1:**

**Input:** arr = \[3,5,1,2,4\], m = 1
**Output:** 4
**Explanation:**
Step 1:  "00100 ", groups: \[ "1 "\]
Step 2:  "00101 ", groups: \[ "1 ",  "1 "\]
Step 3:  "10101 ", groups: \[ "1 ",  "1 ",  "1 "\]
Step 4:  "11101 ", groups: \[ "111 ",  "1 "\]
Step 5:  "11111 ", groups: \[ "11111 "\]
The latest step at which there exists a group of size 1 is step 4.

**Example 2:**

**Input:** arr = \[3,1,5,4,2\], m = 2
**Output:** -1
**Explanation:**
Step 1:  "00100 ", groups: \[ "1 "\]
Step 2:  "10100 ", groups: \[ "1 ",  "1 "\]
Step 3:  "10101 ", groups: \[ "1 ",  "1 ",  "1 "\]
Step 4:  "10111 ", groups: \[ "1 ",  "111 "\]
Step 5:  "11111 ", groups: \[ "11111 "\]
No group of size 2 exists during any step.

**Constraints:**

*   `n == arr.length`
*   `1 <= m <= n <= 105`
*   `1 <= arr[i] <= n`
*   All integers in `arr` are **distinct**.

## A solution in Java

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

public class Solution {
    public List<Integer> peopleIndexes(List<List<String>> favoriteCompanies) {
        List<Integer> result = new ArrayList<>();
        for (int i = 0; i < favoriteCompanies.size(); i++) {
            boolean isSubset = false;
            for (int j = 0; j < favoriteCompanies.size() && !isSubset; j++) {
                if (i != j && favoriteCompanies.get(j).containsAll(favoriteCompanies.get(i))) {
                    isSubset = true;
                }
            }
            if (!isSubset) result.add(i);
        }
        return result;
    }
}
```
The algorithm takes a list of favorite companies for each person. It checks if the favorite companies list for the `ith` person is a subset of any other person's favorite companies list. If it's not, add the index of that person to the result array.

- Iterate through each person's list of favorite companies.
- For each person, compare their list to each other person's list of favorite companies.
- If their list is a subset of another person, set the `isSubset` flag to true and stop the inner loop.
- If the `isSubset` flag is false after going through all other people's lists, add the index of the current person to the result array.
- Return the result array at the end.

Language-specific implementations mainly differ in their ways of testing if one set is a subset of another set. In C++, it's done using the `includes` function; in Java, `containsAll` method; in Python, `issubset` method; and in JavaScript, we use `every` and `includes` methods.

## A solution in C++

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

vector<int> peopleIndexes(vector<vector<string>>& favoriteCompanies) {
    vector<int> result;
    for (int i = 0; i < favoriteCompanies.size(); i++) {
        bool isSubset = false;
        for (int j = 0; j < favoriteCompanies.size() && !isSubset; j++) {
            if (i != j && includes(favoriteCompanies[j].begin(), favoriteCompanies[j].end(),
                                   favoriteCompanies[i].begin(), favoriteCompanies[i].end())) {
                isSubset = true;
            }
        }
        if (!isSubset) result.push_back(i);
    }
    return result;
}
```
The algorithm takes a list of favorite companies for each person. It checks if the favorite companies list for the `ith` person is a subset of any other person's favorite companies list. If it's not, add the index of that person to the result array.

- Iterate through each person's list of favorite companies.
- For each person, compare their list to each other person's list of favorite companies.
- If their list is a subset of another person, set the `isSubset` flag to true and stop the inner loop.
- If the `isSubset` flag is false after going through all other people's lists, add the index of the current person to the result array.
- Return the result array at the end.

Language-specific implementations mainly differ in their ways of testing if one set is a subset of another set. In C++, it's done using the `includes` function; in Java, `containsAll` method; in Python, `issubset` method; and in JavaScript, we use `every` and `includes` methods.

## A solution in Python

```python
from typing import List

def peopleIndexes(favoriteCompanies: List[List[str]]) -> List[int]:
    result = []
    for i in range(len(favoriteCompanies)):
        is_subset = False
        for j in range(len(favoriteCompanies)):
            if i != j and set(favoriteCompanies[i]).issubset(favoriteCompanies[j]):
                is_subset = True
                break
        if not is_subset:
            result.append(i)
    return result
```
The algorithm takes a list of favorite companies for each person. It checks if the favorite companies list for the `ith` person is a subset of any other person's favorite companies list. If it's not, add the index of that person to the result array.

- Iterate through each person's list of favorite companies.
- For each person, compare their list to each other person's list of favorite companies.
- If their list is a subset of another person, set the `isSubset` flag to true and stop the inner loop.
- If the `isSubset` flag is false after going through all other people's lists, add the index of the current person to the result array.
- Return the result array at the end.

Language-specific implementations mainly differ in their ways of testing if one set is a subset of another set. In C++, it's done using the `includes` function; in Java, `containsAll` method; in Python, `issubset` method; and in JavaScript, we use `every` and `includes` methods.

## A solution in Javascript

```javascript
function peopleIndexes(favoriteCompanies) {
    const result = [];
    for (let i = 0; i < favoriteCompanies.length; i++) {
        let isSubset = false;
        for (let j = 0; j < favoriteCompanies.length && !isSubset; j++) {
            if (i !== j && favoriteCompanies[j].every(company => favoriteCompanies[i].includes(company))) {
                isSubset = true;
            }
        }
        if (!isSubset) result.push(i);
    }
    return result;
}
```
The algorithm takes a list of favorite companies for each person. It checks if the favorite companies list for the `ith` person is a subset of any other person's favorite companies list. If it's not, add the index of that person to the result array.

- Iterate through each person's list of favorite companies.
- For each person, compare their list to each other person's list of favorite companies.
- If their list is a subset of another person, set the `isSubset` flag to true and stop the inner loop.
- If the `isSubset` flag is false after going through all other people's lists, add the index of the current person to the result array.
- Return the result array at the end.

Language-specific implementations mainly differ in their ways of testing if one set is a subset of another set. In C++, it's done using the `includes` function; in Java, `containsAll` method; in Python, `issubset` method; and in JavaScript, we use `every` and `includes` methods.


# Stone Game V

- slug: stone-game-v
- difficulty: Hard

There are several stones **arranged in a row**, and each stone has an associated value which is an integer given in the array `stoneValue`.

In each round of the game, Alice divides the row into **two non-empty rows** (i.e. left row and right row), then Bob calculates the value of each row which is the sum of the values of all the stones in this row. Bob throws away the row which has the maximum value, and Alice's score increases by the value of the remaining row. If the value of the two rows are equal, Bob lets Alice decide which row will be thrown away. The next round starts with the remaining row.

The game ends when there is only **one stone remaining**. Alice's is initially **zero**.

Return _the maximum score that Alice can obtain_.

**Example 1:**

**Input:** stoneValue = \[6,2,3,4,5,5\]
**Output:** 18
**Explanation:** In the first round, Alice divides the row to \[6,2,3\], \[4,5,5\]. The left row has the value 11 and the right row has value 14. Bob throws away the right row and Alice's score is now 11.
In the second round Alice divides the row to \[6\], \[2,3\]. This time Bob throws away the left row and Alice's score becomes 16 (11 + 5).
The last round Alice has only one choice to divide the row which is \[2\], \[3\]. Bob throws away the right row and Alice's score is now 18 (16 + 2). The game ends because only one stone is remaining in the row.

**Example 2:**

**Input:** stoneValue = \[7,7,7,7,7,7,7\]
**Output:** 28

**Example 3:**

**Input:** stoneValue = \[4\]
**Output:** 0

**Constraints:**

*   `1 <= stoneValue.length <= 500`
*   `1 <= stoneValue[i] <= 106`

## A solution in Java

```java
import java.awt.geom.Point2D;
import java.util.List;

public int maxNumberOfDarts(List<List<Integer>> darts, int r) {
    int n = darts.size();
    int maxDarts = 1;

    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            double dist = Point2D.distance(darts.get(j).get(0), darts.get(j).get(1), darts.get(i).get(0), darts.get(i).get(1));
            if (dist > 2.0 * r) continue;

            double angle = Math.acos(dist / (2.0 * r));
            for (int k = 0; k < 2; k++) {
                double locAngle = angle * (k == 0 ? 1 : -1);
                double cx = darts.get(i).get(0) + r * (darts.get(j).get(0) - darts.get(i).get(0)) / dist * Math.cos(locAngle) - r * (darts.get(j).get(1) - darts.get(i).get(1)) / dist * Math.sin(locAngle);
                double cy = darts.get(i).get(1) + r * (darts.get(j).get(0) - darts.get(i).get(0)) / dist * Math.sin(locAngle) + r * (darts.get(j).get(1) - darts.get(i).get(1)) / dist * Math.cos(locAngle);

                int cnt = 0;
                for (int l = 0; l < n; l++) {
                    double newDist = Point2D.distance(darts.get(l).get(0), darts.get(l).get(1), cx, cy);
                    if (newDist <= r + 1e-5) cnt++;
                }

                maxDarts = Math.max(maxDarts, cnt);
            }
        }
    }

    return maxDarts;
}
```
For each dart pair (i, j), we calculate the distance between them, and check if it's smaller than or equal to the diameter (2*r) of the dartboard. If so, find the two possible centers (c1, c2) of the dartboard using trigonometry (getting the angle between the chord connecting two darts and the radius, and the angle between the radius and the wall), where i-th and j-th darts lie on the edge.

Then, for both possible centers of the dartboard, count how many darts in the array have a distance less than or equal to r and choose the highest value among all possible combinations of dart pairs and possible centers. This value is the maximum number of darts that can fit on the dartboard.

## A solution in C++

```cpp
#include <cmath>
#include <vector>

int maxNumberOfDarts(vector<vector<int>>& darts, int r) {
    int n = darts.size();
    int max_darts = 1;

    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            double dist = hypot(darts[j][0] - darts[i][0], darts[j][1] - darts[i][1]);
            if (dist > 2.0 * r) continue;

            double angle = acos(dist / (2.0 * r));
            for (int k = 0; k < 2; k++) {
                double loc_angle = angle * (k == 0 ? 1 : -1);
                double cx = darts[i][0] + r * (darts[j][0] - darts[i][0]) / dist * cos(loc_angle) - r * (darts[j][1] - darts[i][1]) / dist * sin(loc_angle);
                double cy = darts[i][1] + r * (darts[j][0] - darts[i][0]) / dist * sin(loc_angle) + r * (darts[j][1] - darts[i][1]) / dist * cos(loc_angle);

                int cnt = 0;
                for (int l = 0; l < n; l++) {
                    double new_dist = hypot(darts[l][0] - cx, darts[l][1] - cy);
                    if (new_dist <= r + 1e-5) cnt++;
                }

                max_darts = max(max_darts, cnt);
            }
        }
    }

    return max_darts;
}
```
For each dart pair (i, j), we calculate the distance between them, and check if it's smaller than or equal to the diameter (2*r) of the dartboard. If so, find the two possible centers (c1, c2) of the dartboard using trigonometry (getting the angle between the chord connecting two darts and the radius, and the angle between the radius and the wall), where i-th and j-th darts lie on the edge.

Then, for both possible centers of the dartboard, count how many darts in the array have a distance less than or equal to r and choose the highest value among all possible combinations of dart pairs and possible centers. This value is the maximum number of darts that can fit on the dartboard.

## A solution in Python

```python
from math import acos, cos, sin, sqrt

def max_number_of_darts(darts, r):
    n = len(darts)
    max_darts = 1

    for i in range(n):
        for j in range(i + 1, n):
            dist = sqrt((darts[j][0] - darts[i][0])**2 + (darts[j][1] - darts[i][1])**2)
            if dist > 2.0 * r: continue

            angle = acos(dist / (2.0 * r))
            for k in range(2):
                loc_angle = angle * (1 if k == 0 else -1)
                cx = darts[i][0] + r * (darts[j][0] - darts[i][0]) / dist * cos(loc_angle) - r * (darts[j][1] - darts[i][1]) / dist * sin(loc_angle)
                cy = darts[i][1] + r * (darts[j][0] - darts[i][0]) / dist * sin(loc_angle) + r * (darts[j][1] - darts[i][1]) / dist * cos(loc_angle)

                cnt = 0
                for l in range(n):
                    new_dist = sqrt((darts[l][0] - cx)**2 + (darts[l][1] - cy)**2)
                    if new_dist <= r + 1e-5: cnt += 1

                max_darts = max(max_darts, cnt)

    return max_darts
```
For each dart pair (i, j), we calculate the distance between them, and check if it's smaller than or equal to the diameter (2*r) of the dartboard. If so, find the two possible centers (c1, c2) of the dartboard using trigonometry (getting the angle between the chord connecting two darts and the radius, and the angle between the radius and the wall), where i-th and j-th darts lie on the edge.

Then, for both possible centers of the dartboard, count how many darts in the array have a distance less than or equal to r and choose the highest value among all possible combinations of dart pairs and possible centers. This value is the maximum number of darts that can fit on the dartboard.

## A solution in Javascript

```javascript
function maxNumberOfDarts(darts, r) {
    const n = darts.length;
    let maxDarts = 1;

    function distance(x1, y1, x2, y2) {
        return Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2);
    }

    for (let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++) {
            const dist = distance(darts[j][0], darts[j][1], darts[i][0], darts[i][1]);
            if (dist > 2.0 * r) continue;

            const angle = Math.acos(dist / (2.0 * r));
            for (let k = 0; k < 2; k++) {
                const locAngle = angle * (k === 0 ? 1 : -1);
                const cx = darts[i][0] + r * (darts[j][0] - darts[i][0]) / dist * Math.cos(locAngle) - r * (darts[j][1] - darts[i][1]) / dist * Math.sin(locAngle);
                const cy = darts[i][1] + r * (darts[j][0] - darts[i][0]) / dist * Math.sin(locAngle) + r * (darts[j][1] - darts[i][1]) / dist * Math.cos(locAngle);

                let cnt = 0;
                for (let l = 0; l < n; l++) {
                    const newDist = distance(darts[l][0], darts[l][1], cx, cy);
                    if (newDist <= r + 1e-5) cnt++;
                }

                maxDarts = Math.max(maxDarts, cnt);
            }
        }
    }

    return maxDarts;
}
```
For each dart pair (i, j), we calculate the distance between them, and check if it's smaller than or equal to the diameter (2*r) of the dartboard. If so, find the two possible centers (c1, c2) of the dartboard using trigonometry (getting the angle between the chord connecting two darts and the radius, and the angle between the radius and the wall), where i-th and j-th darts lie on the edge.

Then, for both possible centers of the dartboard, count how many darts in the array have a distance less than or equal to r and choose the highest value among all possible combinations of dart pairs and possible centers. This value is the maximum number of darts that can fit on the dartboard.


# Put Boxes Into the Warehouse I

- slug: put-boxes-into-the-warehouse-i
- difficulty: Medium

You are given two arrays of positive integers, `boxes` and `warehouse`, representing the heights of some boxes of unit width and the heights of `n` rooms in a warehouse respectively. The warehouse's rooms are labelled from `0` to `n - 1` from left to right where `warehouse[i]` (0-indexed) is the height of the `ith` room.

Boxes are put into the warehouse by the following rules:

*   Boxes cannot be stacked.
*   You can rearrange the insertion order of the boxes.
*   Boxes can only be pushed into the warehouse from left to right only.
*   If the height of some room in the warehouse is less than the height of a box, then that box and all other boxes behind it will be stopped before that room.

Return _the maximum number of boxes you can put into the warehouse._

**Example 1:**

**Input:** boxes = \[4,3,4,1\], warehouse = \[5,3,3,4,1\]
**Output:** 3
**Explanation:**

We can first put the box of height 1 in room 4. Then we can put the box of height 3 in either of the 3 rooms 1, 2, or 3. Lastly, we can put one box of height 4 in room 0.
There is no way we can fit all 4 boxes in the warehouse.

**Example 2:**

**Input:** boxes = \[1,2,2,3,4\], warehouse = \[3,4,1,2\]
**Output:** 3
**Explanation:**

Notice that it's not possible to put the box of height 4 into the warehouse since it cannot pass the first room of height 3.
Also, for the last two rooms, 2 and 3, only boxes of height 1 can fit.
We can fit 3 boxes maximum as shown above. The yellow box can also be put in room 2 instead.
Swapping the orange and green boxes is also valid, or swapping one of them with the red box.

**Example 3:**

**Input:** boxes = \[1,2,3\], warehouse = \[1,2,3,4\]
**Output:** 1
**Explanation:** Since the first room in the warehouse is of height 1, we can only put boxes of height 1.

**Constraints:**

*   `n == warehouse.length`
*   `1 <= boxes.length, warehouse.length <= 105`
*   `1 <= boxes[i], warehouse[i] <= 109`

## A solution in Java

```java
public int maxBoxesInWarehouse(int[] boxes, int[] warehouse) {
    int n = warehouse.length;
    for (int i = 1; i < n; i++)
        warehouse[i] = Math.min(warehouse[i], warehouse[i - 1]);
    Arrays.sort(boxes);
    int boxIndex = boxes.length - 1;
    int boxesCount = 0;
    for (int i = 0; i < n && boxIndex >= 0; i++) {
        if (boxes[boxIndex] <= warehouse[i]) {
            boxesCount++;
            boxIndex--;
        }
    }
    return boxesCount;
}
```
The main idea of the algorithm is to first preprocess the warehouse array such that for each room, it stores the minimum height up to that room. This is done to find the maximum height a box can have to be placed in a room considering previous rooms' heights. Then, reverse sort the boxes array to have the largest box first. Finally, iterate through the preprocessed warehouse array and compare the height of the current largest box with the height of the current room. If the box can fit, increment the count of boxes and move to the next box in the sorted array.

## A solution in C++

```cpp
int maxBoxesInWarehouse(vector<int>& boxes, vector<int>& warehouse) {
    int n = warehouse.size();
    for (int i = 1; i < n; i++)
        warehouse[i] = min(warehouse[i], warehouse[i - 1]);
    sort(boxes.rbegin(), boxes.rend());
    int boxIndex = 0;
    int boxesCount = 0;
    for (int i = 0; i < n && boxIndex < boxes.size(); i++) {
        if (boxes[boxIndex] <= warehouse[i]) {
            boxesCount++;
            boxIndex++;
        }
    }
    return boxesCount;
}
```
The main idea of the algorithm is to first preprocess the warehouse array such that for each room, it stores the minimum height up to that room. This is done to find the maximum height a box can have to be placed in a room considering previous rooms' heights. Then, reverse sort the boxes array to have the largest box first. Finally, iterate through the preprocessed warehouse array and compare the height of the current largest box with the height of the current room. If the box can fit, increment the count of boxes and move to the next box in the sorted array.

## A solution in Python

```python
def maxBoxesInWarehouse(boxes, warehouse):
    n = len(warehouse)
    for i in range(1, n):
        warehouse[i] = min(warehouse[i], warehouse[i - 1])
    boxes.sort(reverse=True)
    boxIndex = 0
    boxesCount = 0
    for i in range(n):
        if boxIndex < len(boxes) and boxes[boxIndex] <= warehouse[i]:
            boxesCount += 1
            boxIndex += 1
    return boxesCount
```
The main idea of the algorithm is to first preprocess the warehouse array such that for each room, it stores the minimum height up to that room. This is done to find the maximum height a box can have to be placed in a room considering previous rooms' heights. Then, reverse sort the boxes array to have the largest box first. Finally, iterate through the preprocessed warehouse array and compare the height of the current largest box with the height of the current room. If the box can fit, increment the count of boxes and move to the next box in the sorted array.

## A solution in Javascript

```javascript
function maxBoxesInWarehouse(boxes, warehouse) {
    let n = warehouse.length;
    for (let i = 1; i < n; i++)
        warehouse[i] = Math.min(warehouse[i], warehouse[i - 1]);
    boxes.sort((a, b) => b - a);
    let boxIndex = 0;
    let boxesCount = 0;
    for (let i = 0; i < n && boxIndex < boxes.length; i++) {
        if (boxes[boxIndex] <= warehouse[i]) {
            boxesCount++;
            boxIndex++;
        }
    }
    return boxesCount;
}
```
The main idea of the algorithm is to first preprocess the warehouse array such that for each room, it stores the minimum height up to that room. This is done to find the maximum height a box can have to be placed in a room considering previous rooms' heights. Then, reverse sort the boxes array to have the largest box first. Finally, iterate through the preprocessed warehouse array and compare the height of the current largest box with the height of the current room. If the box can fit, increment the count of boxes and move to the next box in the sorted array.


# Detect Pattern of Length M Repeated K or More Times

- slug: detect-pattern-of-length-m-repeated-k-or-more-times
- difficulty: Easy

Given an array of positive integers `arr`, find a pattern of length `m` that is repeated `k` or more times.

A **pattern** is a subarray (consecutive sub-sequence) that consists of one or more values, repeated multiple times **consecutively** without overlapping. A pattern is defined by its length and the number of repetitions.

Return `true` _if there exists a pattern of length_ `m` _that is repeated_ `k` _or more times, otherwise return_ `false`.

**Example 1:**

**Input:** arr = \[1,2,4,4,4,4\], m = 1, k = 3
**Output:** true
**Explanation:** The pattern **(4)** of length 1 is repeated 4 consecutive times. Notice that pattern can be repeated k or more times but not less.

**Example 2:**

**Input:** arr = \[1,2,1,2,1,1,1,3\], m = 2, k = 2
**Output:** true
**Explanation:** The pattern **(1,2)** of length 2 is repeated 2 consecutive times. Another valid pattern **(2,1) is** also repeated 2 times.

**Example 3:**

**Input:** arr = \[1,2,1,2,1,3\], m = 2, k = 3
**Output:** false
**Explanation:** The pattern (1,2) is of length 2 but is repeated only 2 times. There is no pattern of length 2 that is repeated 3 or more times.

**Constraints:**

*   `2 <= arr.length <= 100`
*   `1 <= arr[i] <= 100`
*   `1 <= m <= 100`
*   `2 <= k <= 100`

## A solution in Java

```java
public int isPrefixOfWord(String sentence, String searchWord) {
    String[] words = sentence.split(" ");
    for (int i = 0; i < words.length; i++) {
        if (words[i].startsWith(searchWord)) {
            return i + 1;
        }
    }
    return -1;
}
```
The algorithm for solving this problem consists of the following steps:
1. Split the given sentence into words based on the space delimiter.
2. Iterate over the list of words.
3. For each word, check if the searchWord is a prefix (using substring in C++, `startsWith()` in Java and JavaScript, and `startswith()` in Python).
4. If the searchWord is a prefix of the current word, return the current index (1-indexed).
5. If no word has searchWord as a prefix, return -1.

## A solution in C++

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

int isPrefixOfWord(std::string sentence, std::string searchWord) {
    std::istringstream iss(sentence);
    std::string word;
    int index = 1;
    while (iss >> word) {
        if (word.substr(0, searchWord.size()) == searchWord) {
            return index;
        }
        index++;
    }
    return -1;
}
```
The algorithm for solving this problem consists of the following steps:
1. Split the given sentence into words based on the space delimiter.
2. Iterate over the list of words.
3. For each word, check if the searchWord is a prefix (using substring in C++, `startsWith()` in Java and JavaScript, and `startswith()` in Python).
4. If the searchWord is a prefix of the current word, return the current index (1-indexed).
5. If no word has searchWord as a prefix, return -1.

## A solution in Python

```python
def is_prefix_of_word(sentence: str, search_word: str) -> int:
    words = sentence.split(' ')
    for index, word in enumerate(words, start=1):
        if word.startswith(search_word):
            return index
    return -1
```
The algorithm for solving this problem consists of the following steps:
1. Split the given sentence into words based on the space delimiter.
2. Iterate over the list of words.
3. For each word, check if the searchWord is a prefix (using substring in C++, `startsWith()` in Java and JavaScript, and `startswith()` in Python).
4. If the searchWord is a prefix of the current word, return the current index (1-indexed).
5. If no word has searchWord as a prefix, return -1.

## A solution in Javascript

```javascript
function isPrefixOfWord(sentence, searchWord) {
    const words = sentence.split(" ");
    for (let i = 0; i < words.length; i++) {
        if (words[i].startsWith(searchWord)) {
            return i + 1;
        }
    }
    return -1;
}
```
The algorithm for solving this problem consists of the following steps:
1. Split the given sentence into words based on the space delimiter.
2. Iterate over the list of words.
3. For each word, check if the searchWord is a prefix (using substring in C++, `startsWith()` in Java and JavaScript, and `startswith()` in Python).
4. If the searchWord is a prefix of the current word, return the current index (1-indexed).
5. If no word has searchWord as a prefix, return -1.


# Maximum Length of Subarray With Positive Product

- slug: maximum-length-of-subarray-with-positive-product
- difficulty: Medium

Given an array of integers `nums`, find the maximum length of a subarray where the product of all its elements is positive.

A subarray of an array is a consecutive sequence of zero or more values taken out of that array.

Return _the maximum length of a subarray with positive product_.

**Example 1:**

**Input:** nums = \[1,-2,-3,4\]
**Output:** 4
**Explanation:** The array nums already has a positive product of 24.

**Example 2:**

**Input:** nums = \[0,1,-2,-3,-4\]
**Output:** 3
**Explanation:** The longest subarray with positive product is \[1,-2,-3\] which has a product of 6.
Notice that we cannot include 0 in the subarray since that'll make the product 0 which is not positive.

**Example 3:**

**Input:** nums = \[-1,-2,-3,0,1\]
**Output:** 2
**Explanation:** The longest subarray with positive product is \[-1,-2\] or \[-2,-3\].

**Constraints:**

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

## A solution in Java

```java
public int maxVowels(String s, int k) {
    int max_count = 0, count = 0;
    for (int i = 0; i < s.length(); i++) {
        count += isVowel(s.charAt(i)) ? 1 : 0;
        if (i >= k)
            count -= isVowel(s.charAt(i - k)) ? 1 : 0;
        max_count = Math.max(max_count, count);
    }
    return max_count;
}

private boolean isVowel(char c) {
    return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
}
```
1. Initialize `max_count` and `count` variables to store the maximum count of consecutive vowels and the current count of vowels within the window of size `k`.
2. Iterate through each character in the input string `s`.
3. For each character, check if the character is a vowel. If it's a vowel, increment the `count` variable.
4. If the current index `i` is greater than or equal to `k`, then check if the character (`s[i - k]`) that is outside of the current `k`-sized window is a vowel. If it's a vowel, decrement the `count` variable.
5. At each iteration, update the `max_count` variable to store the maximum value of `count`.
6. Return the value of `max_count` after the loop.

## A solution in C++

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

int maxVowels(std::string s, int k) {
    int max_count = 0, count = 0;
    for (int i = 0; i < s.length(); i++) {
        count += (s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u');
        if (i >= k)
            count -= (s[i - k] == 'a' || s[i - k] == 'e' || s[i - k] == 'i' || s[i - k] == 'o' || s[i - k] == 'u');
        max_count = std::max(max_count, count);
    }
    return max_count;
}
```
1. Initialize `max_count` and `count` variables to store the maximum count of consecutive vowels and the current count of vowels within the window of size `k`.
2. Iterate through each character in the input string `s`.
3. For each character, check if the character is a vowel. If it's a vowel, increment the `count` variable.
4. If the current index `i` is greater than or equal to `k`, then check if the character (`s[i - k]`) that is outside of the current `k`-sized window is a vowel. If it's a vowel, decrement the `count` variable.
5. At each iteration, update the `max_count` variable to store the maximum value of `count`.
6. Return the value of `max_count` after the loop.

## A solution in Python

```python
def max_vowels(s, k):
    max_count = count = 0
    for i, c in enumerate(s):
        count += int(c in 'aeiou')
        if i >= k:
            count -= int(s[i - k] in 'aeiou')
        max_count = max(max_count, count)
    return max_count
```
1. Initialize `max_count` and `count` variables to store the maximum count of consecutive vowels and the current count of vowels within the window of size `k`.
2. Iterate through each character in the input string `s`.
3. For each character, check if the character is a vowel. If it's a vowel, increment the `count` variable.
4. If the current index `i` is greater than or equal to `k`, then check if the character (`s[i - k]`) that is outside of the current `k`-sized window is a vowel. If it's a vowel, decrement the `count` variable.
5. At each iteration, update the `max_count` variable to store the maximum value of `count`.
6. Return the value of `max_count` after the loop.

## A solution in Javascript

```javascript
function maxVowels(s, k) {
    let max_count = 0, count = 0;
    for (let i = 0; i < s.length; i++) {
        count += isVowel(s[i]) ? 1 : 0;
        if (i >= k)
            count -= isVowel(s[i - k]) ? 1 : 0;
        max_count = Math.max(max_count, count);
    }
    return max_count;
}

function isVowel(c) {
    return c === 'a' || c === 'e' || c === 'i' || c === 'o' || c === 'u';
}
```
1. Initialize `max_count` and `count` variables to store the maximum count of consecutive vowels and the current count of vowels within the window of size `k`.
2. Iterate through each character in the input string `s`.
3. For each character, check if the character is a vowel. If it's a vowel, increment the `count` variable.
4. If the current index `i` is greater than or equal to `k`, then check if the character (`s[i - k]`) that is outside of the current `k`-sized window is a vowel. If it's a vowel, decrement the `count` variable.
5. At each iteration, update the `max_count` variable to store the maximum value of `count`.
6. Return the value of `max_count` after the loop.


# Minimum Number of Days to Disconnect Island

- slug: minimum-number-of-days-to-disconnect-island
- difficulty: Hard

You are given an `m x n` binary grid `grid` where `1` represents land and `0` represents water. An **island** is a maximal **4-directionally** (horizontal or vertical) connected group of `1`'s.

The grid is said to be **connected** if we have **exactly one island**, otherwise is said **disconnected**.

In one day, we are allowed to change **any** single land cell `(1)` into a water cell `(0)`.

Return _the minimum number of days to disconnect the grid_.

**Example 1:**

**Input:** grid = \[\[0,1,1,0\],\[0,1,1,0\],\[0,0,0,0\]\]

**Output:** 2
**Explanation:** We need at least 2 days to get a disconnected grid.
Change land grid\[1\]\[1\] and grid\[0\]\[2\] to water and get 2 disconnected island.

**Example 2:**

**Input:** grid = \[\[1,1\]\]
**Output:** 2
**Explanation:** Grid of full water is also disconnected (\[\[1,1\]\] -> \[\[0,0\]\]), 0 islands.

**Constraints:**

*   `m == grid.length`
*   `n == grid[i].length`
*   `1 <= m, n <= 30`
*   `grid[i][j]` is either `0` or `1`.

## A solution in Java

```java
public int pseudoPalindromicPaths(TreeNode root, int cnt) {
    if (root == null) return 0;
    cnt ^= 1 << (root.val - 1);
    if (root.left == null && root.right == null)
        return (cnt & (cnt - 1)) == 0 ? 1 : 0;
    return pseudoPalindromicPaths(root.left, cnt) + pseudoPalindromicPaths(root.right, cnt);
}
```
The algorithm takes the root of the binary tree and iterates through each path from the root to leaf nodes using recursion. For each node in the path, it toggles the bit corresponding to the node's value in the integer `cnt`. The total number of non-empty pseudo-palindrome paths is found by recursively traversing the tree.

When encountering a leaf node, the algorithm checks if the bitwise-and between `cnt` and `(cnt - 1)` is equal to 0. If true, this means that at most one bit is set in `cnt`, which indicates a pseudo-palindrome as there are either zero or one nodes that have an odd count, and the rest of the nodes have even counts. If the condition is satisfied, return 1, otherwise, return 0.

The function then adds up the number of pseudo-palindromic paths found in all branches of the tree.

## A solution in C++

```cpp
int pseudoPalindromicPaths(TreeNode* root, int cnt = 0) {
    if (!root) return 0;
    cnt ^= 1 << (root->val - 1);
    if (!root->left && !root->right)
        return (cnt & (cnt - 1)) == 0;
    return pseudoPalindromicPaths(root->left, cnt) + pseudoPalindromicPaths(root->right, cnt);
}
```
The algorithm takes the root of the binary tree and iterates through each path from the root to leaf nodes using recursion. For each node in the path, it toggles the bit corresponding to the node's value in the integer `cnt`. The total number of non-empty pseudo-palindrome paths is found by recursively traversing the tree.

When encountering a leaf node, the algorithm checks if the bitwise-and between `cnt` and `(cnt - 1)` is equal to 0. If true, this means that at most one bit is set in `cnt`, which indicates a pseudo-palindrome as there are either zero or one nodes that have an odd count, and the rest of the nodes have even counts. If the condition is satisfied, return 1, otherwise, return 0.

The function then adds up the number of pseudo-palindromic paths found in all branches of the tree.

## A solution in Python

```python
def pseudoPalindromicPaths(root, cnt = 0):
    if not root:
        return 0
    cnt ^= 1 << (root.val - 1)
    if not root.left and not root.right:
        return (cnt & (cnt - 1)) == 0
    return pseudoPalindromicPaths(root.left, cnt) + pseudoPalindromicPaths(root.right, cnt)
```
The algorithm takes the root of the binary tree and iterates through each path from the root to leaf nodes using recursion. For each node in the path, it toggles the bit corresponding to the node's value in the integer `cnt`. The total number of non-empty pseudo-palindrome paths is found by recursively traversing the tree.

When encountering a leaf node, the algorithm checks if the bitwise-and between `cnt` and `(cnt - 1)` is equal to 0. If true, this means that at most one bit is set in `cnt`, which indicates a pseudo-palindrome as there are either zero or one nodes that have an odd count, and the rest of the nodes have even counts. If the condition is satisfied, return 1, otherwise, return 0.

The function then adds up the number of pseudo-palindromic paths found in all branches of the tree.

## A solution in Javascript

```javascript
function pseudoPalindromicPaths(root, cnt = 0) {
    if (!root) return 0;
    cnt ^= 1 << (root.val - 1);
    if (!root.left && !root.right)
        return (cnt & (cnt - 1)) == 0 ? 1 : 0;
    return pseudoPalindromicPaths(root.left, cnt) + pseudoPalindromicPaths(root.right, cnt);
}
```
The algorithm takes the root of the binary tree and iterates through each path from the root to leaf nodes using recursion. For each node in the path, it toggles the bit corresponding to the node's value in the integer `cnt`. The total number of non-empty pseudo-palindrome paths is found by recursively traversing the tree.

When encountering a leaf node, the algorithm checks if the bitwise-and between `cnt` and `(cnt - 1)` is equal to 0. If true, this means that at most one bit is set in `cnt`, which indicates a pseudo-palindrome as there are either zero or one nodes that have an odd count, and the rest of the nodes have even counts. If the condition is satisfied, return 1, otherwise, return 0.

The function then adds up the number of pseudo-palindromic paths found in all branches of the tree.


# Number of Ways to Reorder Array to Get Same BST

- slug: number-of-ways-to-reorder-array-to-get-same-bst
- difficulty: Hard

Given an array `nums` that represents a permutation of integers from `1` to `n`. We are going to construct a binary search tree (BST) by inserting the elements of `nums` in order into an initially empty BST. Find the number of different ways to reorder `nums` so that the constructed BST is identical to that formed from the original array `nums`.

*   For example, given `nums = [2,1,3]`, we will have 2 as the root, 1 as a left child, and 3 as a right child. The array `[2,3,1]` also yields the same BST but `[3,2,1]` yields a different BST.

Return _the number of ways to reorder_ `nums` _such that the BST formed is identical to the original BST formed from_ `nums`.

Since the answer may be very large, **return it modulo** `109 + 7`.

**Example 1:**

**Input:** nums = \[2,1,3\]
**Output:** 1
**Explanation:** We can reorder nums to be \[2,3,1\] which will yield the same BST. There are no other ways to reorder nums which will yield the same BST.

**Example 2:**

**Input:** nums = \[3,4,5,1,2\]
**Output:** 5
**Explanation:** The following 5 arrays will yield the same BST:
\[3,1,2,4,5\]
\[3,1,4,2,5\]
\[3,1,4,5,2\]
\[3,4,1,2,5\]
\[3,4,1,5,2\]

**Example 3:**

**Input:** nums = \[1,2,3\]
**Output:** 0
**Explanation:** There are no other orderings of nums that will yield the same BST.

**Constraints:**

*   `1 <= nums.length <= 1000`
*   `1 <= nums[i] <= nums.length`
*   All integers in `nums` are **distinct**.

## A solution in Java

```java
public int maxDotProduct(int[] nums1, int[] nums2) {
    int n = nums1.length, m = nums2.length;
    int[][] dp = new int[n + 1][m + 1];
    for (int i = 0; i <= n; ++i) {
        Arrays.fill(dp[i], Integer.MIN_VALUE);
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            dp[i][j] = Math.max(dp[i][j], Math.max(dp[i - 1][j], Math.max(dp[i][j - 1], Math.max(dp[i - 1][j - 1] + nums1[i - 1] * nums2[j - 1], nums1[i - 1] * nums2[j - 1]))));
        }
    }
    return dp[n][m];
}
```
The algorithm iterates over both input arrays with nested loops, creating a two-dimensional DP table. For each cell (i, j) in the table, it finds the maximum between multiple alternatives:
1. Previous value at dp[i][j]
2. Value at dp[i-1][j]
3. Value at dp[i][j-1]
4. Value at (dp[i-1][j-1] + nums1[i-1] * nums2[j-1]) (i.e., including a dot product at the current position)
5. Value at (nums1[i-1] * nums2[j-1]) (i.e., starting a new subsequence at the current position)

After filling the DP table, dp[n][m] contains the maximum dot product between the two input arrays.

## A solution in C++

```cpp
int maxDotProduct(vector<int>& nums1, vector<int>& nums2) {
    int n = nums1.size(), m = nums2.size();
    vector<vector<int>> dp(n + 1, vector<int>(m + 1, INT_MIN));
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            dp[i][j] = max({dp[i][j], dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1] + nums1[i - 1] * nums2[j - 1], nums1[i - 1] * nums2[j - 1]});
        }
    }
    return dp[n][m];
}
```
The algorithm iterates over both input arrays with nested loops, creating a two-dimensional DP table. For each cell (i, j) in the table, it finds the maximum between multiple alternatives:
1. Previous value at dp[i][j]
2. Value at dp[i-1][j]
3. Value at dp[i][j-1]
4. Value at (dp[i-1][j-1] + nums1[i-1] * nums2[j-1]) (i.e., including a dot product at the current position)
5. Value at (nums1[i-1] * nums2[j-1]) (i.e., starting a new subsequence at the current position)

After filling the DP table, dp[n][m] contains the maximum dot product between the two input arrays.

## A solution in Python

```python
def maxDotProduct(nums1, nums2):
    n, m = len(nums1), len(nums2)
    dp = [[float('-inf') for _ in range(m + 1)] for _ in range(n + 1)]
    for i in range(1, n + 1):
        for j in range(1, m + 1):
            dp[i][j] = max(dp[i][j], dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1] + nums1[i - 1] * nums2[j - 1], nums1[i - 1] * nums2[j - 1])
    return dp[n][m]
```
The algorithm iterates over both input arrays with nested loops, creating a two-dimensional DP table. For each cell (i, j) in the table, it finds the maximum between multiple alternatives:
1. Previous value at dp[i][j]
2. Value at dp[i-1][j]
3. Value at dp[i][j-1]
4. Value at (dp[i-1][j-1] + nums1[i-1] * nums2[j-1]) (i.e., including a dot product at the current position)
5. Value at (nums1[i-1] * nums2[j-1]) (i.e., starting a new subsequence at the current position)

After filling the DP table, dp[n][m] contains the maximum dot product between the two input arrays.

## A solution in Javascript

```javascript
function maxDotProduct(nums1, nums2) {
    const n = nums1.length, m = nums2.length;
    const dp = Array.from(Array(n + 1), () => Array(m + 1).fill(Number.MIN_SAFE_INTEGER));
    for (let i = 1; i <= n; ++i) {
        for (let j = 1; j <= m; ++j) {
            dp[i][j] = Math.max(dp[i][j], dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1] + nums1[i - 1] * nums2[j - 1], nums1[i - 1] * nums2[j - 1]);
        }
    }
    return dp[n][m];
}
```
The algorithm iterates over both input arrays with nested loops, creating a two-dimensional DP table. For each cell (i, j) in the table, it finds the maximum between multiple alternatives:
1. Previous value at dp[i][j]
2. Value at dp[i-1][j]
3. Value at dp[i][j-1]
4. Value at (dp[i-1][j-1] + nums1[i-1] * nums2[j-1]) (i.e., including a dot product at the current position)
5. Value at (nums1[i-1] * nums2[j-1]) (i.e., starting a new subsequence at the current position)

After filling the DP table, dp[n][m] contains the maximum dot product between the two input arrays.


# Dot Product of Two Sparse Vectors

- slug: dot-product-of-two-sparse-vectors
- difficulty: Medium

Given two sparse vectors, compute their dot product.

Implement class `SparseVector`:

*   `SparseVector(nums)` Initializes the object with the vector `nums`
*   `dotProduct(vec)` Compute the dot product between the instance of _SparseVector_ and `vec`

A **sparse vector** is a vector that has mostly zero values, you should store the sparse vector **efficiently** and compute the dot product between two _SparseVector_.

**Follow up:** What if only one of the vectors is sparse?

**Example 1:**

**Input:** nums1 = \[1,0,0,2,3\], nums2 = \[0,3,0,4,0\]
**Output:** 8
**Explanation:** v1 = SparseVector(nums1) , v2 = SparseVector(nums2)
v1.dotProduct(v2) = 1\*0 + 0\*3 + 0\*0 + 2\*4 + 3\*0 = 8

**Example 2:**

**Input:** nums1 = \[0,1,0,0,0\], nums2 = \[0,0,0,0,2\]
**Output:** 0
**Explanation:** v1 = SparseVector(nums1) , v2 = SparseVector(nums2)
v1.dotProduct(v2) = 0\*0 + 1\*0 + 0\*0 + 0\*0 + 0\*2 = 0

**Example 3:**

**Input:** nums1 = \[0,1,0,0,2,0,0\], nums2 = \[1,0,0,0,3,0,4\]
**Output:** 6

**Constraints:**

*   `n == nums1.length == nums2.length`
*   `1 <= n <= 10^5`
*   `0 <= nums1[i], nums2[i] <= 100`

## A solution in Java

```java
public int[] finalPrices(int[] prices) {
    for(int i = 0; i < prices.length; i++) {
        for(int j = i + 1; j < prices.length; j++) {
            if(prices[j] <= prices[i]) {
                prices[i] -= prices[j];
                break;
            }
        }
    }
    return prices;
}
```
The algorithm iterates through each element `i` in the `prices` array. For each element, it iterates through the remaining elements (from `i+1` to the end), looking for an element `j` such that `prices[j] <= prices[i]`. If such an element is found, we subtract `prices[j]` from `prices[i]` and then move on to the next element. This is done using nested loops.

The outer loop iterates through all the elements in the array, and the inner loop checks for eligible discounts. Only one discount per item is applied, hence the `break` statement after an applicable discount is found.

The running time complexity of this algorithm is O(n^2), where "n" is the length of the input array. This is because, in the worst case, all pairs of elements need to be checked.

## A solution in C++

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

vector<int> finalPrices(vector<int>& prices) {
    for(int i = 0; i < prices.size(); i++) {
        for(int j = i + 1; j < prices.size(); j++) {
            if(prices[j] <= prices[i]) {
                prices[i] -= prices[j];
                break;
            }
        }
    }
    return prices;
}
```
The algorithm iterates through each element `i` in the `prices` array. For each element, it iterates through the remaining elements (from `i+1` to the end), looking for an element `j` such that `prices[j] <= prices[i]`. If such an element is found, we subtract `prices[j]` from `prices[i]` and then move on to the next element. This is done using nested loops.

The outer loop iterates through all the elements in the array, and the inner loop checks for eligible discounts. Only one discount per item is applied, hence the `break` statement after an applicable discount is found.

The running time complexity of this algorithm is O(n^2), where "n" is the length of the input array. This is because, in the worst case, all pairs of elements need to be checked.

## A solution in Python

```python
def final_prices(prices):
    for i in range(len(prices)):
        for j in range(i + 1, len(prices)):
            if prices[j] <= prices[i]:
                prices[i] -= prices[j]
                break
    return prices
```
The algorithm iterates through each element `i` in the `prices` array. For each element, it iterates through the remaining elements (from `i+1` to the end), looking for an element `j` such that `prices[j] <= prices[i]`. If such an element is found, we subtract `prices[j]` from `prices[i]` and then move on to the next element. This is done using nested loops.

The outer loop iterates through all the elements in the array, and the inner loop checks for eligible discounts. Only one discount per item is applied, hence the `break` statement after an applicable discount is found.

The running time complexity of this algorithm is O(n^2), where "n" is the length of the input array. This is because, in the worst case, all pairs of elements need to be checked.

## A solution in Javascript

```javascript
function finalPrices(prices) {
    for(let i = 0; i < prices.length; i++) {
        for(let j = i + 1; j < prices.length; j++) {
            if(prices[j] <= prices[i]) {
                prices[i] -= prices[j];
                break;
            }
        }
    }
    return prices;
}
```
The algorithm iterates through each element `i` in the `prices` array. For each element, it iterates through the remaining elements (from `i+1` to the end), looking for an element `j` such that `prices[j] <= prices[i]`. If such an element is found, we subtract `prices[j]` from `prices[i]` and then move on to the next element. This is done using nested loops.

The outer loop iterates through all the elements in the array, and the inner loop checks for eligible discounts. Only one discount per item is applied, hence the `break` statement after an applicable discount is found.

The running time complexity of this algorithm is O(n^2), where "n" is the length of the input array. This is because, in the worst case, all pairs of elements need to be checked.


# Matrix Diagonal Sum

- slug: matrix-diagonal-sum
- difficulty: Easy

Given a square matrix `mat`, return the sum of the matrix diagonals.

Only include the sum of all the elements on the primary diagonal and all the elements on the secondary diagonal that are not part of the primary diagonal.

**Example 1:**

**Input:** mat = \[\[**1**,2,**3**\],
              \[4,**5**,6\],
              \[**7**,8,**9**\]\]
**Output:** 25
**Explanation:** Diagonals sum: 1 + 5 + 9 + 3 + 7 = 25
Notice that element mat\[1\]\[1\] = 5 is counted only once.

**Example 2:**

**Input:** mat = \[\[**1**,1,1,**1**\],
              \[1,**1**,**1**,1\],
              \[1,**1**,**1**,1\],
              \[**1**,1,1,**1**\]\]
**Output:** 8

**Example 3:**

**Input:** mat = \[\[**5**\]\]
**Output:** 5

**Constraints:**

*   `n == mat.length == mat[i].length`
*   `1 <= n <= 100`
*   `1 <= mat[i][j] <= 100`

## A solution in Java

```java
class SubrectangleQueries {
    int[][] rectangle;

    public SubrectangleQueries(int[][] rectangle) {
        this.rectangle = rectangle;
    }

    public void updateSubrectangle(int row1, int col1, int row2, int col2, int newValue) {
        for(int i = row1; i <= row2; i++) {
            for(int j = col1; j <= col2; j++) {
                rectangle[i][j] = newValue;
            }
        }
    }

    public int getValue(int row, int col) {
        return rectangle[row][col];
    }
}
```
The algorithm creates a class `SubrectangleQueries` that takes a 2D matrix called `rectangle` as input. It has two methods: `updateSubrectangle` and `getValue`.

`updateSubrectangle()` takes five parameters: row1, col1, row2, col2, and newValue. It iterates over the subrectangle with top-left corner (row1, col1) and bottom-right corner (row2, col2) and updates all the values inside it to newValue.

`getValue()` is a simple getter function that takes row and col as parameters and returns the value located at rectangle[row][col].

## A solution in C++

```cpp
class SubrectangleQueries {
public:
    vector<vector<int>> rectangle;
    SubrectangleQueries(vector<vector<int>>& rectangle) {
        this->rectangle = rectangle;
    }

    void updateSubrectangle(int row1, int col1, int row2, int col2, int newValue) {
        for(int i = row1; i <= row2; i++) {
            for(int j = col1; j <= col2; j++) {
                rectangle[i][j] = newValue;
            }
        }
    }

    int getValue(int row, int col) {
        return rectangle[row][col];
    }
};
```
The algorithm creates a class `SubrectangleQueries` that takes a 2D matrix called `rectangle` as input. It has two methods: `updateSubrectangle` and `getValue`.

`updateSubrectangle()` takes five parameters: row1, col1, row2, col2, and newValue. It iterates over the subrectangle with top-left corner (row1, col1) and bottom-right corner (row2, col2) and updates all the values inside it to newValue.

`getValue()` is a simple getter function that takes row and col as parameters and returns the value located at rectangle[row][col].

## A solution in Python

```python
class SubrectangleQueries:
    def __init__(self, rectangle: List[List[int]]):
        self.rectangle = rectangle

    def updateSubrectangle(self, row1: int, col1: int, row2: int, col2: int, newValue: int) -> None:
        for i in range(row1, row2 + 1):
            for j in range(col1, col2 + 1):
                self.rectangle[i][j] = newValue

    def getValue(self, row: int, col: int) -> int:
        return self.rectangle[row][col]
```
The algorithm creates a class `SubrectangleQueries` that takes a 2D matrix called `rectangle` as input. It has two methods: `updateSubrectangle` and `getValue`.

`updateSubrectangle()` takes five parameters: row1, col1, row2, col2, and newValue. It iterates over the subrectangle with top-left corner (row1, col1) and bottom-right corner (row2, col2) and updates all the values inside it to newValue.

`getValue()` is a simple getter function that takes row and col as parameters and returns the value located at rectangle[row][col].

## A solution in Javascript

```javascript
class SubrectangleQueries {
    constructor(rectangle) {
        this.rectangle = rectangle;
    }

    updateSubrectangle(row1, col1, row2, col2, newValue) {
        for(let i = row1; i <= row2; i++) {
            for(let j = col1; j <= col2; j++) {
                this.rectangle[i][j] = newValue;
            }
        }
    }

    getValue(row, col) {
        return this.rectangle[row][col];
    }
}
```
The algorithm creates a class `SubrectangleQueries` that takes a 2D matrix called `rectangle` as input. It has two methods: `updateSubrectangle` and `getValue`.

`updateSubrectangle()` takes five parameters: row1, col1, row2, col2, and newValue. It iterates over the subrectangle with top-left corner (row1, col1) and bottom-right corner (row2, col2) and updates all the values inside it to newValue.

`getValue()` is a simple getter function that takes row and col as parameters and returns the value located at rectangle[row][col].


# Number of Ways to Split a String

- slug: number-of-ways-to-split-a-string
- difficulty: Medium

Given a binary string `s`, you can split `s` into 3 **non-empty** strings `s1`, `s2`, and `s3` where `s1 + s2 + s3 = s`.

Return the number of ways `s` can be split such that the number of ones is the same in `s1`, `s2`, and `s3`. Since the answer may be too large, return it **modulo** `109 + 7`.

**Example 1:**

**Input:** s =  "10101 "
**Output:** 4
**Explanation:** There are four ways to split s in 3 parts where each part contain the same number of letters '1'.
 "1|010|1 "
 "1|01|01 "
 "10|10|1 "
 "10|1|01 "

**Example 2:**

**Input:** s =  "1001 "
**Output:** 0

**Example 3:**

**Input:** s =  "0000 "
**Output:** 3
**Explanation:** There are three ways to split s in 3 parts.
 "0|0|00 "
 "0|00|0 "
 "00|0|0 "

**Constraints:**

*   `3 <= s.length <= 105`
*   `s[i]` is either `'0'` or `'1'`.

## A solution in Java

```java
import java.util.HashMap;

public int minSumOfLengths(int[] arr, int target) {
    int n = arr.length, sum = 0, minLen = Integer.MAX_VALUE, result = Integer.MAX_VALUE;
    HashMap<Integer, Integer> map = new HashMap<>();
    map.put(0, -1);

    for (int i = 0; i < n; ++i) {
        sum += arr[i];
        if (sum >= target && map.containsKey(sum - target)) {
            if (map.get(sum - target) > -1 && minLen != Integer.MAX_VALUE) {
                result = Math.min(result, i - map.get(sum - target) + minLen);
            }
            minLen = Math.min(minLen, i - map.get(sum - target));
        }
        map.put(sum, i);
    }
    return result == Integer.MAX_VALUE ? -1 : result;
}
```
1. Initialize sum, min_len, result, and a map to store the prefix sum and its index.
2. Iterate through the array, keeping track of the running sum.
3. Check if running sum is greater than or equal to target and if the difference between running sum and target exists in the map:
   a. If yes, then check if the index associated with the difference is greater than -1 and min_len is not infinite.
      i. Update the result by taking the minimum between the result and the sum of the current index, min_len, and difference of the index associated with the found difference.
   b. Update min_len by taking the minimum between min_len and the difference of the current index i and the index associated with the found difference.
4. Return result if it is not infinite; otherwise, return -1.

## A solution in C++

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

int min_sum_of_lengths(std::vector<int> &arr, int target) {
    int n = arr.size(), sum = 0, min_len = std::numeric_limits<int>::max();
    int result = std::numeric_limits<int>::max();
    std::unordered_map<int, int> mp;
    mp.reserve(n + 1);
    mp[0] = -1;

    for (int i = 0; i < n; ++i) {
        sum += arr[i];
        if (sum >= target && mp.count(sum - target) > 0) {
            if (mp[sum - target] > -1 && min_len != std::numeric_limits<int>::max()) {
                result = std::min(result, i - mp[sum - target] + min_len);
            }
            min_len = std::min(min_len, i - mp[sum - target]);
        }
        mp[sum] = i;
    }
    return result == std::numeric_limits<int>::max() ? -1 : result;
}
```
1. Initialize sum, min_len, result, and a map to store the prefix sum and its index.
2. Iterate through the array, keeping track of the running sum.
3. Check if running sum is greater than or equal to target and if the difference between running sum and target exists in the map:
   a. If yes, then check if the index associated with the difference is greater than -1 and min_len is not infinite.
      i. Update the result by taking the minimum between the result and the sum of the current index, min_len, and difference of the index associated with the found difference.
   b. Update min_len by taking the minimum between min_len and the difference of the current index i and the index associated with the found difference.
4. Return result if it is not infinite; otherwise, return -1.

## A solution in Python

```python
def min_sum_of_lengths(arr, target):
    n = len(arr)
    sum_, min_len, result = 0, float('inf'), float('inf')
    mp = {0: -1}

    for i in range(n):
        sum_ += arr[i]
        if sum_ >= target and (sum_ - target) in mp:
            if mp[sum_ - target] > -1 and min_len != float('inf'):
                result = min(result, i - mp[sum_ - target] + min_len)
            min_len = min(min_len, i - mp[sum_ - target])
        mp[sum_] = i

    return result if result != float('inf') else -1
```
1. Initialize sum, min_len, result, and a map to store the prefix sum and its index.
2. Iterate through the array, keeping track of the running sum.
3. Check if running sum is greater than or equal to target and if the difference between running sum and target exists in the map:
   a. If yes, then check if the index associated with the difference is greater than -1 and min_len is not infinite.
      i. Update the result by taking the minimum between the result and the sum of the current index, min_len, and difference of the index associated with the found difference.
   b. Update min_len by taking the minimum between min_len and the difference of the current index i and the index associated with the found difference.
4. Return result if it is not infinite; otherwise, return -1.

## A solution in Javascript

```javascript
function minSumOfLengths(arr, target) {
    const n = arr.length, mp = new Map();
    let sum = 0, minLen = Infinity, result = Infinity;
    mp.set(0, -1);

    for (let i = 0; i < n; ++i) {
        sum += arr[i];
        if (sum >= target && mp.has(sum - target)) {
            if (mp.get(sum - target) > -1 && minLen !== Infinity) {
                result = Math.min(result, i - mp.get(sum - target) + minLen);
            }
            minLen = Math.min(minLen, i - mp.get(sum - target));
        }
        mp.set(sum, i);
    }
    return result === Infinity ? -1 : result;
}
```
1. Initialize sum, min_len, result, and a map to store the prefix sum and its index.
2. Iterate through the array, keeping track of the running sum.
3. Check if running sum is greater than or equal to target and if the difference between running sum and target exists in the map:
   a. If yes, then check if the index associated with the difference is greater than -1 and min_len is not infinite.
      i. Update the result by taking the minimum between the result and the sum of the current index, min_len, and difference of the index associated with the found difference.
   b. Update min_len by taking the minimum between min_len and the difference of the current index i and the index associated with the found difference.
4. Return result if it is not infinite; otherwise, return -1.


# Shortest Subarray to be Removed to Make Array Sorted

- slug: shortest-subarray-to-be-removed-to-make-array-sorted
- difficulty: Medium

Given an integer array `arr`, remove a subarray (can be empty) from `arr` such that the remaining elements in `arr` are **non-decreasing**.

Return _the length of the shortest subarray to remove_.

A **subarray** is a contiguous subsequence of the array.

**Example 1:**

**Input:** arr = \[1,2,3,10,4,2,3,5\]
**Output:** 3
**Explanation:** The shortest subarray we can remove is \[10,4,2\] of length 3. The remaining elements after that will be \[1,2,3,3,5\] which are sorted.
Another correct solution is to remove the subarray \[3,10,4\].

**Example 2:**

**Input:** arr = \[5,4,3,2,1\]
**Output:** 4
**Explanation:** Since the array is strictly decreasing, we can only keep a single element. Therefore we need to remove a subarray of length 4, either \[5,4,3,2\] or \[4,3,2,1\].

**Example 3:**

**Input:** arr = \[1,2,3\]
**Output:** 0
**Explanation:** The array is already non-decreasing. We do not need to remove any elements.

**Constraints:**

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

## A solution in Java

```java
public int findLengthOfShortestSubarray(int[] arr) {
    int n = arr.length, left = 0, right = n - 1;
    while (left < n - 1 && arr[left] <= arr[left + 1]) left++;
    if (left == n - 1) return 0;
    while (right > 0 && arr[right] >= arr[right - 1]) right--;
    int result = Math.min(n - left - 1, right);
    for (int i = 0, j = right; i <= left && j < n;) {
        if (arr[i] <= arr[j]) {
            result = Math.min(result, j - i - 1);
            i++;
        } else {
            j++;
        }
    }
    return result;
}
```
The algorithm starts by finding the longest non-decreasing subarray from both ends (left and right) of the array. If the left index reaches the end of the array, it means the array is already non-decreasing and we can return 0.

Then, we initialize the result as the minimum of the remaining subarray lengths on the left side and the right side. We use two pointers i and j starting from the left index and the right index, respectively.

We iterate through the array and compare the values of arr[i] and arr[j]. If arr[i] <= arr[j], it means the subarray from i to j can be non-decreasing, so we update the result with the minimum length of this subarray. If arr[i] > arr[j], we increment j.

When the loop finishes, the result is the length of the shortest subarray to remove to make the remaining elements non-decreasing.

## A solution in C++

```cpp
int findLengthOfShortestSubarray(vector<int>& arr) {
    int n = arr.size(), left = 0, right = n - 1;
    while (left < n - 1 && arr[left] <= arr[left + 1]) left++;
    if (left == n - 1) return 0;
    while (right > 0 && arr[right] >= arr[right - 1]) right--;
    int result = min(n - left - 1, right);
    for (int i = 0, j = right; i <= left && j < n;) {
        if (arr[i] <= arr[j]) {
            result = min(result, j - i - 1);
            i++;
        } else {
            j++;
        }
    }
    return result;
}
```
The algorithm starts by finding the longest non-decreasing subarray from both ends (left and right) of the array. If the left index reaches the end of the array, it means the array is already non-decreasing and we can return 0.

Then, we initialize the result as the minimum of the remaining subarray lengths on the left side and the right side. We use two pointers i and j starting from the left index and the right index, respectively.

We iterate through the array and compare the values of arr[i] and arr[j]. If arr[i] <= arr[j], it means the subarray from i to j can be non-decreasing, so we update the result with the minimum length of this subarray. If arr[i] > arr[j], we increment j.

When the loop finishes, the result is the length of the shortest subarray to remove to make the remaining elements non-decreasing.

## A solution in Python

```python
def findLengthOfShortestSubarray(arr):
    n = len(arr)
    left, right = 0, n - 1
    while left < n - 1 and arr[left] <= arr[left + 1]:
        left += 1
    if left == n - 1:
        return 0
    while right > 0 and arr[right] >= arr[right - 1]:
        right -= 1
    result = min(n - left - 1, right)
    i, j = 0, right
    while i <= left and j < n:
        if arr[i] <= arr[j]:
            result = min(result, j - i - 1)
            i += 1
        else:
            j += 1
    return result
```
The algorithm starts by finding the longest non-decreasing subarray from both ends (left and right) of the array. If the left index reaches the end of the array, it means the array is already non-decreasing and we can return 0.

Then, we initialize the result as the minimum of the remaining subarray lengths on the left side and the right side. We use two pointers i and j starting from the left index and the right index, respectively.

We iterate through the array and compare the values of arr[i] and arr[j]. If arr[i] <= arr[j], it means the subarray from i to j can be non-decreasing, so we update the result with the minimum length of this subarray. If arr[i] > arr[j], we increment j.

When the loop finishes, the result is the length of the shortest subarray to remove to make the remaining elements non-decreasing.

## A solution in Javascript

```javascript
function findLengthOfShortestSubarray(arr) {
    const n = arr.length;
    let left = 0, right = n - 1;
    while (left < n - 1 && arr[left] <= arr[left + 1]) left++;
    if (left === n - 1) return 0;
    while (right > 0 && arr[right] >= arr[right - 1]) right--;
    let result = Math.min(n - left - 1, right);
    let i = 0, j = right;
    while (i <= left && j < n) {
        if (arr[i] <= arr[j]) {
            result = Math.min(result, j - i - 1);
            i++;
        } else {
            j++;
        }
    }
    return result;
}
```
The algorithm starts by finding the longest non-decreasing subarray from both ends (left and right) of the array. If the left index reaches the end of the array, it means the array is already non-decreasing and we can return 0.

Then, we initialize the result as the minimum of the remaining subarray lengths on the left side and the right side. We use two pointers i and j starting from the left index and the right index, respectively.

We iterate through the array and compare the values of arr[i] and arr[j]. If arr[i] <= arr[j], it means the subarray from i to j can be non-decreasing, so we update the result with the minimum length of this subarray. If arr[i] > arr[j], we increment j.

When the loop finishes, the result is the length of the shortest subarray to remove to make the remaining elements non-decreasing.


# Count All Possible Routes

- slug: count-all-possible-routes
- difficulty: Hard

You are given an array of **distinct** positive integers locations where `locations[i]` represents the position of city `i`. You are also given integers `start`, `finish` and `fuel` representing the starting city, ending city, and the initial amount of fuel you have, respectively.

At each step, if you are at city `i`, you can pick any city `j` such that `j != i` and `0 <= j < locations.length` and move to city `j`. Moving from city `i` to city `j` reduces the amount of fuel you have by `|locations[i] - locations[j]|`. Please notice that `|x|` denotes the absolute value of `x`.

Notice that `fuel` **cannot** become negative at any point in time, and that you are **allowed** to visit any city more than once (including `start` and `finish`).

Return _the count of all possible routes from_ `start` _to_ `finish`. Since the answer may be too large, return it modulo `109 + 7`.

**Example 1:**

**Input:** locations = \[2,3,6,8,4\], start = 1, finish = 3, fuel = 5
**Output:** 4
**Explanation:** The following are all possible routes, each uses 5 units of fuel:
1 -> 3
1 -> 2 -> 3
1 -> 4 -> 3
1 -> 4 -> 2 -> 3

**Example 2:**

**Input:** locations = \[4,3,1\], start = 1, finish = 0, fuel = 6
**Output:** 5
**Explanation:** The following are all possible routes:
1 -> 0, used fuel = 1
1 -> 2 -> 0, used fuel = 5
1 -> 2 -> 1 -> 0, used fuel = 5
1 -> 0 -> 1 -> 0, used fuel = 3
1 -> 0 -> 1 -> 0 -> 1 -> 0, used fuel = 5

**Example 3:**

**Input:** locations = \[5,2,1\], start = 0, finish = 2, fuel = 3
**Output:** 0
**Explanation:** It is impossible to get from 0 to 2 using only 3 units of fuel since the shortest route needs 4 units of fuel.

**Constraints:**

*   `2 <= locations.length <= 100`
*   `1 <= locations[i] <= 109`
*   All integers in `locations` are **distinct**.
*   `0 <= start, finish < locations.length`
*   `1 <= fuel <= 200`

## A solution in Java

```java
import java.util.Arrays;

public int maxArea(int h, int w, int[] horizontalCuts, int[] verticalCuts) {
    Arrays.sort(horizontalCuts);
    Arrays.sort(verticalCuts);

    int maxH = Math.max(horizontalCuts[0], h - horizontalCuts[horizontalCuts.length - 1]);
    int maxV = Math.max(verticalCuts[0], w - verticalCuts[verticalCuts.length - 1]);

    for (int i = 1; i < horizontalCuts.length; ++i) {
        maxH = Math.max(maxH, horizontalCuts[i] - horizontalCuts[i - 1]);
    }

    for (int i = 1; i < verticalCuts.length; ++i) {
        maxV = Math.max(maxV, verticalCuts[i] - verticalCuts[i - 1]);
    }

    return (int)((long)maxH * maxV % 1000000007);
}
```
1. Sort both horizontalCuts and verticalCuts arrays in ascending order.
2. Calculate the initial values of maxH and maxV as the maximum of the first cut distance and the distance from the last cut to the cake's edge.
3. Loop through each cut in both arrays (starting from index 1), updating maxH and maxV to be the maximum value between their current value and the difference between the current cut and the previous cut. This will give us the largest distance between cuts for both horizontal and vertical directions.
4. Return the product of maxH and maxV modulo 10^9 + 7.

## A solution in C++

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

int maxArea(int h, int w, vector<int>& horizontalCuts, vector<int>& verticalCuts) {
    sort(horizontalCuts.begin(), horizontalCuts.end());
    sort(verticalCuts.begin(), verticalCuts.end());

    int maxH = max(horizontalCuts[0], h - horizontalCuts.back());
    int maxV = max(verticalCuts[0], w - verticalCuts.back());

    for (int i = 1; i < horizontalCuts.size(); ++i) {
        maxH = max(maxH, horizontalCuts[i] - horizontalCuts[i - 1]);
    }

    for (int i = 1; i < verticalCuts.size(); ++i) {
        maxV = max(maxV, verticalCuts[i] - verticalCuts[i - 1]);
    }

    return (long long)maxH * maxV % 1000000007;
}
```
1. Sort both horizontalCuts and verticalCuts arrays in ascending order.
2. Calculate the initial values of maxH and maxV as the maximum of the first cut distance and the distance from the last cut to the cake's edge.
3. Loop through each cut in both arrays (starting from index 1), updating maxH and maxV to be the maximum value between their current value and the difference between the current cut and the previous cut. This will give us the largest distance between cuts for both horizontal and vertical directions.
4. Return the product of maxH and maxV modulo 10^9 + 7.

## A solution in Python

```python
def maxArea(h, w, horizontalCuts, verticalCuts):
    horizontalCuts.sort()
    verticalCuts.sort()

    maxH = max(horizontalCuts[0], h - horizontalCuts[-1])
    maxV = max(verticalCuts[0], w - verticalCuts[-1])

    for i in range(1, len(horizontalCuts)):
        maxH = max(maxH, horizontalCuts[i] - horizontalCuts[i - 1])

    for i in range(1, len(verticalCuts)):
        maxV = max(maxV, verticalCuts[i] - verticalCuts[i - 1])

    return (maxH * maxV) % (10**9 + 7)
```
1. Sort both horizontalCuts and verticalCuts arrays in ascending order.
2. Calculate the initial values of maxH and maxV as the maximum of the first cut distance and the distance from the last cut to the cake's edge.
3. Loop through each cut in both arrays (starting from index 1), updating maxH and maxV to be the maximum value between their current value and the difference between the current cut and the previous cut. This will give us the largest distance between cuts for both horizontal and vertical directions.
4. Return the product of maxH and maxV modulo 10^9 + 7.

## A solution in Javascript

```javascript
function maxArea(h, w, horizontalCuts, verticalCuts) {
    horizontalCuts.sort((a, b) => a - b);
    verticalCuts.sort((a, b) => a - b);

    let maxH = Math.max(horizontalCuts[0], h - horizontalCuts[horizontalCuts.length - 1]);
    let maxV = Math.max(verticalCuts[0], w - verticalCuts[verticalCuts.length - 1]);

    for (let i = 1; i < horizontalCuts.length; ++i) {
        maxH = Math.max(maxH, horizontalCuts[i] - horizontalCuts[i - 1]);
    }

    for (let i = 1; i < verticalCuts.length; ++i) {
        maxV = Math.max(maxV, verticalCuts[i] - verticalCuts[i - 1]);
    }

    return BigInt(maxH) * BigInt(maxV) % 1000000007n;
}
```
1. Sort both horizontalCuts and verticalCuts arrays in ascending order.
2. Calculate the initial values of maxH and maxV as the maximum of the first cut distance and the distance from the last cut to the cake's edge.
3. Loop through each cut in both arrays (starting from index 1), updating maxH and maxV to be the maximum value between their current value and the difference between the current cut and the previous cut. This will give us the largest distance between cuts for both horizontal and vertical directions.
4. Return the product of maxH and maxV modulo 10^9 + 7.


# Replace All ?'s to Avoid Consecutive Repeating Characters

- slug: replace-all-s-to-avoid-consecutive-repeating-characters
- difficulty: Easy

Given a string `s` containing only lowercase English letters and the `'?'` character, convert **all** the `'?'` characters into lowercase letters such that the final string does not contain any **consecutive repeating** characters. You **cannot** modify the non `'?'` characters.

It is **guaranteed** that there are no consecutive repeating characters in the given string **except** for `'?'`.

Return _the final string after all the conversions (possibly zero) have been made_. If there is more than one solution, return **any of them**. It can be shown that an answer is always possible with the given constraints.

**Example 1:**

**Input:** s =  "?zs "
**Output:**  "azs "
**Explanation:** There are 25 solutions for this problem. From  "azs " to  "yzs ", all are valid. Only  "z " is an invalid modification as the string will consist of consecutive repeating characters in  "zzs ".

**Example 2:**

**Input:** s =  "ubv?w "
**Output:**  "ubvaw "
**Explanation:** There are 24 solutions for this problem. Only  "v " and  "w " are invalid modifications as the strings will consist of consecutive repeating characters in  "ubvvw " and  "ubvww ".

**Constraints:**

*   `1 <= s.length <= 100`
*   `s` consist of lowercase English letters and `'?'`.

## A solution in Java

```java
import java.util.*;

class Solution {
    public void dfs(int node, int parent, List<List<Integer>> graph, int[] count) {
        if (node != 0 && parent == 0) count[0]++;

        for (int neighbor : graph.get(node)) {
            if (neighbor != parent) {
                dfs(neighbor, node, graph, count);
            }
        }
    }

    public int minReorder(int n, int[][] connections) {
        List<List<Integer>> graph = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            graph.add(new ArrayList<>());
        }

        for (int[] c : connections) {
            graph.get(c[0]).add(c[1]);
            graph.get(c[1]).add(c[0]);
        }

        int[] count = {0};
        dfs(0, -1, graph, count);
        return count[0];
    }
}
```
The algorithm used in the code snippet uses a Depth-First Search (DFS) approach for traversing the given graph of cities represented by nodes and roads represented by connections. The dfs() functions are called on every node and their respective parents, and the result stores the minimum number of edges that should be changed.

Initially, the graph is created with each city having a list of its neighboring cities (bi-directional). The DFS algorithm starts traversing the graph from city 0 and recursively visits its neighboring nodes, and the edges that need to be adjusted are kept track of with the 'count' variable.

Whenever DFS encounters a city with a direct road towards city 0, 1 is added to the count. The minimum number of required edge changes will be the value of count. The final answer returned is the count of edges needed to be changed for all cities to reach city 0.

## A solution in C++

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

void dfs(int node, int parent, vector<vector<int>> &graph, int &count) {
    if (node != 0 && parent == 0) count++;

    for (int neighbor : graph[node]) {
        if (neighbor != parent) {
            dfs(neighbor, node, graph, count);
        }
    }
}

int minReorder(int n, vector<vector<int>> &connections) {
    vector<vector<int>> graph(n);
    for (auto &c : connections) {
        graph[c[0]].push_back(c[1]);
        graph[c[1]].push_back(c[0]);
    }

    int count = 0;
    dfs(0, -1, graph, count);
    return count;
}
```
The algorithm used in the code snippet uses a Depth-First Search (DFS) approach for traversing the given graph of cities represented by nodes and roads represented by connections. The dfs() functions are called on every node and their respective parents, and the result stores the minimum number of edges that should be changed.

Initially, the graph is created with each city having a list of its neighboring cities (bi-directional). The DFS algorithm starts traversing the graph from city 0 and recursively visits its neighboring nodes, and the edges that need to be adjusted are kept track of with the 'count' variable.

Whenever DFS encounters a city with a direct road towards city 0, 1 is added to the count. The minimum number of required edge changes will be the value of count. The final answer returned is the count of edges needed to be changed for all cities to reach city 0.

## A solution in Python

```python
from collections import defaultdict

def dfs(node, parent, graph, count):
    if node != 0 and parent == 0:
        count[0] += 1

    for neighbor in graph[node]:
        if neighbor != parent:
            dfs(neighbor, node, graph, count)

def minReorder(n, connections):
    graph = defaultdict(list)
    for a, b in connections:
        graph[a].append(b)
        graph[b].append(a)

    count = [0]
    dfs(0, -1, graph, count)
    return count[0]
```
The algorithm used in the code snippet uses a Depth-First Search (DFS) approach for traversing the given graph of cities represented by nodes and roads represented by connections. The dfs() functions are called on every node and their respective parents, and the result stores the minimum number of edges that should be changed.

Initially, the graph is created with each city having a list of its neighboring cities (bi-directional). The DFS algorithm starts traversing the graph from city 0 and recursively visits its neighboring nodes, and the edges that need to be adjusted are kept track of with the 'count' variable.

Whenever DFS encounters a city with a direct road towards city 0, 1 is added to the count. The minimum number of required edge changes will be the value of count. The final answer returned is the count of edges needed to be changed for all cities to reach city 0.

## A solution in Javascript

```javascript
function dfs(node, parent, graph, count) {
    if (node !== 0 && parent === 0) count[0]++;

    for (let neighbor of graph[node]) {
        if (neighbor !== parent) {
            dfs(neighbor, node, graph, count);
        }
    }
}

function minReorder(n, connections) {
    const graph = Array.from({length: n}, () => []);
    for (const [a, b] of connections) {
        graph[a].push(b);
        graph[b].push(a);
    }

    const count = [0];
    dfs(0, -1, graph, count);
    return count[0];
}
```
The algorithm used in the code snippet uses a Depth-First Search (DFS) approach for traversing the given graph of cities represented by nodes and roads represented by connections. The dfs() functions are called on every node and their respective parents, and the result stores the minimum number of edges that should be changed.

Initially, the graph is created with each city having a list of its neighboring cities (bi-directional). The DFS algorithm starts traversing the graph from city 0 and recursively visits its neighboring nodes, and the edges that need to be adjusted are kept track of with the 'count' variable.

Whenever DFS encounters a city with a direct road towards city 0, 1 is added to the count. The minimum number of required edge changes will be the value of count. The final answer returned is the count of edges needed to be changed for all cities to reach city 0.


# Number of Ways Where Square of Number Is Equal to Product of Two Numbers

- slug: number-of-ways-where-square-of-number-is-equal-to-product-of-two-numbers
- difficulty: Medium

Given two arrays of integers `nums1` and `nums2`, return the number of triplets formed (type 1 and type 2) under the following rules:

*   Type 1: Triplet (i, j, k) if `nums1[i]2 == nums2[j] * nums2[k]` where `0 <= i < nums1.length` and `0 <= j < k < nums2.length`.
*   Type 2: Triplet (i, j, k) if `nums2[i]2 == nums1[j] * nums1[k]` where `0 <= i < nums2.length` and `0 <= j < k < nums1.length`.

**Example 1:**

**Input:** nums1 = \[7,4\], nums2 = \[5,2,8,9\]
**Output:** 1
**Explanation:** Type 1: (1, 1, 2), nums1\[1\]2 = nums2\[1\] \* nums2\[2\]. (42 = 2 \* 8).

**Example 2:**

**Input:** nums1 = \[1,1\], nums2 = \[1,1,1\]
**Output:** 9
**Explanation:** All Triplets are valid, because 12 = 1 \* 1.
Type 1: (0,0,1), (0,0,2), (0,1,2), (1,0,1), (1,0,2), (1,1,2).  nums1\[i\]2 = nums2\[j\] \* nums2\[k\].
Type 2: (0,0,1), (1,0,1), (2,0,1). nums2\[i\]2 = nums1\[j\] \* nums1\[k\].

**Example 3:**

**Input:** nums1 = \[7,7,8,3\], nums2 = \[1,2,9,7\]
**Output:** 2
**Explanation:** There are 2 valid triplets.
Type 1: (3,0,2).  nums1\[3\]2 = nums2\[0\] \* nums2\[2\].
Type 2: (3,0,1).  nums2\[3\]2 = nums1\[0\] \* nums1\[1\].

**Constraints:**

*   `1 <= nums1.length, nums2.length <= 1000`
*   `1 <= nums1[i], nums2[i] <= 105`

## A solution in Java

```java
class Solution {
    double[][][] dp = new double[50][50][50];
    public double getProbability(int[] balls) {
        int sum = 0, k = balls.length;
        for(int b : balls) sum += b;
        int[] preSum = new int[k+1];
        for(int i = 0; i < k; i++) preSum[i+1] = preSum[i] + balls[i];

        for(int i = 0; i < 50; i++)
            for(int j = 0; j < 50; j++)
                for(int x = 0; x < 50; x++)
                    dp[i][j][x] = 0;

        dp[0][0][0] = 1;
        for(int i = 0; i < k; ++i) {
            for(int j = i; j >= 0; --j) {
                for(int x = preSum[i+1]; x >= 0; --x) {
                    for (int y = preSum[i + 1] - x; y >= 0; --y) {
                        if (x + y <= balls[i]) {
                            for (int d = Math.max(0, balls[i] - 2 * y); d <= x; ++d) {
                                double tmp = 1;
                                for (int z = 1; z <= d; ++z) tmp *= (x + y + 1 - z) / z;
                                for (int z = 1; z <= y; ++z) tmp *= (x + y + d + 1 - z) / z;
                                for (int z = 1; z <= balls[i] - y - y - d; ++z) tmp *= (x + y + d + 1 - z) / z;
                                dp[i + 1][j + 1][x + d] += dp[i][j][x] * tmp;
                                dp[i + 1][j][x + d] += dp[i][j][x] * tmp;
                            }
                        }
                    }
                }
            }
        }

        return (dp[k][k >> 1][sum >> 1] - (1e-5 > dp[k][k >> 1][sum >> 1])) / (sum % 2 != 0 ? 1 : (1 << (sum >> 1)));
    }
}
```
In this problem, we use dynamic programming to get the solutions. Our approach is as follows:

1. Define pre_sum[i] as the sum of values in the balls array up to the (i-1)th index (1-indexed). This will be used later to access precomputed sums.
2. Define a 3-dimensional dp table dp[i][j][x] that stores the probability such that there are i distinct balls in the first box, j in the second box, and x balls having the same color in both boxes.
3. Initialize the base case for no distinct balls, dp[0][0][0]=1.
4. Iterate through all balls and apply the transitions to fill up the dp table.
5. For each ball, iterate through all possible values of j, x, y such that j is the number of distinct balls of a color that has been considered so far, x is the number of balls with the same color in both boxes, and y is the number of balls having ball[i] color in the second box.
6. If the sum of x and y is smaller than or equal to the number of balls of color i, then iterate through all possible values of d to distribute balls of color i to both boxes. Calculate the combination of distributing the balls and update the probabilities in the dp table accordingly.
7. Finally, use the computed probabilities and sums to get the resultant probability.

## A solution in C++

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

double dp[50][50][50];
class Solution {
public:
    double getProbability(vector<int>& balls) {
        int sum = 0, k = balls.size();
        for(int b : balls) sum+= b;
        vector<int> pre_sum;
        pre_sum.push_back(0);
        for(int b : balls) pre_sum.push_back(pre_sum.back()+b);

        memset(dp, 0, sizeof(dp));
        dp[0][0][0] = 1;
        for(int i = 0; i < k; ++i)
            for(int j = i; j >= 0; --j)
                for(int x = pre_sum[i+1]; x >= 0; --x)
                    for(int y = pre_sum[i+1] - x; y >= 0; --y)
                        if (x + y <= balls[i])
                            for(int d = max(0, balls[i] - 2 * y); d <= x; ++d){
                                double tmp = 1;
                                for(int z = 1; z <= d; ++z) tmp *= x + y + 1 - z, tmp /= z;
                                for(int z = 1; z <= y; ++z) tmp *= x + y + d + 1 - z, tmp /= z;
                                for(int z = 1; z <= balls[i] - y - y - d; ++z) tmp *= x + y + d + 1 - z, tmp /= z;
                                dp[i+1][j+1][x+d] += dp[i][j][x] * tmp;
                                dp[i+1][j][x+d] += dp[i][j][x] * tmp;
                            }

        return (dp[k][k>>1][sum>>1] - (1e-5 > dp[k][k>>1][sum>>1])) / (sum % 2 ? 1 : (1ll<<(sum>>1)));
    }
};
```
In this problem, we use dynamic programming to get the solutions. Our approach is as follows:

1. Define pre_sum[i] as the sum of values in the balls array up to the (i-1)th index (1-indexed). This will be used later to access precomputed sums.
2. Define a 3-dimensional dp table dp[i][j][x] that stores the probability such that there are i distinct balls in the first box, j in the second box, and x balls having the same color in both boxes.
3. Initialize the base case for no distinct balls, dp[0][0][0]=1.
4. Iterate through all balls and apply the transitions to fill up the dp table.
5. For each ball, iterate through all possible values of j, x, y such that j is the number of distinct balls of a color that has been considered so far, x is the number of balls with the same color in both boxes, and y is the number of balls having ball[i] color in the second box.
6. If the sum of x and y is smaller than or equal to the number of balls of color i, then iterate through all possible values of d to distribute balls of color i to both boxes. Calculate the combination of distributing the balls and update the probabilities in the dp table accordingly.
7. Finally, use the computed probabilities and sums to get the resultant probability.

## A solution in Python

```python
class Solution:
    def getProbability(self, balls: List[int]) -> float:
        pre_sum = [0]
        dp = [[[0]*62 for _ in range(10)] for _ in range(35)]
        k = len(balls)

        for b in balls:
            pre_sum.append(pre_sum[-1] + b)

        dp[0][0][0] = 1
        for i in range(k):
            for j in reversed(range(i + 1)):
                for x in reversed(range(pre_sum[i+1] + 1)):
                    for y in reversed(range(0, pre_sum[i+1] - x + 1)):
                        if x + y <= balls[i]:
                            for d in range(max(0, balls[i] - 2 * y), x + 1):
                                tmp = 1
                                for z in range(1, d + 1):
                                    tmp *= (x + y + 1 - z) / z
                                for z in range(1, y + 1):
                                    tmp *= (x + y + d + 1 - z) / z
                                for z in range(1, balls[i] - y - y - d + 1):
                                    tmp *= (x + y + d + 1 - z) / z
                                dp[i+1][j+1][x + d] += dp[i][j][x] * tmp
                                dp[i+1][j][x + d] += dp[i][j][x] * tmp

        sum_ = sum(balls)
        return (dp[k][k >> 1][sum_ >> 1] - (1e-5 > dp[k][k >> 1][sum_ >> 1])) / (1 if sum_ % 2 else (1 << (sum_ >> 1)))
```
In this problem, we use dynamic programming to get the solutions. Our approach is as follows:

1. Define pre_sum[i] as the sum of values in the balls array up to the (i-1)th index (1-indexed). This will be used later to access precomputed sums.
2. Define a 3-dimensional dp table dp[i][j][x] that stores the probability such that there are i distinct balls in the first box, j in the second box, and x balls having the same color in both boxes.
3. Initialize the base case for no distinct balls, dp[0][0][0]=1.
4. Iterate through all balls and apply the transitions to fill up the dp table.
5. For each ball, iterate through all possible values of j, x, y such that j is the number of distinct balls of a color that has been considered so far, x is the number of balls with the same color in both boxes, and y is the number of balls having ball[i] color in the second box.
6. If the sum of x and y is smaller than or equal to the number of balls of color i, then iterate through all possible values of d to distribute balls of color i to both boxes. Calculate the combination of distributing the balls and update the probabilities in the dp table accordingly.
7. Finally, use the computed probabilities and sums to get the resultant probability.

## A solution in Javascript

```javascript
var getProbability = function(balls) {
    const k = balls.length;
    const pre_sum = [0];
    for(let b of balls) pre_sum.push(pre_sum[pre_sum.length - 1] + b);

    const dp = new Array(50).fill(0).map(() => new Array(50).fill(0).map(() => new Array(50).fill(0)));
    dp[0][0][0] = 1;
    for(let i = 0; i < k; ++i){
        for(let j = i; j >= 0; --j){
            for(let x = pre_sum[i+1]; x >= 0; --x){
                for(let y = pre_sum[i+1] - x; y >= 0; --y){
                    if (x + y <= balls[i]){
                        for(let d = Math.max(0, balls[i] - 2 * y); d <= x; ++d){
                            let tmp = 1;
                            for(let z = 1; z <= d; ++z) tmp *= x + y + 1 - z, tmp /= z;
                            for(let z = 1; z <= y; ++z) tmp *= x + y + d + 1 - z, tmp /= z;
                            for(let z = 1; z <= balls[i] - y - y - d; ++z) tmp *= x + y + d + 1 - z, tmp /= z;
                            dp[i+1][j+1][x+d] += dp[i][j][x] * tmp;
                            dp[i+1][j][x+d] += dp[i][j][x] * tmp;
                        }
                    }
                }
            }
        }
    }

    const sum_ = balls.reduce((acc, cur) => acc + cur);
    return (dp[k][k>>1][sum_>>1] - (1e-5 > dp[k][k>>1][sum_>>1])) / (sum_ % 2 ? 1 : (1<<(sum_>>1)));
};
```
In this problem, we use dynamic programming to get the solutions. Our approach is as follows:

1. Define pre_sum[i] as the sum of values in the balls array up to the (i-1)th index (1-indexed). This will be used later to access precomputed sums.
2. Define a 3-dimensional dp table dp[i][j][x] that stores the probability such that there are i distinct balls in the first box, j in the second box, and x balls having the same color in both boxes.
3. Initialize the base case for no distinct balls, dp[0][0][0]=1.
4. Iterate through all balls and apply the transitions to fill up the dp table.
5. For each ball, iterate through all possible values of j, x, y such that j is the number of distinct balls of a color that has been considered so far, x is the number of balls with the same color in both boxes, and y is the number of balls having ball[i] color in the second box.
6. If the sum of x and y is smaller than or equal to the number of balls of color i, then iterate through all possible values of d to distribute balls of color i to both boxes. Calculate the combination of distributing the balls and update the probabilities in the dp table accordingly.
7. Finally, use the computed probabilities and sums to get the resultant probability.