# Matrix Cells in Distance Order

- slug: matrix-cells-in-distance-order
- difficulty: Easy

You are given four integers `row`, `cols`, `rCenter`, and `cCenter`. There is a `rows x cols` matrix and you are on the cell with the coordinates `(rCenter, cCenter)`.

Return _the coordinates of all cells in the matrix, sorted by their **distance** from_ `(rCenter, cCenter)` _from the smallest distance to the largest distance_. You may return the answer in **any order** that satisfies this condition.

The **distance** between two cells `(r1, c1)` and `(r2, c2)` is `|r1 - r2| + |c1 - c2|`.

**Example 1:**

**Input:** rows = 1, cols = 2, rCenter = 0, cCenter = 0
**Output:** \[\[0,0\],\[0,1\]\]
**Explanation:** The distances from (0, 0) to other cells are: \[0,1\]

**Example 2:**

**Input:** rows = 2, cols = 2, rCenter = 0, cCenter = 1
**Output:** \[\[0,1\],\[0,0\],\[1,1\],\[1,0\]\]
**Explanation:** The distances from (0, 1) to other cells are: \[0,1,1,2\]
The answer \[\[0,1\],\[1,1\],\[0,0\],\[1,0\]\] would also be accepted as correct.

**Example 3:**

**Input:** rows = 2, cols = 3, rCenter = 1, cCenter = 2
**Output:** \[\[1,2\],\[0,2\],\[1,1\],\[0,1\],\[1,0\],\[0,0\]\]
**Explanation:** The distances from (1, 2) to other cells are: \[0,1,1,2,2,3\]
There are other answers that would also be accepted as correct, such as \[\[1,2\],\[1,1\],\[0,2\],\[1,0\],\[0,1\],\[0,0\]\].

**Constraints:**

*   `1 <= rows, cols <= 100`
*   `0 <= rCenter < rows`
*   `0 <= cCenter < cols`

## A solution in Java

```java
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}

public class Solution {
    public String smallestFromLeaf(TreeNode root) {
        if (root == null) return "|";
        String s = Character.toString((char) (root.val + 'a'));
        if (root.left == null && root.right == null) return s;
        String left = smallestFromLeaf(root.left);
        String right = smallestFromLeaf(root.right);
        return (left.compareTo(right) <= 0 ? left : right) + s;
    }
}
```
We perform a post-order traversal of the tree. If the root is null, we return the largest possible lexicographically ordered string "|". If the root is a leaf (both left and right children are null), we return the character equivalent of the node value converted to the corresponding lowercase alphabet character.

We get the lexicographically smallest strings from both the left and right subtrees (if they exist) and add the current root value's character equivalent to the result. We use the min function to determine the lexicographically smaller string between the two.

Note that we add the current root value's character equivalent to the end of the result string, so that the result string starts with a leaf node and goes to the root node as the function returns. This keeps the lexicographically smaller strings at the beginning and correctly forms the lexicographically smallest string from leaf to root.

## A solution in C++

```cpp
#include <climits>
#include <string>
#include <algorithm>
using namespace std;

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

string smallestFromLeaf(TreeNode* root) {
    if (!root) return "|";
    string s(1, root->val + 'a');
    if (!root->left && !root->right) return s;
    string left = smallestFromLeaf(root->left);
    string right = smallestFromLeaf(root->right);
    return min(left, right) + s;
}
```
We perform a post-order traversal of the tree. If the root is null, we return the largest possible lexicographically ordered string "|". If the root is a leaf (both left and right children are null), we return the character equivalent of the node value converted to the corresponding lowercase alphabet character.

We get the lexicographically smallest strings from both the left and right subtrees (if they exist) and add the current root value's character equivalent to the result. We use the min function to determine the lexicographically smaller string between the two.

Note that we add the current root value's character equivalent to the end of the result string, so that the result string starts with a leaf node and goes to the root node as the function returns. This keeps the lexicographically smaller strings at the beginning and correctly forms the lexicographically smallest string from leaf to root.

## A solution in Python

```python
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def smallestFromLeaf(self, root: TreeNode) -> str:
        if not root:
            return "|"
        s = chr(root.val + 97)
        if not root.left and not root.right:
            return s
        left = self.smallestFromLeaf(root.left)
        right = self.smallestFromLeaf(root.right)
        return min(left, right) + s
```
We perform a post-order traversal of the tree. If the root is null, we return the largest possible lexicographically ordered string "|". If the root is a leaf (both left and right children are null), we return the character equivalent of the node value converted to the corresponding lowercase alphabet character.

We get the lexicographically smallest strings from both the left and right subtrees (if they exist) and add the current root value's character equivalent to the result. We use the min function to determine the lexicographically smaller string between the two.

Note that we add the current root value's character equivalent to the end of the result string, so that the result string starts with a leaf node and goes to the root node as the function returns. This keeps the lexicographically smaller strings at the beginning and correctly forms the lexicographically smallest string from leaf to root.

## A solution in Javascript

```javascript
class TreeNode {
    constructor(val, left = null, right = null) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

function smallestFromLeaf(root) {
    if (!root) return "|";
    const s = String.fromCharCode(root.val + 97);
    if (!root.left && !root.right) return s;
    const left = smallestFromLeaf(root.left);
    const right = smallestFromLeaf(root.right);
    return (left < right ? left : right) + s;
}
```
We perform a post-order traversal of the tree. If the root is null, we return the largest possible lexicographically ordered string "|". If the root is a leaf (both left and right children are null), we return the character equivalent of the node value converted to the corresponding lowercase alphabet character.

We get the lexicographically smallest strings from both the left and right subtrees (if they exist) and add the current root value's character equivalent to the result. We use the min function to determine the lexicographically smaller string between the two.

Note that we add the current root value's character equivalent to the end of the result string, so that the result string starts with a leaf node and goes to the root node as the function returns. This keeps the lexicographically smaller strings at the beginning and correctly forms the lexicographically smallest string from leaf to root.


# Maximum Sum of Two Non-Overlapping Subarrays

- slug: maximum-sum-of-two-non-overlapping-subarrays
- difficulty: Medium

Given an integer array `nums` and two integers `firstLen` and `secondLen`, return _the maximum sum of elements in two non-overlapping **subarrays** with lengths_ `firstLen` _and_ `secondLen`.

The array with length `firstLen` could occur before or after the array with length `secondLen`, but they have to be non-overlapping.

A **subarray** is a **contiguous** part of an array.

**Example 1:**

**Input:** nums = \[0,6,5,2,2,5,1,9,4\], firstLen = 1, secondLen = 2
**Output:** 20
**Explanation:** One choice of subarrays is \[9\] with length 1, and \[6,5\] with length 2.

**Example 2:**

**Input:** nums = \[3,8,1,3,2,1,8,9,0\], firstLen = 3, secondLen = 2
**Output:** 29
**Explanation:** One choice of subarrays is \[3,8,1\] with length 3, and \[8,9\] with length 2.

**Example 3:**

**Input:** nums = \[2,1,5,6,0,9,5,0,3,8\], firstLen = 4, secondLen = 3
**Output:** 31
**Explanation:** One choice of subarrays is \[5,6,0,9\] with length 4, and \[0,3,8\] with length 3.

**Constraints:**

*   `1 <= firstLen, secondLen <= 1000`
*   `2 <= firstLen + secondLen <= 1000`
*   `firstLen + secondLen <= nums.length <= 1000`
*   `0 <= nums[i] <= 1000`

## A solution in Java

```java
import java.util.*;

public List<Integer> addToArrayForm(int[] num, int k) {
    List<Integer> result = new ArrayList<>();
    int carry = k, i = num.length - 1;
    while (i >= 0 || carry > 0) {
        if (i >= 0) {
            carry += num[i--];
        }
        result.add(carry % 10);
        carry /= 10;
    }
    Collections.reverse(result);
    return result;
}
```
The algorithm processes the input digit by digit, starting from the least significant digit (the digits farthest to the right). The logic is as follows:

1. Add k to the least significant digit.
2. Iterate through the digits. For each digit:
   a. If the digit is greater than or equal to 10, carry over the left digit by dividing the current digit by 10 and adding the result to the left neighboring digit.
   b. Set the current digit to the remainder of the digit divided by 10.
3. If there is any remaining carry, handle it by adding new digits to the beginning of the array.
4. Return the modified array.

The algorithm above works for all the given programming languages since it only relies on basic arithmetic operations and list operations that are available in all languages. The main difference between implementations is the specific syntax for inserting and accessing elements in an array or list.

## A solution in C++

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

vector<int> addToArrayForm(vector<int>& num, int k) {
    // add k to the least significant digit of the integer represented by num
    num.back() += k;
    // sum digits from least to most significant digit
    for (int i = num.size() - 1; i > 0 && num[i]; --i) {
        num[i - 1] += num[i] / 10;
        num[i] %= 10;
    }
    // handle possible remaining carry
    while (num[0] >= 10) {
        num.insert(num.begin(), num[0] / 10);
        num[1] %= 10;
    }
    return num;
}
```
The algorithm processes the input digit by digit, starting from the least significant digit (the digits farthest to the right). The logic is as follows:

1. Add k to the least significant digit.
2. Iterate through the digits. For each digit:
   a. If the digit is greater than or equal to 10, carry over the left digit by dividing the current digit by 10 and adding the result to the left neighboring digit.
   b. Set the current digit to the remainder of the digit divided by 10.
3. If there is any remaining carry, handle it by adding new digits to the beginning of the array.
4. Return the modified array.

The algorithm above works for all the given programming languages since it only relies on basic arithmetic operations and list operations that are available in all languages. The main difference between implementations is the specific syntax for inserting and accessing elements in an array or list.

## A solution in Python

```python
def add_to_array_form(num, k):
    for i in range(len(num) - 1, -1, -1):
        k, num[i] = divmod(num[i] + k, 10)
        if k == 0:
            break
    while k:
        k, digit = divmod(k, 10)
        num.insert(0, digit)
    return num
```
The algorithm processes the input digit by digit, starting from the least significant digit (the digits farthest to the right). The logic is as follows:

1. Add k to the least significant digit.
2. Iterate through the digits. For each digit:
   a. If the digit is greater than or equal to 10, carry over the left digit by dividing the current digit by 10 and adding the result to the left neighboring digit.
   b. Set the current digit to the remainder of the digit divided by 10.
3. If there is any remaining carry, handle it by adding new digits to the beginning of the array.
4. Return the modified array.

The algorithm above works for all the given programming languages since it only relies on basic arithmetic operations and list operations that are available in all languages. The main difference between implementations is the specific syntax for inserting and accessing elements in an array or list.

## A solution in Javascript

```javascript
function addToArrayForm(num, k) {
    for (let i = num.length - 1; i >= 0; --i) {
        let sum = num[i] + k % 10;
        k = Math.floor(k / 10);
        if (sum >= 10) {
            sum -= 10;
            k++;
        }
        num[i] = sum;
        if (k === 0)
            break;
    }
    while (k !== 0) {
        num.unshift(k % 10);
        k = Math.floor(k / 10);
    }
    return num;
}
```
The algorithm processes the input digit by digit, starting from the least significant digit (the digits farthest to the right). The logic is as follows:

1. Add k to the least significant digit.
2. Iterate through the digits. For each digit:
   a. If the digit is greater than or equal to 10, carry over the left digit by dividing the current digit by 10 and adding the result to the left neighboring digit.
   b. Set the current digit to the remainder of the digit divided by 10.
3. If there is any remaining carry, handle it by adding new digits to the beginning of the array.
4. Return the modified array.

The algorithm above works for all the given programming languages since it only relies on basic arithmetic operations and list operations that are available in all languages. The main difference between implementations is the specific syntax for inserting and accessing elements in an array or list.


# Stream of Characters

- slug: stream-of-characters
- difficulty: Hard

Design an algorithm that accepts a stream of characters and checks if a suffix of these characters is a string of a given array of strings `words`.

For example, if `words = [ "abc ", "xyz "]` and the stream added the four characters (one by one) `'a'`, `'x'`, `'y'`, and `'z'`, your algorithm should detect that the suffix `"xyz "` of the characters `"axyz "` matches `"xyz "` from `words`.

Implement the `StreamChecker` class:

*   `StreamChecker(String[] words)` Initializes the object with the strings array `words`.
*   `boolean query(char letter)` Accepts a new character from the stream and returns `true` if any non-empty suffix from the stream forms a word that is in `words`.

**Example 1:**

**Input**
\[ "StreamChecker ",  "query ",  "query ",  "query ",  "query ",  "query ",  "query ",  "query ",  "query ",  "query ",  "query ",  "query ",  "query "\]
\[\[\[ "cd ",  "f ",  "kl "\]\], \[ "a "\], \[ "b "\], \[ "c "\], \[ "d "\], \[ "e "\], \[ "f "\], \[ "g "\], \[ "h "\], \[ "i "\], \[ "j "\], \[ "k "\], \[ "l "\]\]
**Output**
\[null, false, false, false, true, false, true, false, false, false, false, false, true\]

**Explanation**
StreamChecker streamChecker = new StreamChecker(\[ "cd ",  "f ",  "kl "\]);
streamChecker.query( "a "); // return False
streamChecker.query( "b "); // return False
streamChecker.query( "c "); // return False
streamChecker.query( "d "); // return True, because 'cd' is in the wordlist
streamChecker.query( "e "); // return False
streamChecker.query( "f "); // return True, because 'f' is in the wordlist
streamChecker.query( "g "); // return False
streamChecker.query( "h "); // return False
streamChecker.query( "i "); // return False
streamChecker.query( "j "); // return False
streamChecker.query( "k "); // return False
streamChecker.query( "l "); // return True, because 'kl' is in the wordlist

**Constraints:**

*   `1 <= words.length <= 2000`
*   `1 <= words[i].length <= 200`
*   `words[i]` consists of lowercase English letters.
*   `letter` is a lowercase English letter.
*   At most `4 * 104` calls will be made to query.

## A solution in Java

```java
public boolean equationsPossible(String[] equations) {
    int[] parent = new int[26];
    for (int i = 0; i < 26; ++i) {
        parent[i] = i;
    }

    for (String e : equations) {
        if (e.charAt(1) == '=') {
            int x = e.charAt(0) - 'a';
            int y = e.charAt(3) - 'a';
            parent[find(x, parent)] = find(y, parent);
        }
    }

    for (String e : equations) {
        if (e.charAt(1) == '!' && find(e.charAt(0) - 'a', parent) == find(e.charAt(3) - 'a', parent)) {
            return false;
        }
    }

    return true;
}

private int find(int x, int[] parent) {
    if (parent[x] != x) {
        parent[x] = find(parent[x], parent);
    }

    return parent[x];
}
```
The algorithm is the same for all languages:

1. Create an array `parent` to store the parent indices, initially equal to the indices themselves (i.e., the parent of the element at index i is itself).

2. Iterate through the `equations`, and for each equation where the relationship is equality (value at index 1 is '='), union the elements - update the parent of the first element to be the parent of the second element. Use the find function to find the root of each element.

3. Iterate through the `equations` again, and for each equation where the relationship is inequality (value at index 1 is '!'), check if both variable nodes have the same parent. If they have the same parent, it means their values must be equal, which makes the inequality equation false. Therefore, return false.

4. If all the equalities and inequalities hold, return true.

Note that the only difference in code implementation is due to the syntax differences in each language. The algorithm remains the same.

## A solution in C++

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

bool equationsPossible(std::vector<std::string>& equations) {
    std::vector<int> parent(26, 0);

    for (int i = 0; i < 26; ++i) {
        parent[i] = i;
    }

    for (const auto& eq : equations) {
        if (eq[1] == '=') {
            int x = eq[0] - 'a';
            int y = eq[3] - 'a';
            parent[find(x, parent)] = find(y, parent);
        }
    }

    for (const auto& eq : equations) {
        if (eq[1] == '!' && find(eq[0] - 'a', parent) == find(eq[3] - 'a', parent)) {
            return false;
        }
    }

    return true;
}

int find(int x, std::vector<int>& parent) {
    if (parent[x] != x) {
        parent[x] = find(parent[x], parent);
    }

    return parent[x];
}
```
The algorithm is the same for all languages:

1. Create an array `parent` to store the parent indices, initially equal to the indices themselves (i.e., the parent of the element at index i is itself).

2. Iterate through the `equations`, and for each equation where the relationship is equality (value at index 1 is '='), union the elements - update the parent of the first element to be the parent of the second element. Use the find function to find the root of each element.

3. Iterate through the `equations` again, and for each equation where the relationship is inequality (value at index 1 is '!'), check if both variable nodes have the same parent. If they have the same parent, it means their values must be equal, which makes the inequality equation false. Therefore, return false.

4. If all the equalities and inequalities hold, return true.

Note that the only difference in code implementation is due to the syntax differences in each language. The algorithm remains the same.

## A solution in Python

```python
def equationsPossible(equations):
    parent = [i for i in range(26)]

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

    for e in equations:
        if e[1] == '=':
            x = ord(e[0]) - ord('a')
            y = ord(e[3]) - ord('a')
            parent[find(x)] = find(y)

    for e in equations:
        if e[1] == '!' and find(ord(e[0]) - ord('a')) == find(ord(e[3]) - ord('a')):
            return False

    return True
```
The algorithm is the same for all languages:

1. Create an array `parent` to store the parent indices, initially equal to the indices themselves (i.e., the parent of the element at index i is itself).

2. Iterate through the `equations`, and for each equation where the relationship is equality (value at index 1 is '='), union the elements - update the parent of the first element to be the parent of the second element. Use the find function to find the root of each element.

3. Iterate through the `equations` again, and for each equation where the relationship is inequality (value at index 1 is '!'), check if both variable nodes have the same parent. If they have the same parent, it means their values must be equal, which makes the inequality equation false. Therefore, return false.

4. If all the equalities and inequalities hold, return true.

Note that the only difference in code implementation is due to the syntax differences in each language. The algorithm remains the same.

## A solution in Javascript

```javascript
function equationsPossible(equations) {
    const parent = [...Array(26).keys()];

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

    for (let e of equations) {
        if (e[1] === '=') {
            const x = e.charCodeAt(0) - 'a'.charCodeAt(0);
            const y = e.charCodeAt(3) - 'a'.charCodeAt(0);
            parent[find(x)] = find(y);
        }
    }

    for (let e of equations) {
        if (e[1] === '!' && find(e.charCodeAt(0) - 'a'.charCodeAt(0)) === find(e.charCodeAt(3) - 'a'.charCodeAt(0))) {
            return false;
        }
    }

    return true;
}
```
The algorithm is the same for all languages:

1. Create an array `parent` to store the parent indices, initially equal to the indices themselves (i.e., the parent of the element at index i is itself).

2. Iterate through the `equations`, and for each equation where the relationship is equality (value at index 1 is '='), union the elements - update the parent of the first element to be the parent of the second element. Use the find function to find the root of each element.

3. Iterate through the `equations` again, and for each equation where the relationship is inequality (value at index 1 is '!'), check if both variable nodes have the same parent. If they have the same parent, it means their values must be equal, which makes the inequality equation false. Therefore, return false.

4. If all the equalities and inequalities hold, return true.

Note that the only difference in code implementation is due to the syntax differences in each language. The algorithm remains the same.


# Moving Stones Until Consecutive

- slug: moving-stones-until-consecutive
- difficulty: Medium

There are three stones in different positions on the X-axis. You are given three integers `a`, `b`, and `c`, the positions of the stones.

In one move, you pick up a stone at an endpoint (i.e., either the lowest or highest position stone), and move it to an unoccupied position between those endpoints. Formally, let's say the stones are currently at positions `x`, `y`, and `z` with `x < y < z`. You pick up the stone at either position `x` or position `z`, and move that stone to an integer position `k`, with `x < k < z` and `k != y`.

The game ends when you cannot make any more moves (i.e., the stones are in three consecutive positions).

Return _an integer array_ `answer` _of length_ `2` _where_:

*   `answer[0]` _is the minimum number of moves you can play, and_
*   `answer[1]` _is the maximum number of moves you can play_.

**Example 1:**

**Input:** a = 1, b = 2, c = 5
**Output:** \[1,2\]
**Explanation:** Move the stone from 5 to 3, or move the stone from 5 to 4 to 3.

**Example 2:**

**Input:** a = 4, b = 3, c = 2
**Output:** \[0,0\]
**Explanation:** We cannot make any moves.

**Example 3:**

**Input:** a = 3, b = 5, c = 1
**Output:** \[1,2\]
**Explanation:** Move the stone from 1 to 4; or move the stone from 1 to 2 to 4.

**Constraints:**

*   `1 <= a, b, c <= 100`
*   `a`, `b`, and `c` have different values.

## A solution in Java

```java
public int brokenCalc(int startValue, int target) {
    int operations = 0;
    while (target > startValue) {
        target = (target % 2 == 0) ? target / 2 : target + 1;
        operations++;
    }
    return operations + startValue - target;
}
```
The algorithm starts by initializing the operation counter to 0. Then, while the target value is greater than the start value, the algorithm checks if the target value is even. If it's even, we divide the target value by 2, otherwise, we increment the target value before updating the operation counter. The algorithm continues iterating until the target value is less than or equal to the start value. The final result is obtained by adding the current operation counter to the difference between the start value and the target value.

## A solution in C++

```cpp
int brokenCalc(int startValue, int target) {
    int operations = 0;
    while (target > startValue) {
        target = (target % 2 == 0) ? target / 2 : target + 1;
        operations++;
    }
    return operations + startValue - target;
}
```
The algorithm starts by initializing the operation counter to 0. Then, while the target value is greater than the start value, the algorithm checks if the target value is even. If it's even, we divide the target value by 2, otherwise, we increment the target value before updating the operation counter. The algorithm continues iterating until the target value is less than or equal to the start value. The final result is obtained by adding the current operation counter to the difference between the start value and the target value.

## A solution in Python

```python
def broken_calc(startValue: int, target: int) -> int:
    operations = 0
    while target > startValue:
        target = target // 2 if target % 2 == 0 else target + 1
        operations += 1
    return operations + startValue - target
```
The algorithm starts by initializing the operation counter to 0. Then, while the target value is greater than the start value, the algorithm checks if the target value is even. If it's even, we divide the target value by 2, otherwise, we increment the target value before updating the operation counter. The algorithm continues iterating until the target value is less than or equal to the start value. The final result is obtained by adding the current operation counter to the difference between the start value and the target value.

## A solution in Javascript

```javascript
function brokenCalc(startValue, target) {
    let operations = 0;
    while (target > startValue) {
        target = (target % 2 === 0) ? target / 2 : target + 1;
        operations++;
    }
    return operations + startValue - target;
}
```
The algorithm starts by initializing the operation counter to 0. Then, while the target value is greater than the start value, the algorithm checks if the target value is even. If it's even, we divide the target value by 2, otherwise, we increment the target value before updating the operation counter. The algorithm continues iterating until the target value is less than or equal to the start value. The final result is obtained by adding the current operation counter to the difference between the start value and the target value.


# Coloring A Border

- slug: coloring-a-border
- difficulty: Medium

You are given an `m x n` integer matrix `grid`, and three integers `row`, `col`, and `color`. Each value in the grid represents the color of the grid square at that location.

Two squares belong to the same **connected component** if they have the same color and are next to each other in any of the 4 directions.

The **border of a connected component** is all the squares in the connected component that are either **4-directionally** adjacent to a square not in the component, or on the boundary of the grid (the first or last row or column).

You should color the **border** of the **connected component** that contains the square `grid[row][col]` with `color`.

Return _the final grid_.

**Example 1:**

**Input:** grid = \[\[1,1\],\[1,2\]\], row = 0, col = 0, color = 3
**Output:** \[\[3,3\],\[3,2\]\]

**Example 2:**

**Input:** grid = \[\[1,2,2\],\[2,3,2\]\], row = 0, col = 1, color = 3
**Output:** \[\[1,3,3\],\[2,3,3\]\]

**Example 3:**

**Input:** grid = \[\[1,1,1\],\[1,1,1\],\[1,1,1\]\], row = 1, col = 1, color = 2
**Output:** \[\[2,2,2\],\[2,1,2\],\[2,2,2\]\]

**Constraints:**

*   `m == grid.length`
*   `n == grid[i].length`
*   `1 <= m, n <= 50`
*   `1 <= grid[i][j], color <= 1000`
*   `0 <= row < m`
*   `0 <= col < n`

## A solution in Java

```java
import java.util.HashMap;

public int good_subarrays(int[] nums, int k) {
    int count = 0;
    for (int i = 0; i < nums.length; i++) {
        HashMap<Integer, Integer> frequency = new HashMap<>();
        for (int j = i; j < nums.length; j++) {
            frequency.put(nums[j], frequency.getOrDefault(nums[j], 0) + 1);
            if (frequency.size() > k) break;
            if (frequency.size() == k) count++;
        }
    }
    return count;
}

```
The algorithm iterates through each element of the array and starts another loop from that element to the end. In the inner loop, we maintain a frequency map/dict/object which stores the frequency of the integer occurrence in the subarray starting from `i` to the current element of the inner loop. We update the frequency of the integer at each step of the inner loop.

If the size of the frequency map/dict/object is greater than `k`, we break the inner loop as it's not a good subarray. If the size of the frequency map/dict/object is exactly equal to `k`, we increment the count of good subarrays.

Lastly, we return the count of good subarrays after iterating through the entire array.

## A solution in C++

```cpp
#include <unordered_map>

int good_subarrays(vector<int>& nums, int k) {
    int count = 0;
    for (int i = 0; i < nums.size(); i++) {
        unordered_map<int, int> frequency;
        for (int j = i; j < nums.size(); j++) {
            frequency[nums[j]]++;
            if (frequency.size() > k) break;
            if (frequency.size() == k) count++;
        }
    }
    return count;
}
```
The algorithm iterates through each element of the array and starts another loop from that element to the end. In the inner loop, we maintain a frequency map/dict/object which stores the frequency of the integer occurrence in the subarray starting from `i` to the current element of the inner loop. We update the frequency of the integer at each step of the inner loop.

If the size of the frequency map/dict/object is greater than `k`, we break the inner loop as it's not a good subarray. If the size of the frequency map/dict/object is exactly equal to `k`, we increment the count of good subarrays.

Lastly, we return the count of good subarrays after iterating through the entire array.

## A solution in Python

```python
def good_subarrays(nums, k):
    count = 0
    for i in range(len(nums)):
        frequency = {}
        for j in range(i, len(nums)):
            frequency[nums[j]] = frequency.get(nums[j], 0) + 1
            if len(frequency) > k:
                break
            if len(frequency) == k:
                count += 1
    return count
```
The algorithm iterates through each element of the array and starts another loop from that element to the end. In the inner loop, we maintain a frequency map/dict/object which stores the frequency of the integer occurrence in the subarray starting from `i` to the current element of the inner loop. We update the frequency of the integer at each step of the inner loop.

If the size of the frequency map/dict/object is greater than `k`, we break the inner loop as it's not a good subarray. If the size of the frequency map/dict/object is exactly equal to `k`, we increment the count of good subarrays.

Lastly, we return the count of good subarrays after iterating through the entire array.

## A solution in Javascript

```javascript
function good_subarrays(nums, k) {
    let count = 0;
    for (let i = 0; i < nums.length; i++) {
        let frequency = {};
        for (let j = i; j < nums.length; j++) {
            frequency[nums[j]] = (frequency[nums[j]] || 0) + 1;
            if (Object.keys(frequency).length > k) break;
            if (Object.keys(frequency).length === k) count++;
        }
    }
    return count;
}
```
The algorithm iterates through each element of the array and starts another loop from that element to the end. In the inner loop, we maintain a frequency map/dict/object which stores the frequency of the integer occurrence in the subarray starting from `i` to the current element of the inner loop. We update the frequency of the integer at each step of the inner loop.

If the size of the frequency map/dict/object is greater than `k`, we break the inner loop as it's not a good subarray. If the size of the frequency map/dict/object is exactly equal to `k`, we increment the count of good subarrays.

Lastly, we return the count of good subarrays after iterating through the entire array.


# Uncrossed Lines

- slug: uncrossed-lines
- difficulty: Medium

You are given two integer arrays `nums1` and `nums2`. We write the integers of `nums1` and `nums2` (in the order they are given) on two separate horizontal lines.

We may draw connecting lines: a straight line connecting two numbers `nums1[i]` and `nums2[j]` such that:

*   `nums1[i] == nums2[j]`, and
*   the line we draw does not intersect any other connecting (non-horizontal) line.

Note that a connecting line cannot intersect even at the endpoints (i.e., each number can only belong to one connecting line).

Return _the maximum number of connecting lines we can draw in this way_.

**Example 1:**

**Input:** nums1 = \[1,4,2\], nums2 = \[1,2,4\]
**Output:** 2
**Explanation:** We can draw 2 uncrossed lines as in the diagram.
We cannot draw 3 uncrossed lines, because the line from nums1\[1\] = 4 to nums2\[2\] = 4 will intersect the line from nums1\[2\]=2 to nums2\[1\]=2.

**Example 2:**

**Input:** nums1 = \[2,5,1,2,5\], nums2 = \[10,5,2,1,5,2\]
**Output:** 3

**Example 3:**

**Input:** nums1 = \[1,3,7,1,7,5\], nums2 = \[1,9,2,5,1\]
**Output:** 2

**Constraints:**

*   `1 <= nums1.length, nums2.length <= 500`
*   `1 <= nums1[i], nums2[j] <= 2000`

## A solution in Java

```java
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode() {}
    TreeNode(int val) { this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

class Solution {
    public boolean isCousins(TreeNode root, int x, int y) {
        int xDepth = findDepth(root, x, 0);
        int yDepth = findDepth(root, y, 0);
        TreeNode xParent = findParent(root, x);
        TreeNode yParent = findParent(root, y);
        return (xDepth == yDepth) && (xParent != yParent);
    }

    private int findDepth(TreeNode node, int searchVal, int depth) {
        if (node == null) return -1;
        if (node.val == searchVal) return depth;
        int leftDepth = findDepth(node.left, searchVal, depth + 1);
        if (leftDepth != -1) return leftDepth;
        return findDepth(node.right, searchVal, depth + 1);
    }

    private TreeNode findParent(TreeNode node, int searchVal) {
        if (node == null || (node.left == null && node.right == null)) return null;
        if ((node.left != null && node.left.val == searchVal) || (node.right != null && node.right.val == searchVal)) return node;
        TreeNode leftParent = findParent(node.left, searchVal);
        if (leftParent != null) return leftParent;
        return findParent(node.right, searchVal);
    }
}
```
The algorithm consists of two parts: find the depth and parent of each node with the values x and y.

1. `findDepth` function: It is a recursive function that searches for the node with the `searchVal` value in a depth-first manner (left-to-right). When the target node is found, it returns the depth.

2. `findParent` function: It is a recursive function that searches for the node with the `searchVal` value in a depth-first manner (left-to-right). When the target node's children contain the value, it returns the node itself as the parent.

After finding the depth and parent of each node with the values x and y, the nodes are cousins if and only if their depths are the same, and their parents are different.

## A solution in C++

```cpp
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};

class Solution {
public:
    bool isCousins(TreeNode* root, int x, int y) {
        int x_depth = findDepth(root, x, 0);
        int y_depth = findDepth(root, y, 0);
        TreeNode* x_parent = findParent(root, x);
        TreeNode* y_parent = findParent(root, y);
        return (x_depth == y_depth) && (x_parent != y_parent);
    }

private:
    int findDepth(TreeNode* node, int search_val, int depth) {
        if (!node) return -1;
        if (node->val == search_val) return depth;
        int left_depth = findDepth(node->left, search_val, depth + 1);
        if (left_depth != -1) return left_depth;
        return findDepth(node->right, search_val, depth + 1);
    }

    TreeNode* findParent(TreeNode* node, int search_val) {
        if (!node || (!node->left && !node->right)) return nullptr;
        if ((node->left && node->left->val == search_val) || (node->right && node->right->val == search_val)) return node;
        TreeNode* left_parent = findParent(node->left, search_val);
        if (left_parent) return left_parent;
        return findParent(node->right, search_val);
    }
};
```
The algorithm consists of two parts: find the depth and parent of each node with the values x and y.

1. `findDepth` function: It is a recursive function that searches for the node with the `searchVal` value in a depth-first manner (left-to-right). When the target node is found, it returns the depth.

2. `findParent` function: It is a recursive function that searches for the node with the `searchVal` value in a depth-first manner (left-to-right). When the target node's children contain the value, it returns the node itself as the parent.

After finding the depth and parent of each node with the values x and y, the nodes are cousins if and only if their depths are the same, and their parents are different.

## A solution in Python

```python
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def isCousins(self, root, x, y):
        def findDepth(node, search_val, depth):
            if not node:
                return -1
            if node.val == search_val:
                return depth
            left_depth = findDepth(node.left, search_val, depth + 1)
            if left_depth != -1:
                return left_depth
            return findDepth(node.right, search_val, depth + 1)

        def findParent(node, search_val):
            if not node or not (node.left or node.right):
                return None
            if (node.left and node.left.val == search_val) or (node.right and node.right.val == search_val):
                return node
            left_parent = findParent(node.left, search_val)
            if left_parent:
                return left_parent
            return findParent(node.right, search_val)

        x_depth = findDepth(root, x, 0)
        y_depth = findDepth(root, y, 0)
        x_parent = findParent(root, x)
        y_parent = findParent(root, y)
        return (x_depth == y_depth) and (x_parent != y_parent)
```
The algorithm consists of two parts: find the depth and parent of each node with the values x and y.

1. `findDepth` function: It is a recursive function that searches for the node with the `searchVal` value in a depth-first manner (left-to-right). When the target node is found, it returns the depth.

2. `findParent` function: It is a recursive function that searches for the node with the `searchVal` value in a depth-first manner (left-to-right). When the target node's children contain the value, it returns the node itself as the parent.

After finding the depth and parent of each node with the values x and y, the nodes are cousins if and only if their depths are the same, and their parents are different.

## A solution in Javascript

```javascript
class TreeNode {
    constructor(val, left = null, right = null) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

function isCousins(root, x, y) {
    function findDepth(node, searchVal, depth) {
        if (!node) return -1;
        if (node.val === searchVal) return depth;
        let leftDepth = findDepth(node.left, searchVal, depth + 1);
        if (leftDepth !== -1) return leftDepth;
        return findDepth(node.right, searchVal, depth + 1);
    }

    function findParent(node, searchVal) {
        if (!node || (!node.left && !node.right)) return null;
        if ((node.left && node.left.val === searchVal) || (node.right && node.right.val === searchVal)) return node;
        let leftParent = findParent(node.left, searchVal);
        if (leftParent) return leftParent;
        return findParent(node.right, search_val);
    }

    let xDepth = findDepth(root, x, 0);
    let yDepth = findDepth(root, y, 0);
    let xParent = findParent(root, x);
    let yParent = findParent(root, y);
    return (xDepth === yDepth) && (xParent !== yParent);
}
```
The algorithm consists of two parts: find the depth and parent of each node with the values x and y.

1. `findDepth` function: It is a recursive function that searches for the node with the `searchVal` value in a depth-first manner (left-to-right). When the target node is found, it returns the depth.

2. `findParent` function: It is a recursive function that searches for the node with the `searchVal` value in a depth-first manner (left-to-right). When the target node's children contain the value, it returns the node itself as the parent.

After finding the depth and parent of each node with the values x and y, the nodes are cousins if and only if their depths are the same, and their parents are different.


# Escape a Large Maze

- slug: escape-a-large-maze
- difficulty: Hard

There is a 1 million by 1 million grid on an XY-plane, and the coordinates of each grid square are `(x, y)`.

We start at the `source = [sx, sy]` square and want to reach the `target = [tx, ty]` square. There is also an array of `blocked` squares, where each `blocked[i] = [xi, yi]` represents a blocked square with coordinates `(xi, yi)`.

Each move, we can walk one square north, east, south, or west if the square is **not** in the array of `blocked` squares. We are also not allowed to walk outside of the grid.

Return `true` _if and only if it is possible to reach the_ `target` _square from the_ `source` _square through a sequence of valid moves_.

**Example 1:**

**Input:** blocked = \[\[0,1\],\[1,0\]\], source = \[0,0\], target = \[0,2\]
**Output:** false
**Explanation:** The target square is inaccessible starting from the source square because we cannot move.
We cannot move north or east because those squares are blocked.
We cannot move south or west because we cannot go outside of the grid.

**Example 2:**

**Input:** blocked = \[\], source = \[0,0\], target = \[999999,999999\]
**Output:** true
**Explanation:** Because there are no blocked cells, it is possible to reach the target square.

**Constraints:**

*   `0 <= blocked.length <= 200`
*   `blocked[i].length == 2`
*   `0 <= xi, yi < 106`
*   `source.length == target.length == 2`
*   `0 <= sx, sy, tx, ty < 106`
*   `source != target`
*   It is guaranteed that `source` and `target` are not blocked.

## A solution in Java

```java
import java.util.LinkedList;
import java.util.Queue;

public int orangesRotting(int[][] grid) {
    int m = grid.length;
    int n = grid[0].length;
    int freshOranges = 0;
    Queue<int[]> rotten = new LinkedList<>();

    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            if (grid[i][j] == 1)
                freshOranges++;
            else if (grid[i][j] == 2)
                rotten.offer(new int[]{i, j});
        }
    }

    int minutes = 0;
    int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

    while (!rotten.isEmpty() && freshOranges != 0) {
        int size = rotten.size();
        for (int i = 0; i < size; ++i) {
            int[] current = rotten.poll();

            for (int[] direction : directions) {
                int x = current[0] + direction[0];
                int y = current[1] + direction[1];

                if (x < 0 || y < 0 || x >= m || y >= n || grid[x][y] != 1)
                    continue;

                grid[x][y] = 2;
                freshOranges--;
                rotten.offer(new int[]{x, y});
            }
        }
        minutes++;
    }

    return freshOranges == 0 ? minutes : -1;
}
```
The algorithm uses a Breadth-First Search (BFS) approach. Initially, it loops through the grid to count the number of fresh oranges and to store the rotten oranges in a queue. Then, it starts processing rotten oranges from the queue. For each rotten orange, it checks the four adjacent cells (up, down, left, right). If an adjacent cell has a fresh orange, it turns it into a rotten one, decreases the fresh orange counter and appends it to the queue. The process is repeated for all rotten oranges until there are no more fresh oranges or the queue is empty. Finally, the algorithm returns the number of minutes taken, or -1 if there are still fresh oranges left.

## A solution in C++

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

int orangesRotting(std::vector<std::vector<int>>& grid) {
    int m = grid.size();
    int n = grid[0].size();
    int freshOranges = 0;
    std::queue<std::pair<int, int>> rotten;

    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            if (grid[i][j] == 1)
                freshOranges++;
            else if (grid[i][j] == 2)
                rotten.push({i, j});
        }
    }

    int minutes = 0;
    std::vector<std::vector<int>> directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

    while (!rotten.empty() && freshOranges != 0) {
        int size = rotten.size();
        for (int i = 0; i < size; ++i) {
            auto current = rotten.front();
            rotten.pop();

            for (auto& direction : directions) {
                int x = current.first + direction[0];
                int y = current.second + direction[1];

                if (x < 0 || y < 0 || x >= m || y >= n || grid[x][y] != 1)
                    continue;

                grid[x][y] = 2;
                freshOranges--;
                rotten.push({x, y});
            }
        }
        minutes++;
    }

    return freshOranges == 0 ? minutes : -1;
}
```
The algorithm uses a Breadth-First Search (BFS) approach. Initially, it loops through the grid to count the number of fresh oranges and to store the rotten oranges in a queue. Then, it starts processing rotten oranges from the queue. For each rotten orange, it checks the four adjacent cells (up, down, left, right). If an adjacent cell has a fresh orange, it turns it into a rotten one, decreases the fresh orange counter and appends it to the queue. The process is repeated for all rotten oranges until there are no more fresh oranges or the queue is empty. Finally, the algorithm returns the number of minutes taken, or -1 if there are still fresh oranges left.

## A solution in Python

```python
from collections import deque

def orangesRotting(grid):
    m, n = len(grid), len(grid[0])
    fresh_oranges = sum(row.count(1) for row in grid)
    rotten = deque([(i, j) for i, row in enumerate(grid) for j, value in enumerate(row) if value == 2])

    minutes = 0
    directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]

    while rotten and fresh_oranges:
        for _ in range(len(rotten)):
            x, y = rotten.popleft()

            for dx, dy in directions:
                nx, ny = x + dx, y + dy
                if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] == 1:
                    grid[nx][ny] = 2
                    fresh_oranges -= 1
                    rotten.append((nx, ny))
        minutes += 1

    return minutes if fresh_oranges == 0 else -1
```
The algorithm uses a Breadth-First Search (BFS) approach. Initially, it loops through the grid to count the number of fresh oranges and to store the rotten oranges in a queue. Then, it starts processing rotten oranges from the queue. For each rotten orange, it checks the four adjacent cells (up, down, left, right). If an adjacent cell has a fresh orange, it turns it into a rotten one, decreases the fresh orange counter and appends it to the queue. The process is repeated for all rotten oranges until there are no more fresh oranges or the queue is empty. Finally, the algorithm returns the number of minutes taken, or -1 if there are still fresh oranges left.

## A solution in Javascript

```javascript
function orangesRotting(grid) {
    const m = grid.length;
    const n = grid[0].length;
    let freshOranges = 0;
    const rotten = [];

    for (let i = 0; i < m; ++i) {
        for (let j = 0; j < n; ++j) {
            if (grid[i][j] === 1)
                freshOranges++;
            else if (grid[i][j] === 2)
                rotten.push([i, j]);
        }
    }

    let minutes = 0;
    const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]];

    while (rotten.length && freshOranges !== 0) {
        const size = rotten.length;
        for (let i = 0; i < size; ++i) {
            const [x, y] = rotten.shift();

            for (const [dx, dy] of directions) {
                const nx = x + dx;
                const ny = y + dy;

                if (nx < 0 || ny < 0 || nx >= m || ny >= n || grid[nx][ny] !== 1)
                    continue;

                grid[nx][ny] = 2;
                freshOranges--;
                rotten.push([nx, ny]);
            }
        }
        minutes++;
    }

    return freshOranges === 0 ? minutes : -1;
}
```
The algorithm uses a Breadth-First Search (BFS) approach. Initially, it loops through the grid to count the number of fresh oranges and to store the rotten oranges in a queue. Then, it starts processing rotten oranges from the queue. For each rotten orange, it checks the four adjacent cells (up, down, left, right). If an adjacent cell has a fresh orange, it turns it into a rotten one, decreases the fresh orange counter and appends it to the queue. The process is repeated for all rotten oranges until there are no more fresh oranges or the queue is empty. Finally, the algorithm returns the number of minutes taken, or -1 if there are still fresh oranges left.


# Valid Boomerang

- slug: valid-boomerang
- difficulty: Easy

Given an array `points` where `points[i] = [xi, yi]` represents a point on the **X-Y** plane, return `true` _if these points are a **boomerang**_.

A **boomerang** is a set of three points that are **all distinct** and **not in a straight line**.

**Example 1:**

**Input:** points = \[\[1,1\],\[2,3\],\[3,2\]\]
**Output:** true

**Example 2:**

**Input:** points = \[\[1,1\],\[2,2\],\[3,3\]\]
**Output:** false

**Constraints:**

*   `points.length == 3`
*   `points[i].length == 2`
*   `0 <= xi, yi <= 100`

## A solution in Java

```java
public int minKBitFlips(int[] nums, int k) {
    int n = nums.length, res = 0, flipped = 0;
    int[] change = new int[n];
    for (int i = 0; i <= n - k; i++) {
        flipped ^= change[i];
        if (nums[i] == flipped) {
            res++;
            flipped ^= 1;
            if (i + k < n) change[i + k] ^= 1;
        }
    }
    for (int i = n - k + 1; i < n; i++) {
        flipped ^= change[i];
        if (nums[i] == flipped) return -1;
    }
    return res;
}
```
The algorithm iterates through the array and uses a 'greedy' approach. It flips any subarray starting from the left-most index to ensure no zeroes are left in the array.

To minimize the number of flips, we only flip subarrays if it starts with a 0. We also keep track of previous flips using a separate array (`change`) to reduce redundant flips.

In the second loop, we check if any 0s are left in the remaining non-flipable part of the array. If so, return -1 as it's not possible to have an all 1s array.

## A solution in C++

```cpp
int minKBitFlips(vector<int>& nums, int k) {
    int n = nums.size(), res = 0, flipped = 0;
    vector<int> change(n, 0);
    for (int i = 0; i <= n - k; i++) {
        flipped ^= change[i];
        if (nums[i] ^ flipped == 0) {
            res++;
            flipped ^= 1;
            if (i + k < n) change[i + k] ^= 1;
        }
    }
    for (int i = n - k + 1; i < n; i++) {
        flipped ^= change[i];
        if (nums[i] ^ flipped == 0) return -1;
    }
    return res;
}
```
The algorithm iterates through the array and uses a 'greedy' approach. It flips any subarray starting from the left-most index to ensure no zeroes are left in the array.

To minimize the number of flips, we only flip subarrays if it starts with a 0. We also keep track of previous flips using a separate array (`change`) to reduce redundant flips.

In the second loop, we check if any 0s are left in the remaining non-flipable part of the array. If so, return -1 as it's not possible to have an all 1s array.

## A solution in Python

```python
def min_k_bit_flips(nums, k):
    n, res, flipped = len(nums), 0, 0
    change = [0] * n
    for i in range(n - k + 1):
        flipped ^= change[i]
        if nums[i] == flipped:
            res += 1
            flipped ^= 1
            if i + k < n:
                change[i + k] ^= 1
    for i in range(n - k + 1, n):
        flipped ^= change[i]
        if nums[i] == flipped:
            return -1
    return res
```
The algorithm iterates through the array and uses a 'greedy' approach. It flips any subarray starting from the left-most index to ensure no zeroes are left in the array.

To minimize the number of flips, we only flip subarrays if it starts with a 0. We also keep track of previous flips using a separate array (`change`) to reduce redundant flips.

In the second loop, we check if any 0s are left in the remaining non-flipable part of the array. If so, return -1 as it's not possible to have an all 1s array.

## A solution in Javascript

```javascript
function minKBitFlips(nums, k) {
    const n = nums.length;
    let res = 0, flipped = 0;
    const change = new Array(n).fill(0);
    for (let i = 0; i <= n - k; ++i) {
        flipped ^= change[i];
        if (nums[i] == flipped) {
            res++;
            flipped ^= 1;
            if (i + k < n) change[i + k] ^= 1;
        }
    }
    for (let i = n - k + 1; i < n; ++i) {
        flipped ^= change[i];
        if (nums[i] == flipped) return -1;
    }
    return res;
}
```
The algorithm iterates through the array and uses a 'greedy' approach. It flips any subarray starting from the left-most index to ensure no zeroes are left in the array.

To minimize the number of flips, we only flip subarrays if it starts with a 0. We also keep track of previous flips using a separate array (`change`) to reduce redundant flips.

In the second loop, we check if any 0s are left in the remaining non-flipable part of the array. If so, return -1 as it's not possible to have an all 1s array.


# Binary Search Tree to Greater Sum Tree

- slug: binary-search-tree-to-greater-sum-tree
- difficulty: Medium

Given the `root` of a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus the sum of all keys greater than the original key in BST.

As a reminder, a _binary search tree_ is a tree that satisfies these constraints:

*   The left subtree of a node contains only nodes with keys **less than** the node's key.
*   The right subtree of a node contains only nodes with keys **greater than** the node's key.
*   Both the left and right subtrees must also be binary search trees.

**Example 1:**

**Input:** root = \[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8\]
**Output:** \[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8\]

**Example 2:**

**Input:** root = \[0,null,1\]
**Output:** \[1,null,1\]

**Constraints:**

*   The number of nodes in the tree is in the range `[1, 100]`.
*   `0 <= Node.val <= 100`
*   All the values in the tree are **unique**.

**Note:** This question is the same as 538: [https://leetcode.com/problems/convert-bst-to-greater-tree/](https://leetcode.com/problems/convert-bst-to-greater-tree/)

## A solution in Java

```java
import java.util.Arrays;

public int squareful_perms(int[] nums) {
    Arrays.sort(nums);
    return count_permutations(nums, 0);
}

private boolean is_squareful(int x, int y) {
    int s = (int) Math.sqrt(x + y);
    return s * s == x + y;
}

private int count_permutations(int[] nums, int start) {
    if (start == nums.length) {
        return 1;
    }

    int count = 0;

    for (int i = start; i < nums.length; i++) {
        if (i == start || nums[i] != nums[start]) {
            if (start == 0 || is_squareful(nums[start - 1], nums[i])) {
                swap(nums, i, start);
                count += count_permutations(nums, start + 1);
                swap(nums, i, start);
            }
        }
    }

    return count;
}

private void swap(int[] nums, int i, int j) {
    int temp = nums[i];
    nums[i] = nums[j];
    nums[j] = temp;
}
```
The algorithm starts by sorting the input array, this will make it easier to find out permutations without considering repeated elements in the next steps.

The core idea is to iterate through the sorted array and permutations of adjacent numbers. To do that, we use a function `count_permutations` that takes the given array and a starting index. The function works recursively; at each step, it checks whether the current pair of adjacent elements in the array is squareful (using `is_squareful` function). If it is, it continues with the next index by swapping the elements and making a recursive call.

What's important is that the algorithm avoids duplicated permutations by checking if the elements at the starting index and the current index are equal. If they are equal, it means this permutation was already calculated and doesn't need to be counted again. This is possible because the array is sorted.

Finally, the count of squareful permutations is returned.

## A solution in C++

```cpp
#include<cmath>
#include<algorithm>

bool is_squareful(int x, int y) {
    int s = sqrt(x + y);
    return s * s == x + y;
}

void count_permutations(const vector<int>& nums, int start, int &count) {
    if (start == nums.size()) {
        count++;
        return;
    }
    for (int i = start; i < nums.size(); i++) {
        if (i == start || nums[i] != nums[start]) {
            if (start == 0 || is_squareful(nums[start - 1], nums[i])) {
                swap(nums[i], nums[start]);
                count_permutations(nums, start + 1, count);
                swap(nums[i], nums[start]);
            }
        }
    }
}

int squareful_perms(vector<int> nums) {
    int count = 0;
    sort(nums.begin(), nums.end());
    count_permutations(nums, 0, count);
    return count;
}
```
The algorithm starts by sorting the input array, this will make it easier to find out permutations without considering repeated elements in the next steps.

The core idea is to iterate through the sorted array and permutations of adjacent numbers. To do that, we use a function `count_permutations` that takes the given array and a starting index. The function works recursively; at each step, it checks whether the current pair of adjacent elements in the array is squareful (using `is_squareful` function). If it is, it continues with the next index by swapping the elements and making a recursive call.

What's important is that the algorithm avoids duplicated permutations by checking if the elements at the starting index and the current index are equal. If they are equal, it means this permutation was already calculated and doesn't need to be counted again. This is possible because the array is sorted.

Finally, the count of squareful permutations is returned.

## A solution in Python

```python
from math import sqrt
from itertools import permutations

def is_squareful(x, int_y):
    s = int(sqrt(x + y))
    return s * s == x + y

def squareful_perms(nums):
    count = 0
    for p in permutations(nums):
        if all(is_squareful(p[i], p[i + 1]) for i in range(len(p) - 1)):
            count += 1
    return count
```
The algorithm starts by sorting the input array, this will make it easier to find out permutations without considering repeated elements in the next steps.

The core idea is to iterate through the sorted array and permutations of adjacent numbers. To do that, we use a function `count_permutations` that takes the given array and a starting index. The function works recursively; at each step, it checks whether the current pair of adjacent elements in the array is squareful (using `is_squareful` function). If it is, it continues with the next index by swapping the elements and making a recursive call.

What's important is that the algorithm avoids duplicated permutations by checking if the elements at the starting index and the current index are equal. If they are equal, it means this permutation was already calculated and doesn't need to be counted again. This is possible because the array is sorted.

Finally, the count of squareful permutations is returned.

## A solution in Javascript

```javascript
function is_squareful(x, y) {
    const s = Math.floor(Math.sqrt(x + y));
    return s * s === x + y;
}

function count_permutations(nums, start) {
    if (start === nums.length) {
        return 1;
    }

    let count = 0;

    for (let i = start; i < nums.length; i++) {
        if (i === start || nums[i] !== nums[start]) {
            if (start === 0 || is_squareful(nums[start - 1], nums[i])) {
                [nums[i], nums[start]] = [nums[start], nums[i]];
                count += count_permutations(nums, start + 1);
                [nums[i], nums[start]] = [nums[start], nums[i]];
            }
        }
    }

    return count;
}

function squareful_perms(nums) {
    nums.sort((a, b) => a - b);
    return count_permutations(nums, 0);
}
```
The algorithm starts by sorting the input array, this will make it easier to find out permutations without considering repeated elements in the next steps.

The core idea is to iterate through the sorted array and permutations of adjacent numbers. To do that, we use a function `count_permutations` that takes the given array and a starting index. The function works recursively; at each step, it checks whether the current pair of adjacent elements in the array is squareful (using `is_squareful` function). If it is, it continues with the next index by swapping the elements and making a recursive call.

What's important is that the algorithm avoids duplicated permutations by checking if the elements at the starting index and the current index are equal. If they are equal, it means this permutation was already calculated and doesn't need to be counted again. This is possible because the array is sorted.

Finally, the count of squareful permutations is returned.


# Minimum Score Triangulation of Polygon

- slug: minimum-score-triangulation-of-polygon
- difficulty: Medium

You have a convex `n`\-sided polygon where each vertex has an integer value. You are given an integer array `values` where `values[i]` is the value of the `ith` vertex (i.e., **clockwise order**).

You will **triangulate** the polygon into `n - 2` triangles. For each triangle, the value of that triangle is the product of the values of its vertices, and the total score of the triangulation is the sum of these values over all `n - 2` triangles in the triangulation.

Return _the smallest possible total score that you can achieve with some triangulation of the polygon_.

**Example 1:**

**Input:** values = \[1,2,3\]
**Output:** 6
**Explanation:** The polygon is already triangulated, and the score of the only triangle is 6.

**Example 2:**

**Input:** values = \[3,7,4,5\]
**Output:** 144
**Explanation:** There are two triangulations, with possible scores: 3\*7\*5 + 4\*5\*7 = 245, or 3\*4\*5 + 3\*4\*7 = 144.
The minimum score is 144.

**Example 3:**

**Input:** values = \[1,3,1,4,1,5\]
**Output:** 13
**Explanation:** The minimum score triangulation has score 1\*1\*3 + 1\*1\*4 + 1\*1\*5 + 1\*1\*1 = 13.

**Constraints:**

*   `n == values.length`
*   `3 <= n <= 50`
*   `1 <= values[i] <= 100`

## A solution in Java

```java
public int findJudge(int n, int[][] trust) {
    int[] trustCounts = new int[n + 1];
    for (int[] relation : trust) {
        trustCounts[relation[0]]--;
        trustCounts[relation[1]]++;
    }

    for (int i = 1; i <= n; i++) {
        if (trustCounts[i] == n - 1) {
            return i;
        }
    }
    return -1;
}
```
1. We create an array `trustCounts` of length `n+1` initialized with zeroes. This will hold the number of trust relationships for each person.
2. For each trust[i] = [a, b] in the input trust array, we decrease the count for person 'a' by 1 (since 'a' trusts someone else) and increase the count for person 'b' by 1 (since 'b' is trusted by 'a').
3. We then iterate through the `trustCounts` array from 1 to n (inclusive). If the trust count for person 'i' is `n - 1`, this means that every other person trusts 'i', and 'i' trusts no one else. In this case, 'i' is the town judge and we return 'i'.
4. If no such 'i' is found, we return -1 as the town judge cannot be identified.

## A solution in C++

```cpp
int findJudge(int n, vector<vector<int>>& trust) {
    vector<int> trustCounts(n + 1, 0);
    for (vector<int>& relation : trust) {
        trustCounts[relation[0]]--;
        trustCounts[relation[1]]++;
    }

    for (int i = 1; i <= n; ++i) {
        if (trustCounts[i] == n - 1) {
            return i;
        }
    }
    return -1;
}
```
1. We create an array `trustCounts` of length `n+1` initialized with zeroes. This will hold the number of trust relationships for each person.
2. For each trust[i] = [a, b] in the input trust array, we decrease the count for person 'a' by 1 (since 'a' trusts someone else) and increase the count for person 'b' by 1 (since 'b' is trusted by 'a').
3. We then iterate through the `trustCounts` array from 1 to n (inclusive). If the trust count for person 'i' is `n - 1`, this means that every other person trusts 'i', and 'i' trusts no one else. In this case, 'i' is the town judge and we return 'i'.
4. If no such 'i' is found, we return -1 as the town judge cannot be identified.

## A solution in Python

```python
def find_judge(n, trust):
    trustCounts = [0] * (n + 1)
    for a, b in trust:
        trustCounts[a] -= 1
        trustCounts[b] += 1

    for i in range(1, n + 1):
        if trustCounts[i] == n - 1:
            return i
    return -1
```
1. We create an array `trustCounts` of length `n+1` initialized with zeroes. This will hold the number of trust relationships for each person.
2. For each trust[i] = [a, b] in the input trust array, we decrease the count for person 'a' by 1 (since 'a' trusts someone else) and increase the count for person 'b' by 1 (since 'b' is trusted by 'a').
3. We then iterate through the `trustCounts` array from 1 to n (inclusive). If the trust count for person 'i' is `n - 1`, this means that every other person trusts 'i', and 'i' trusts no one else. In this case, 'i' is the town judge and we return 'i'.
4. If no such 'i' is found, we return -1 as the town judge cannot be identified.

## A solution in Javascript

```javascript
function findJudge(n, trust) {
    const trustCounts = new Array(n + 1).fill(0);
    for (const relation of trust) {
        trustCounts[relation[0]]--;
        trustCounts[relation[1]]++;
    }

    for (let i = 1; i <= n; i++) {
        if (trustCounts[i] === n - 1) {
            return i;
        }
    }
    return -1;
}
```
1. We create an array `trustCounts` of length `n+1` initialized with zeroes. This will hold the number of trust relationships for each person.
2. For each trust[i] = [a, b] in the input trust array, we decrease the count for person 'a' by 1 (since 'a' trusts someone else) and increase the count for person 'b' by 1 (since 'b' is trusted by 'a').
3. We then iterate through the `trustCounts` array from 1 to n (inclusive). If the trust count for person 'i' is `n - 1`, this means that every other person trusts 'i', and 'i' trusts no one else. In this case, 'i' is the town judge and we return 'i'.
4. If no such 'i' is found, we return -1 as the town judge cannot be identified.


# Moving Stones Until Consecutive II

- slug: moving-stones-until-consecutive-ii
- difficulty: Medium

There are some stones in different positions on the X-axis. You are given an integer array `stones`, the positions of the stones.

Call a stone an **endpoint stone** if it has the smallest or largest position. In one move, you pick up an **endpoint stone** and move it to an unoccupied position so that it is no longer an **endpoint stone**.

*   In particular, if the stones are at say, `stones = [1,2,5]`, you cannot move the endpoint stone at position `5`, since moving it to any position (such as `0`, or `3`) will still keep that stone as an endpoint stone.

The game ends when you cannot make any more moves (i.e., the stones are in three consecutive positions).

Return _an integer array_ `answer` _of length_ `2` _where_:

*   `answer[0]` _is the minimum number of moves you can play, and_
*   `answer[1]` _is the maximum number of moves you can play_.

**Example 1:**

**Input:** stones = \[7,4,9\]
**Output:** \[1,2\]
**Explanation:** We can move 4 -> 8 for one move to finish the game.
Or, we can move 9 -> 5, 4 -> 6 for two moves to finish the game.

**Example 2:**

**Input:** stones = \[6,5,4,3,10\]
**Output:** \[2,3\]
**Explanation:** We can move 3 -> 8 then 10 -> 7 to finish the game.
Or, we can move 3 -> 7, 4 -> 8, 5 -> 9 to finish the game.
Notice we cannot move 10 -> 2 to finish the game, because that would be an illegal move.

**Constraints:**

*   `3 <= stones.length <= 104`
*   `1 <= stones[i] <= 109`
*   All the values of `stones` are **unique**.

## A solution in Java

```java
public TreeNode insertIntoMaxTree(TreeNode root, int val) {
    if (root == null || val > root.val) {
        TreeNode newNode = new TreeNode(val);
        newNode.left = root;
        return newNode;
    }
    root.right = insertIntoMaxTree(root.right, val);
    return root;
}
```
The algorithm works recursively, traversing the tree along the right children until it finds the appropriate position to insert `val` as the left child of the original node. When the algorithm reaches a node where `root` is `null` or `val` is greater than `root.val`, it creates a new node with `val` and sets the newly created node's `left` child to the original `root`. If the condition is not met, the algorithm continues to traverse the tree by updating `root.right` with the call to the function `insertIntoMaxTree(root.right, val)`.

This way, we maintain the maximum tree property by making sure that the newly inserted node's value is greater than any value in its subtree.

## A solution in C++

```cpp
TreeNode* insertIntoMaxTree(TreeNode* root, int val) {
    if (!root || val > root->val) {
        TreeNode *newNode = new TreeNode(val);
        newNode->left = root;
        return newNode;
    }
    root->right = insertIntoMaxTree(root->right, val);
    return root;
}
```
The algorithm works recursively, traversing the tree along the right children until it finds the appropriate position to insert `val` as the left child of the original node. When the algorithm reaches a node where `root` is `null` or `val` is greater than `root.val`, it creates a new node with `val` and sets the newly created node's `left` child to the original `root`. If the condition is not met, the algorithm continues to traverse the tree by updating `root.right` with the call to the function `insertIntoMaxTree(root.right, val)`.

This way, we maintain the maximum tree property by making sure that the newly inserted node's value is greater than any value in its subtree.

## A solution in Python

```python
def insertIntoMaxTree(self, root: TreeNode, val: int) -> TreeNode:
    if root is None or val > root.val:
        newNode = TreeNode(val)
        newNode.left = root
        return newNode
    root.right = self.insertIntoMaxTree(root.right, val)
    return root
```
The algorithm works recursively, traversing the tree along the right children until it finds the appropriate position to insert `val` as the left child of the original node. When the algorithm reaches a node where `root` is `null` or `val` is greater than `root.val`, it creates a new node with `val` and sets the newly created node's `left` child to the original `root`. If the condition is not met, the algorithm continues to traverse the tree by updating `root.right` with the call to the function `insertIntoMaxTree(root.right, val)`.

This way, we maintain the maximum tree property by making sure that the newly inserted node's value is greater than any value in its subtree.

## A solution in Javascript

```javascript
function insertIntoMaxTree(root, val) {
    if (!root || val > root.val) {
        const newNode = new TreeNode(val);
        newNode.left = root;
        return newNode;
    }
    root.right = insertIntoMaxTree(root.right, val);
    return root;
}
```
The algorithm works recursively, traversing the tree along the right children until it finds the appropriate position to insert `val` as the left child of the original node. When the algorithm reaches a node where `root` is `null` or `val` is greater than `root.val`, it creates a new node with `val` and sets the newly created node's `left` child to the original `root`. If the condition is not met, the algorithm continues to traverse the tree by updating `root.right` with the call to the function `insertIntoMaxTree(root.right, val)`.

This way, we maintain the maximum tree property by making sure that the newly inserted node's value is greater than any value in its subtree.


# Robot Bounded In Circle

- slug: robot-bounded-in-circle
- difficulty: Medium

On an infinite plane, a robot initially stands at `(0, 0)` and faces north. Note that:

*   The **north direction** is the positive direction of the y-axis.
*   The **south direction** is the negative direction of the y-axis.
*   The **east direction** is the positive direction of the x-axis.
*   The **west direction** is the negative direction of the x-axis.

The robot can receive one of three instructions:

*   `"G "`: go straight 1 unit.
*   `"L "`: turn 90 degrees to the left (i.e., anti-clockwise direction).
*   `"R "`: turn 90 degrees to the right (i.e., clockwise direction).

The robot performs the `instructions` given in order, and repeats them forever.

Return `true` if and only if there exists a circle in the plane such that the robot never leaves the circle.

**Example 1:**

**Input:** instructions =  "GGLLGG "
**Output:** true
**Explanation:** The robot is initially at (0, 0) facing the north direction.
 "G ": move one step. Position: (0, 1). Direction: North.
 "G ": move one step. Position: (0, 2). Direction: North.
 "L ": turn 90 degrees anti-clockwise. Position: (0, 2). Direction: West.
 "L ": turn 90 degrees anti-clockwise. Position: (0, 2). Direction: South.
 "G ": move one step. Position: (0, 1). Direction: South.
 "G ": move one step. Position: (0, 0). Direction: South.
Repeating the instructions, the robot goes into the cycle: (0, 0) --> (0, 1) --> (0, 2) --> (0, 1) --> (0, 0).
Based on that, we return true.

**Example 2:**

**Input:** instructions =  "GG "
**Output:** false
**Explanation:** The robot is initially at (0, 0) facing the north direction.
 "G ": move one step. Position: (0, 1). Direction: North.
 "G ": move one step. Position: (0, 2). Direction: North.
Repeating the instructions, keeps advancing in the north direction and does not go into cycles.
Based on that, we return false.

**Example 3:**

**Input:** instructions =  "GL "
**Output:** true
**Explanation:** The robot is initially at (0, 0) facing the north direction.
 "G ": move one step. Position: (0, 1). Direction: North.
 "L ": turn 90 degrees anti-clockwise. Position: (0, 1). Direction: West.
 "G ": move one step. Position: (-1, 1). Direction: West.
 "L ": turn 90 degrees anti-clockwise. Position: (-1, 1). Direction: South.
 "G ": move one step. Position: (-1, 0). Direction: South.
 "L ": turn 90 degrees anti-clockwise. Position: (-1, 0). Direction: East.
 "G ": move one step. Position: (0, 0). Direction: East.
 "L ": turn 90 degrees anti-clockwise. Position: (0, 0). Direction: North.
Repeating the instructions, the robot goes into the cycle: (0, 0) --> (0, 1) --> (-1, 1) --> (-1, 0) --> (0, 0).
Based on that, we return true.

**Constraints:**

*   `1 <= instructions.length <= 100`
*   `instructions[i]` is `'G'`, `'L'` or, `'R'`.

## A solution in Java

```java
public int numRookCaptures(char[][] board) {
    int x = 0, y = 0, captures = 0;
    outer: for (x = 0; x < 8; x++) {
        for (y = 0; y < 8; y++) {
            if (board[x][y] == 'R') {
                break outer;
            }
        }
    }

    int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    for (int[] dir : dirs) {
        int nx = x + dir[0];
        int ny = y + dir[1];
        while (nx >= 0 && nx < 8 && ny >= 0 && ny < 8) {
            if (board[nx][ny] == 'p') {
                captures++;
                break;
            } else if (board[nx][ny] == 'B') {
                break;
            }
            nx += dir[0];
            ny += dir[1];
        }
    }

    return captures;
}
```
The algorithm first iterates through the chessboard to find the position of the white rook. After finding the rook, the algorithm iterates through the four cardinal directions (north, east, south, and west) and checks if the rook can capture a black pawn in that direction. If the rook can capture the pawn, the variable `captures` is incremented. If the rook encounters a white bishop in a direction, it stops searching further in that direction. Finally, the function returns the number of captures.

## A solution in C++

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

int numRookCaptures(std::vector<std::string>& board) {
    int x = 0, y = 0, captures = 0;
    for (x = 0; x < 8; ++x) {
        for (y = 0; y < 8; ++y) {
            if (board[x][y] == 'R') {
                break;
            }
        }
        if (y < 8) break;
    }

    std::vector<std::pair<int, int>> dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    for (auto& dir : dirs) {
        int nx = x + dir.first;
        int ny = y + dir.second;
        while (nx >= 0 && nx < 8 && ny >= 0 && ny < 8) {
            if (board[nx][ny] == 'p') {
                captures++;
                break;
            } else if (board[nx][ny] == 'B') {
                break;
            }
            nx += dir.first;
            ny += dir.second;
        }
    }

    return captures;
}
```
The algorithm first iterates through the chessboard to find the position of the white rook. After finding the rook, the algorithm iterates through the four cardinal directions (north, east, south, and west) and checks if the rook can capture a black pawn in that direction. If the rook can capture the pawn, the variable `captures` is incremented. If the rook encounters a white bishop in a direction, it stops searching further in that direction. Finally, the function returns the number of captures.

## A solution in Python

```python
def numRookCaptures(board):
    x, y, captures = 0, 0, 0

    for i in range(8):
        for j in range(8):
            if board[i][j] == 'R':
                x, y = i, j
                break
        if board[x][y] == 'R':
            break

    dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)]
    for dx, dy in dirs:
        nx, ny = x + dx, y + dy
        while 0 <= nx < 8 and 0 <= ny < 8:
            if board[nx][ny] == 'p':
                captures += 1
                break
            elif board[nx][ny] == 'B':
                break
            nx += dx
            ny += dy

    return captures
```
The algorithm first iterates through the chessboard to find the position of the white rook. After finding the rook, the algorithm iterates through the four cardinal directions (north, east, south, and west) and checks if the rook can capture a black pawn in that direction. If the rook can capture the pawn, the variable `captures` is incremented. If the rook encounters a white bishop in a direction, it stops searching further in that direction. Finally, the function returns the number of captures.

## A solution in Javascript

```javascript
function numRookCaptures(board) {
    let x = 0, y = 0, captures = 0;

    outer: for (x = 0; x < 8; x++) {
        for (y = 0; y < 8; y++) {
            if (board[x][y] === 'R') {
                break outer;
            }
        }
    }

    let dirs = [[1, 0], [-1, 0], [0, 1], [0, -1]];
    for (let dir of dirs) {
        let nx = x + dir[0];
        let ny = y + dir[1];
        while (nx >= 0 && nx < 8 && ny >= 0 && ny < 8) {
            if (board[nx][ny] === 'p') {
                captures++;
                break;
            } else if (board[nx][ny] === 'B') {
                break;
            }
            nx += dir[0];
            ny += dir[1];
        }
    }

    return captures;
}
```
The algorithm first iterates through the chessboard to find the position of the white rook. After finding the rook, the algorithm iterates through the four cardinal directions (north, east, south, and west) and checks if the rook can capture a black pawn in that direction. If the rook can capture the pawn, the variable `captures` is incremented. If the rook encounters a white bishop in a direction, it stops searching further in that direction. Finally, the function returns the number of captures.


# Flower Planting With No Adjacent

- slug: flower-planting-with-no-adjacent
- difficulty: Medium

You have `n` gardens, labeled from `1` to `n`, and an array `paths` where `paths[i] = [xi, yi]` describes a bidirectional path between garden `xi` to garden `yi`. In each garden, you want to plant one of 4 types of flowers.

All gardens have **at most 3** paths coming into or leaving it.

Your task is to choose a flower type for each garden such that, for any two gardens connected by a path, they have different types of flowers.

Return _**any** such a choice as an array_ `answer`_, where_ `answer[i]` _is the type of flower planted in the_ `(i+1)th` _garden. The flower types are denoted_ `1`_,_ `2`_,_ `3`_, or_ `4`_. It is guaranteed an answer exists._

**Example 1:**

**Input:** n = 3, paths = \[\[1,2\],\[2,3\],\[3,1\]\]
**Output:** \[1,2,3\]
**Explanation:**
Gardens 1 and 2 have different types.
Gardens 2 and 3 have different types.
Gardens 3 and 1 have different types.
Hence, \[1,2,3\] is a valid answer. Other valid answers include \[1,2,4\], \[1,4,2\], and \[3,2,1\].

**Example 2:**

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

**Example 3:**

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

**Constraints:**

*   `1 <= n <= 104`
*   `0 <= paths.length <= 2 * 104`
*   `paths[i].length == 2`
*   `1 <= xi, yi <= n`
*   `xi != yi`
*   Every garden has **at most 3** paths coming into or leaving it.

## A solution in Java

```java
public int mergeStones(int[] stones, int k) {
    int n = stones.length;
    if ((n - 1) % (k - 1) != 0) return -1;
    int[] prefixSum = new int[n + 1];
    int[][][] dp = new int[n][n][k + 1];

    for (int i = 0; i < n; ++i) {
        prefixSum[i + 1] = prefixSum[i] + stones[i];
    }

    for (int l = 2; l <= n; ++l) {
        for (int i = 0; i <= n - l; ++i) {
            int j = i + l - 1;
            for (int m = 2; m <= k; ++m) {
                for (int p = i; p + m <= j + 1; p += k - 1) {
                    dp[i][j][m] = (dp[i][p][1] + dp[p + 1][j][m - 1]) % (1_000_000_000 + 7);
                }
            }
            if ((j - i) % (k - 1) == 0) {
                dp[i][j][1] = (dp[i][j][k] + prefixSum[j + 1] - prefixSum[i]) % (1_000_000_000 + 7);
            }
        }
    }
    return dp[0][n - 1][1];
}
```
To solve this problem efficiently, we will use dynamic programming. First, we check if it is possible to merge all piles of stones into one pile using the given value of `k`. If not, we return -1.

Next, we initialize a memoization table (dp) and the prefix sum (useful for calculating the total sum of stones) in each language. We use three nested loops to account for all possible values of `l`, `i`, `j`, where `l` is the subarray length, and `ij` is the start and end indices. Then a fourth loop iterates through `m`, which is the number of piles to merge.

For each possible merge, we update the memoization table to store the minimum cost to merge all piles of stones in the current subarray. When the current subarray has a length that is a multiple of the value `k`, we update the dp[i][j][1] with the minimum cost for merging the `k` piles.

At the end of the function, we return the cost to merge all piles of stones into one pile.dp[0][n - 1][1] contains the result.

## A solution in C++

```cpp
int mergeStones(vector<int>& stones, int k) {
    int n = stones.size();
    if ((n - 1) % (k - 1) != 0) return -1;
    vector<int> prefixSum(n + 1, 0);
    vector<vector<vector<int>>> dp(n, vector<vector<int>>(n, vector<int>(k + 1, 0)));

    for (int i = 0; i < n; ++i) {
        prefixSum[i + 1] = prefixSum[i] + stones[i];
    }

    for (int l = 2; l <= n; ++l) {
        for (int i = 0; i <= n - l; ++i) {
            int j = i + l - 1;
            for (int m = 2; m <= k; ++m) {
                for (int p = i; p + m <= j + 1; p += k - 1) {
                    dp[i][j][m] = (dp[i][p][1] + dp[p + 1][j][m - 1]) % (1e9 + 7);
                }
            }
            if ((j - i) % (k - 1) == 0) {
                dp[i][j][1] = (dp[i][j][k] + prefixSum[j + 1] - prefixSum[i]) % (1e9 + 7);
            }
        }
    }
    return dp[0][n - 1][1];
}
```
To solve this problem efficiently, we will use dynamic programming. First, we check if it is possible to merge all piles of stones into one pile using the given value of `k`. If not, we return -1.

Next, we initialize a memoization table (dp) and the prefix sum (useful for calculating the total sum of stones) in each language. We use three nested loops to account for all possible values of `l`, `i`, `j`, where `l` is the subarray length, and `ij` is the start and end indices. Then a fourth loop iterates through `m`, which is the number of piles to merge.

For each possible merge, we update the memoization table to store the minimum cost to merge all piles of stones in the current subarray. When the current subarray has a length that is a multiple of the value `k`, we update the dp[i][j][1] with the minimum cost for merging the `k` piles.

At the end of the function, we return the cost to merge all piles of stones into one pile.dp[0][n - 1][1] contains the result.

## A solution in Python

```python
def mergeStones(stones, k):
    n = len(stones)
    if (n - 1) % (k - 1) != 0:
        return -1
    prefixSum = [0] * (n + 1)
    dp = [[[-1] * (k + 1) for _ in range(n)] for _ in range(n)]

    for i in range(n):
        prefixSum[i + 1] = prefixSum[i] + stones[i]

    for l in range(2, n + 1):
        for i in range(n - l + 1):
            j = i + l - 1
            for m in range(2, k + 1):
                for p in range(i, j + 1 - m + 1, k - 1):
                    dp[i][j][m] = (dp[i][p][1] + dp[p + 1][j][m - 1]) % (1e9 + 7)
            if (j - i) % (k - 1) == 0:
                dp[i][j][1] = (dp[i][j][k] + prefixSum[j + 1] - prefixSum[i]) % (1e9 + 7)

    return dp[0][n - 1][1]
```
To solve this problem efficiently, we will use dynamic programming. First, we check if it is possible to merge all piles of stones into one pile using the given value of `k`. If not, we return -1.

Next, we initialize a memoization table (dp) and the prefix sum (useful for calculating the total sum of stones) in each language. We use three nested loops to account for all possible values of `l`, `i`, `j`, where `l` is the subarray length, and `ij` is the start and end indices. Then a fourth loop iterates through `m`, which is the number of piles to merge.

For each possible merge, we update the memoization table to store the minimum cost to merge all piles of stones in the current subarray. When the current subarray has a length that is a multiple of the value `k`, we update the dp[i][j][1] with the minimum cost for merging the `k` piles.

At the end of the function, we return the cost to merge all piles of stones into one pile.dp[0][n - 1][1] contains the result.

## A solution in Javascript

```javascript
function mergeStones(stones, k) {
    let n = stones.length;
    if ((n - 1) % (k - 1) !== 0) return -1;
    let prefixSum = new Array(n + 1).fill(0);
    let dp = [...Array(n)].map(() => [...Array(n)].map(() => Array(k + 1).fill(0)));

    for (let i = 0; i < n; ++i) {
        prefixSum[i + 1] = prefixSum[i] + stones[i];
    }

    for (let l = 2; l <= n; ++l) {
        for (let i = 0; i <= n - l; ++i) {
            let j = i + l - 1;
            for (let m = 2; m <= k; ++m) {
                for (let p = i; p + m <= j + 1; p += k - 1) {
                    dp[i][j][m] = (dp[i][p][1] + dp[p + 1][j][m - 1]) % (1e9 + 7);
                }
            }
            if ((j - i) % (k - 1) === 0) {
                dp[i][j][1] = (dp[i][j][k] + prefixSum[j + 1] - prefixSum[i]) % (1e9 + 7);
            }
        }
    }
    return dp[0][n - 1][1];
}
```
To solve this problem efficiently, we will use dynamic programming. First, we check if it is possible to merge all piles of stones into one pile using the given value of `k`. If not, we return -1.

Next, we initialize a memoization table (dp) and the prefix sum (useful for calculating the total sum of stones) in each language. We use three nested loops to account for all possible values of `l`, `i`, `j`, where `l` is the subarray length, and `ij` is the start and end indices. Then a fourth loop iterates through `m`, which is the number of piles to merge.

For each possible merge, we update the memoization table to store the minimum cost to merge all piles of stones in the current subarray. When the current subarray has a length that is a multiple of the value `k`, we update the dp[i][j][1] with the minimum cost for merging the `k` piles.

At the end of the function, we return the cost to merge all piles of stones into one pile.dp[0][n - 1][1] contains the result.


# Partition Array for Maximum Sum

- slug: partition-array-for-maximum-sum
- difficulty: Medium

Given an integer array `arr`, partition the array into (contiguous) subarrays of length **at most** `k`. After partitioning, each subarray has their values changed to become the maximum value of that subarray.

Return _the largest sum of the given array after partitioning. Test cases are generated so that the answer fits in a **32-bit** integer._

**Example 1:**

**Input:** arr = \[1,15,7,9,2,5,10\], k = 3
**Output:** 84
**Explanation:** arr becomes \[15,15,15,9,10,10,10\]

**Example 2:**

**Input:** arr = \[1,4,1,5,7,3,6,1,9,9,3\], k = 4
**Output:** 83

**Example 3:**

**Input:** arr = \[1\], k = 1
**Output:** 1

**Constraints:**

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

## A solution in Java

```java
import java.util.*;

public int[] gridIllumination(int n, int[][] lamps, int[][] queries) {
    Set<Integer> lampCols = new HashSet<>();
    Set<Integer> lampRows = new HashSet<>();
    Set<Integer> lampLeftDiag = new HashSet<>();
    Set<Integer> lampRightDiag = new HashSet<>();

    for (int[] lamp : lamps) {
        lampRows.add(lamp[0]);
        lampCols.add(lamp[1]);
        lampLeftDiag.add(lamp[0] - lamp[1]);
        lampRightDiag.add(lamp[0] + lamp[1]);
    }

    int[] ans = new int[queries.length];

    for (int j = 0; j < queries.length; j++) {
        int row = queries[j][0];
        int col = queries[j][1];
        if (lampRows.contains(row) || lampCols.contains(col) || lampLeftDiag.contains(row - col) || lampRightDiag.contains(row + col)) {
            ans[j] = 1;
        } else {
            ans[j] = 0;
        }
        for (int i = -1; i <= 1; i++) {
            for (int k = -1; k <= 1; k++) {
                int newRow = row + i;
                int newCol = col + k;
                lampRows.remove(newRow);
                lampCols.remove(newCol);
                lampLeftDiag.remove(newRow - newCol);
                lampRightDiag.remove(newRow + newCol);
            }
        }
    }
    return ans;
}
```
The algorithm maintains four sets: `lampRows`, `lampCols`, `lampLeftDiag`, and `lampRightDiag`. Each set stores the row number, column number, row - column value, and row + column value of lamps, respectively.

For each query, check the presence of the queried row and column in the four sets. If any of them contains the queried row or column, the query cell is illuminated, so append 1 to the answer array, otherwise append 0.

After processing each query, iterate through the adjacent cells and remove their rows and columns from the four sets, effectively turning off the lamps.

Return the answer array containing 1s and 0s indicating illuminated and non-illuminated query cells, respectively.

## A solution in C++

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

vector<int> gridIllumination(int n, vector<vector<int>>& lamps, vector<vector<int>>& queries) {
    unordered_set<int> lampCols, lampRows, lampLeftDiag, lampRightDiag;
    vector<int> ans;

    for (auto& lamp : lamps) {
        int row = lamp[0];
        int col = lamp[1];
        lampRows.insert(row);
        lampCols.insert(col);
        lampLeftDiag.insert(row - col);
        lampRightDiag.insert(row + col);
    }

    for (auto& query : queries) {
        int row = query[0];
        int col = query[1];
        if (lampRows.count(row) || lampCols.count(col) || lampLeftDiag.count(row - col) || lampRightDiag.count(row + col)) {
            ans.push_back(1);
        } else {
            ans.push_back(0);
        }
        for (int i = -1; i <= 1; i++) {
            for (int j = -1; j <= 1; j++) {
                int newRow = row + i;
                int newCol = col + j;
                lampRows.erase(newRow);
                lampCols.erase(newCol);
                lampLeftDiag.erase(newRow - newCol);
                lampRightDiag.erase(newRow + newCol);
            }
        }
    }
    return ans;
}
```
The algorithm maintains four sets: `lampRows`, `lampCols`, `lampLeftDiag`, and `lampRightDiag`. Each set stores the row number, column number, row - column value, and row + column value of lamps, respectively.

For each query, check the presence of the queried row and column in the four sets. If any of them contains the queried row or column, the query cell is illuminated, so append 1 to the answer array, otherwise append 0.

After processing each query, iterate through the adjacent cells and remove their rows and columns from the four sets, effectively turning off the lamps.

Return the answer array containing 1s and 0s indicating illuminated and non-illuminated query cells, respectively.

## A solution in Python

```python
def grid_illumination(n, lamps, queries):
    lamp_rows = set()
    lamp_cols = set()
    lamp_left_diag = set()
    lamp_right_diag = set()

    for lamp in lamps:
        row, col = lamp
        lamp_rows.add(row)
        lamp_cols.add(col)
        lamp_left_diag.add(row - col)
        lamp_right_diag.add(row + col)

    ans = []

    for query in queries:
        row, col = query
        if row in lamp_rows or col in lamp_cols or (row - col) in lamp_left_diag or (row + col) in lamp_right_diag:
            ans.append(1)
        else:
            ans.append(0)
        for i in range(-1, 2):
            for j in range(-1, 2):
                newRow, newCol = row + i, col + j
                lamp_rows.discard(newRow)
                lamp_cols.discard(newCol)
                lamp_left_diag.discard(newRow - newCol)
                lamp_right_diag.discard(newRow + newCol)

    return ans
```
The algorithm maintains four sets: `lampRows`, `lampCols`, `lampLeftDiag`, and `lampRightDiag`. Each set stores the row number, column number, row - column value, and row + column value of lamps, respectively.

For each query, check the presence of the queried row and column in the four sets. If any of them contains the queried row or column, the query cell is illuminated, so append 1 to the answer array, otherwise append 0.

After processing each query, iterate through the adjacent cells and remove their rows and columns from the four sets, effectively turning off the lamps.

Return the answer array containing 1s and 0s indicating illuminated and non-illuminated query cells, respectively.

## A solution in Javascript

```javascript
function gridIllumination(n, lamps, queries) {
    const lampRows = new Set();
    const lampCols = new Set();
    const lampLeftDiag = new Set();
    const lampRightDiag = new Set();

    for (const lamp of lamps) {
        const [row, col] = lamp;
        lampRows.add(row);
        lampCols.add(col);
        lampLeftDiag.add(row - col);
        lampRightDiag.add(row + col);
    }

    const ans = [];

    for (const query of queries) {
        const [row, col] = query;
        if (lampRows.has(row) || lampCols.has(col) || lampLeftDiag.has(row - col) || lampRightDiag.has(row + col)) {
            ans.push(1);
        } else {
            ans.push(0);
        }
        for (let i = -1; i <= 1; i++) {
            for (let j = -1; j <= 1; j++) {
                const newRow = row + i;
                const newCol = col + j;
                lampRows.delete(newRow);
                lampCols.delete(newCol);
                lampLeftDiag.delete(newRow - newCol);
                lampRightDiag.delete(newRow + newCol);
            }
        }
    }

    return ans;
}
```
The algorithm maintains four sets: `lampRows`, `lampCols`, `lampLeftDiag`, and `lampRightDiag`. Each set stores the row number, column number, row - column value, and row + column value of lamps, respectively.

For each query, check the presence of the queried row and column in the four sets. If any of them contains the queried row or column, the query cell is illuminated, so append 1 to the answer array, otherwise append 0.

After processing each query, iterate through the adjacent cells and remove their rows and columns from the four sets, effectively turning off the lamps.

Return the answer array containing 1s and 0s indicating illuminated and non-illuminated query cells, respectively.