# Maximum Sum BST in Binary Tree

- slug: maximum-sum-bst-in-binary-tree
- difficulty: Hard

Given a **binary tree** `root`, return _the maximum sum of all keys of **any** sub-tree which is also a Binary Search Tree (BST)_.

Assume a BST is defined as follows:

*   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 = \[1,4,3,2,4,2,5,null,null,null,null,null,null,4,6\]
**Output:** 20
**Explanation:** Maximum sum in a valid Binary search tree is obtained in root node with key equal to 3.

**Example 2:**

**Input:** root = \[4,3,null,1,2\]
**Output:** 2
**Explanation:** Maximum sum in a valid Binary search tree is obtained in a single root node with key equal to 2.

**Example 3:**

**Input:** root = \[-4,-2,-5\]
**Output:** 0
**Explanation:** All values are negatives. Return an empty BST.

**Constraints:**

*   The number of nodes in the tree is in the range `[1, 4 * 104]`.
*   `-4 * 104 <= Node.val <= 4 * 104`

## A solution in Java

```java
public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

class Solution {
    int maxSum = 0;

    public int maxSumBST(TreeNode root) {
        dfs(root);
        return maxSum;
    }

    private int[] dfs(TreeNode node) {
        if (node == null)
            return new int[]{1, 0, Integer.MAX_VALUE, Integer.MIN_VALUE};

        int[] l = dfs(node.left);
        int[] r = dfs(node.right);

        if (l[0] == 0 || r[0] == 0 || node.val <= l[3] || node.val >= r[2])
            return new int[4];

        int currSum = node.val + l[1] + r[1];
        maxSum = Math.max(maxSum, currSum);

        return new int[]{1, currSum, Math.min(node.val, l[2]), Math.max(node.val, r[3])};
    }
}
```
The algorithm starts with a Depth First Search (DFS) traversal of the tree. For each node, it checks if the left and right subtree are both BSTs, and the current node's value is within the range defined by its left and right subtrees.

If the current node and its subtrees form a valid BST, we calculate the sum of the current subtree and update the maximum sum if the current sum is greater. We return an array from the `dfs()` function, where the elements at indices:

- `[0]` is 1 if it's a BST and 0 if it's not.
- `[1]` is the sum of the subtree rooted at this node.
- `[2]` is the minimum value in the subtree rooted at this node.
- `[3]` is the maximum value in the subtree rooted at this node.

As we traverse the tree from the root to the leaves, we update the maximum sum of a subtree rooted at the current node if the subtree rooted at this node is a BST. Finally, when we reach the root node, we return the (updated) maximum sum.

## A solution in C++

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

class Solution {
public:
    int maxSumBST(TreeNode* root) {
        int maxSum = 0;
        dfs(root, maxSum);
        return maxSum;
    }

private:
    array<int, 4> dfs(TreeNode* node, int &maxSum) {
        if (!node)
            return {1, 0, 1e5, -1e5};

        auto l = dfs(node->left, maxSum);
        auto r = dfs(node->right, maxSum);

        if (l[0] == 0 || r[0] == 0 || node->val <= l[3] || node->val >= r[2])
            return {0, 0, 0, 0};

        int currSum = node->val + l[1] + r[1];
        maxSum = max(maxSum, currSum);

        return {1, currSum, min(node->val, l[2]), max(node->val, r[3])};
    }
};
```
The algorithm starts with a Depth First Search (DFS) traversal of the tree. For each node, it checks if the left and right subtree are both BSTs, and the current node's value is within the range defined by its left and right subtrees.

If the current node and its subtrees form a valid BST, we calculate the sum of the current subtree and update the maximum sum if the current sum is greater. We return an array from the `dfs()` function, where the elements at indices:

- `[0]` is 1 if it's a BST and 0 if it's not.
- `[1]` is the sum of the subtree rooted at this node.
- `[2]` is the minimum value in the subtree rooted at this node.
- `[3]` is the maximum value in the subtree rooted at this node.

As we traverse the tree from the root to the leaves, we update the maximum sum of a subtree rooted at the current node if the subtree rooted at this node is a BST. Finally, when we reach the root node, we return the (updated) maximum sum.

## 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 maxSumBST(self, root: TreeNode) -> int:
        max_sum = [0]

        def dfs(node):
            if not node:
                return 1, 0, float("inf"), float("-inf")

            l = dfs(node.left)
            r = dfs(node.right)

            if not l[0] or not r[0] or node.val <= l[3] or node.val >= r[2]:
                return 0, 0, 0, 0

            curr_sum = node.val + l[1] + r[1]
            max_sum[0] = max(max_sum[0], curr_sum)

            return 1, curr_sum, min(node.val, l[2]), max(node.val, r[3])

        dfs(root)
        return max_sum[0]
```
The algorithm starts with a Depth First Search (DFS) traversal of the tree. For each node, it checks if the left and right subtree are both BSTs, and the current node's value is within the range defined by its left and right subtrees.

If the current node and its subtrees form a valid BST, we calculate the sum of the current subtree and update the maximum sum if the current sum is greater. We return an array from the `dfs()` function, where the elements at indices:

- `[0]` is 1 if it's a BST and 0 if it's not.
- `[1]` is the sum of the subtree rooted at this node.
- `[2]` is the minimum value in the subtree rooted at this node.
- `[3]` is the maximum value in the subtree rooted at this node.

As we traverse the tree from the root to the leaves, we update the maximum sum of a subtree rooted at the current node if the subtree rooted at this node is a BST. Finally, when we reach the root node, we return the (updated) maximum sum.

## A solution in Javascript

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

function maxSumBST(root) {
    let maxSum = 0;

    function dfs(node) {
        if (node === null)
            return [1, 0, Number.MAX_VALUE, Number.MIN_VALUE];

        const l = dfs(node.left);
        const r = dfs(node.right);

        if (l[0] === 0 || r[0] === 0 || node.val <= l[3] || node.val >= r[2])
            return new Array(4).fill(0);

        const currSum = node.val + l[1] + r[1];
        maxSum = Math.max(maxSum, currSum);

        return [1, currSum, Math.min(node.val, l[2]), Math.max(node.val, r[3])];
    }

    dfs(root);
    return maxSum;
}
```
The algorithm starts with a Depth First Search (DFS) traversal of the tree. For each node, it checks if the left and right subtree are both BSTs, and the current node's value is within the range defined by its left and right subtrees.

If the current node and its subtrees form a valid BST, we calculate the sum of the current subtree and update the maximum sum if the current sum is greater. We return an array from the `dfs()` function, where the elements at indices:

- `[0]` is 1 if it's a BST and 0 if it's not.
- `[1]` is the sum of the subtree rooted at this node.
- `[2]` is the minimum value in the subtree rooted at this node.
- `[3]` is the maximum value in the subtree rooted at this node.

As we traverse the tree from the root to the leaves, we update the maximum sum of a subtree rooted at the current node if the subtree rooted at this node is a BST. Finally, when we reach the root node, we return the (updated) maximum sum.


# Generate a String With Characters That Have Odd Counts

- slug: generate-a-string-with-characters-that-have-odd-counts
- difficulty: Easy

Given an integer `n`, _return a string with `n` characters such that each character in such string occurs **an odd number of times**_.

The returned string must contain only lowercase English letters. If there are multiples valid strings, return **any** of them.

**Example 1:**

**Input:** n = 4
**Output:**  "pppz "
**Explanation:**  "pppz " is a valid string since the character 'p' occurs three times and the character 'z' occurs once. Note that there are many other valid strings such as  "ohhh " and  "love ".

**Example 2:**

**Input:** n = 2
**Output:**  "xy "
**Explanation:**  "xy " is a valid string since the characters 'x' and 'y' occur once. Note that there are many other valid strings such as  "ag " and  "ur ".

**Example 3:**

**Input:** n = 7
**Output:**  "holasss "

**Constraints:**

*   `1 <= n <= 500`

## A solution in Java

```java
class Solution {
    public String generateTheString(int n) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < n - 1; i++)
            result.append('a');
        if (n % 2 == 0)
            result.append('b');
        else
            result.append('a');
        return result.toString();
    }
}
```
The algorithm to solve this problem is straightforward. We initialize the result with a single character (lowercase 'a') repeated `n` times. If the given integer `n` is even, replace the last character with a different character (lowercase 'b') to make sure that each character occurrence is odd. The resulting string contains each character an odd number of times, satisfying the problem's constraints.

## A solution in C++

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

string generateTheString(int n) {
    string result(n, 'a');
    if (n % 2 == 0)
        result[n - 1] = 'b';
    return result;
}
```
The algorithm to solve this problem is straightforward. We initialize the result with a single character (lowercase 'a') repeated `n` times. If the given integer `n` is even, replace the last character with a different character (lowercase 'b') to make sure that each character occurrence is odd. The resulting string contains each character an odd number of times, satisfying the problem's constraints.

## A solution in Python

```python
def generateTheString(n: int) -> str:
    result = 'a' * n
    if n % 2 == 0:
        result = result[:-1] + 'b'
    return result
```
The algorithm to solve this problem is straightforward. We initialize the result with a single character (lowercase 'a') repeated `n` times. If the given integer `n` is even, replace the last character with a different character (lowercase 'b') to make sure that each character occurrence is odd. The resulting string contains each character an odd number of times, satisfying the problem's constraints.

## A solution in Javascript

```javascript
function generateTheString(n) {
    let result = 'a'.repeat(n);
    if (n % 2 === 0) {
        result = result.slice(0, -1) + 'b';
    }
    return result;
}
```
The algorithm to solve this problem is straightforward. We initialize the result with a single character (lowercase 'a') repeated `n` times. If the given integer `n` is even, replace the last character with a different character (lowercase 'b') to make sure that each character occurrence is odd. The resulting string contains each character an odd number of times, satisfying the problem's constraints.


# Number of Times Binary String Is Prefix-Aligned

- slug: number-of-times-binary-string-is-prefix-aligned
- difficulty: Medium

You have a **1-indexed** binary string of length `n` where all the bits are `0` initially. We will flip all the bits of this binary string (i.e., change them from `0` to `1`) one by one. You are given a **1-indexed** integer array `flips` where `flips[i]` indicates that the bit at index `i` will be flipped in the `ith` step.

A binary string is **prefix-aligned** if, after the `ith` step, all the bits in the **inclusive** range `[1, i]` are ones and all the other bits are zeros.

Return _the number of times the binary string is **prefix-aligned** during the flipping process_.

**Example 1:**

**Input:** flips = \[3,2,4,1,5\]
**Output:** 2
**Explanation:** The binary string is initially  "00000 ".
After applying step 1: The string becomes  "00100 ", which is not prefix-aligned.
After applying step 2: The string becomes  "01100 ", which is not prefix-aligned.
After applying step 3: The string becomes  "01110 ", which is not prefix-aligned.
After applying step 4: The string becomes  "11110 ", which is prefix-aligned.
After applying step 5: The string becomes  "11111 ", which is prefix-aligned.
We can see that the string was prefix-aligned 2 times, so we return 2.

**Example 2:**

**Input:** flips = \[4,1,2,3\]
**Output:** 1
**Explanation:** The binary string is initially  "0000 ".
After applying step 1: The string becomes  "0001 ", which is not prefix-aligned.
After applying step 2: The string becomes  "1001 ", which is not prefix-aligned.
After applying step 3: The string becomes  "1101 ", which is not prefix-aligned.
After applying step 4: The string becomes  "1111 ", which is prefix-aligned.
We can see that the string was prefix-aligned 1 time, so we return 1.

**Constraints:**

*   `n == flips.length`
*   `1 <= n <= 5 * 104`
*   `flips` is a permutation of the integers in the range `[1, n]`.

## A solution in Java

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

public int findKthPalindrome(int k, int intLength) {
    int mid = (intLength + 1) / 2;
    int limit = (int) Math.pow(10, mid) - 1;

    for (int i = 0; i <= limit; i++) {
        String num = Integer.toString(i);
        String rev = new StringBuilder(num).reverse().toString();
        if (intLength % 2 != 0)
            rev = rev.substring(1);
        num += rev;
        int palindrome = Integer.parseInt(num);
        if (palindrome > 0)
            k--;
        if (k == 0)
            return palindrome;
    }
    return -1;
}

public List<Integer> palindromeQueries(List<Integer> queries, int intLength) {
    List<Integer> answer = new ArrayList<>();
    for (int query : queries) {
        answer.add(findKthPalindrome(query, intLength));
    }
    return answer;
}
```
The algorithm consists of two functions, `findKthPalindrome` and `palindrome_queries`.

`findKthPalindrome` function receives two parameters – k and intLength. The function calculates the middle part's (`mid`) length of the palindrome number using half of the given `intLength`. Next, calculates the limit of the iteration by raising 10 to the power of mid and subtracting 1 from the result.

The function iterates from 0 to this calculated limit. For each number in the iteration, a possible palindrome number is generated by concatenating the reverse of the string representation of the number. If the desired intLength has an odd length, exclude the first digit from the reversed part.

The generated palindrome number is checked to be greater than zero. If it's a positive palindrome, decrement k. When k reaches 0, the generated number is the k-th palindrome of the given length, and return the palindrome number. If k never reaches 0 in the iteration, return -1.

`palindrome_queries` function takes two parameters: a list/array of queries and intLength. The function maps `findKthPalindrome` function on each element of the queries array/list, so every ith element in the returned list/array has the queries[i]th smallest positive palindrome of length intLength or -1 if no such palindrome exists.

## A solution in C++

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

int findKthPalindrome(int k, int intLength) {
    int mid = (intLength + 1) / 2;
    int limit = pow(10, mid) - 1;

    for (int i = 0; i <= limit; i++) {
        std::string num = std::to_string(i);
        std::string rev(num.rbegin(), num.rend());
        if (intLength % 2 != 0)
            rev = rev.substr(1);
        num += rev;
        int palindrome = stoi(num);
        if (palindrome > 0)
            k--;
        if (k == 0)
            return palindrome;
    }
    return -1;
}

std::vector<int> palindromeQueries(std::vector<int> queries, int intLength) {
    std::vector<int> answer;
    for (int query : queries) {
        answer.push_back(findKthPalindrome(query, intLength));
    }
    return answer;
}
```
The algorithm consists of two functions, `findKthPalindrome` and `palindrome_queries`.

`findKthPalindrome` function receives two parameters – k and intLength. The function calculates the middle part's (`mid`) length of the palindrome number using half of the given `intLength`. Next, calculates the limit of the iteration by raising 10 to the power of mid and subtracting 1 from the result.

The function iterates from 0 to this calculated limit. For each number in the iteration, a possible palindrome number is generated by concatenating the reverse of the string representation of the number. If the desired intLength has an odd length, exclude the first digit from the reversed part.

The generated palindrome number is checked to be greater than zero. If it's a positive palindrome, decrement k. When k reaches 0, the generated number is the k-th palindrome of the given length, and return the palindrome number. If k never reaches 0 in the iteration, return -1.

`palindrome_queries` function takes two parameters: a list/array of queries and intLength. The function maps `findKthPalindrome` function on each element of the queries array/list, so every ith element in the returned list/array has the queries[i]th smallest positive palindrome of length intLength or -1 if no such palindrome exists.

## A solution in Python

```python
def find_kth_palindrome(k, int_length):
    mid = (int_length + 1) // 2
    limit = 10 ** mid - 1

    i = 0
    while i <= limit:
        num = str(i)
        rev = num[::-1]
        if int_length % 2 != 0:
            rev = rev[1:]
        palindrome = int(num + rev)
        if palindrome > 0:
            k -= 1
        if k == 0:
            return palindrome
        i += 1
    return -1

def palindrome_queries(queries, int_length):
    return [find_kth_palindrome(query, int_length) for query in queries]
```
The algorithm consists of two functions, `findKthPalindrome` and `palindrome_queries`.

`findKthPalindrome` function receives two parameters – k and intLength. The function calculates the middle part's (`mid`) length of the palindrome number using half of the given `intLength`. Next, calculates the limit of the iteration by raising 10 to the power of mid and subtracting 1 from the result.

The function iterates from 0 to this calculated limit. For each number in the iteration, a possible palindrome number is generated by concatenating the reverse of the string representation of the number. If the desired intLength has an odd length, exclude the first digit from the reversed part.

The generated palindrome number is checked to be greater than zero. If it's a positive palindrome, decrement k. When k reaches 0, the generated number is the k-th palindrome of the given length, and return the palindrome number. If k never reaches 0 in the iteration, return -1.

`palindrome_queries` function takes two parameters: a list/array of queries and intLength. The function maps `findKthPalindrome` function on each element of the queries array/list, so every ith element in the returned list/array has the queries[i]th smallest positive palindrome of length intLength or -1 if no such palindrome exists.

## A solution in Javascript

```javascript
function findKthPalindrome(k, intLength) {
    let mid = Math.floor((intLength + 1) / 2);
    let limit = Math.pow(10, mid) - 1;

    for (let i = 0; i <= limit; i++) {
        let num = i.toString();
        let rev = num.split('').reverse().join('');
        if (intLength % 2 !== 0)
            rev = rev.slice(1);
        let palindrome = parseInt(num + rev);
        if (palindrome > 0)
            k--;
        if (k === 0)
            return palindrome;
    }
    return -1;
}

function palindromeQueries(queries, intLength) {
    return queries.map(query => findKthPalindrome(query, intLength));
}
```
The algorithm consists of two functions, `findKthPalindrome` and `palindrome_queries`.

`findKthPalindrome` function receives two parameters – k and intLength. The function calculates the middle part's (`mid`) length of the palindrome number using half of the given `intLength`. Next, calculates the limit of the iteration by raising 10 to the power of mid and subtracting 1 from the result.

The function iterates from 0 to this calculated limit. For each number in the iteration, a possible palindrome number is generated by concatenating the reverse of the string representation of the number. If the desired intLength has an odd length, exclude the first digit from the reversed part.

The generated palindrome number is checked to be greater than zero. If it's a positive palindrome, decrement k. When k reaches 0, the generated number is the k-th palindrome of the given length, and return the palindrome number. If k never reaches 0 in the iteration, return -1.

`palindrome_queries` function takes two parameters: a list/array of queries and intLength. The function maps `findKthPalindrome` function on each element of the queries array/list, so every ith element in the returned list/array has the queries[i]th smallest positive palindrome of length intLength or -1 if no such palindrome exists.


# Time Needed to Inform All Employees

- slug: time-needed-to-inform-all-employees
- difficulty: Medium

A company has `n` employees with a unique ID for each employee from `0` to `n - 1`. The head of the company is the one with `headID`.

Each employee has one direct manager given in the `manager` array where `manager[i]` is the direct manager of the `i-th` employee, `manager[headID] = -1`. Also, it is guaranteed that the subordination relationships have a tree structure.

The head of the company wants to inform all the company employees of an urgent piece of news. He will inform his direct subordinates, and they will inform their subordinates, and so on until all employees know about the urgent news.

The `i-th` employee needs `informTime[i]` minutes to inform all of his direct subordinates (i.e., After informTime\[i\] minutes, all his direct subordinates can start spreading the news).

Return _the number of minutes_ needed to inform all the employees about the urgent news.

**Example 1:**

**Input:** n = 1, headID = 0, manager = \[-1\], informTime = \[0\]
**Output:** 0
**Explanation:** The head of the company is the only employee in the company.

**Example 2:**

**Input:** n = 6, headID = 2, manager = \[2,2,-1,2,2,2\], informTime = \[0,0,1,0,0,0\]
**Output:** 1
**Explanation:** The head of the company with id = 2 is the direct manager of all the employees in the company and needs 1 minute to inform them all.
The tree structure of the employees in the company is shown.

**Constraints:**

*   `1 <= n <= 105`
*   `0 <= headID < n`
*   `manager.length == n`
*   `0 <= manager[i] < n`
*   `manager[headID] == -1`
*   `informTime.length == n`
*   `0 <= informTime[i] <= 1000`
*   `informTime[i] == 0` if employee `i` has no subordinates.
*   It is **guaranteed** that all the employees can be informed.

## A solution in Java

```java
public int numOfMinutes(int n, int headID, int[] manager, int[] informTime) {
    List<List<Integer>> subordinates = new ArrayList<>();
    for (int i = 0; i < n; ++i) {
        subordinates.add(new ArrayList<>());
    }
    for (int i = 0; i < n; ++i) {
        if (manager[i] != -1) {
            subordinates.get(manager[i]).add(i);
        }
    }
    return dfs(headID, subordinates, informTime);
}

private int dfs(int employee, List<List<Integer>> subordinates, int[] informTime) {
    if (informTime[employee] == 0) {
        return 0;
    }
    int max_time = 0;
    for (int i : subordinates.get(employee)) {
        max_time = Math.max(max_time, dfs(i, subordinates, informTime));
    }
    return max_time + informTime[employee];
}
```
The algorithm first builds a data structure (adjacency list) to represent the tree of subordinates, and then performs a depth-first search from the headID to find the maximum time taken to inform all employees. In each step of the DFS, it iterates through the direct subordinates of the current employee and calculates the time required for that employee to inform everyone. The maximum time from all possible subordinates is added to the current employee's informTime and returned. This continues recursively until the entire organization is processed.

## A solution in C++

```cpp
int numOfMinutes(int n, int headID, vector<int>& manager, vector<int>& informTime) {
    vector<vector<int>> subordinates(n);
    for (int i = 0; i < n; ++i) {
        if (manager[i] != -1) {
            subordinates[manager[i]].push_back(i);
        }
    }
    return dfs(headID, subordinates, informTime);
}

int dfs(int employee, vector<vector<int>>& subordinates, vector<int>& informTime) {
    if (informTime[employee] == 0) {
        return 0;
    }
    int max_time = 0;
    for (int i : subordinates[employee]) {
        max_time = max(max_time, dfs(i, subordinates, informTime));
    }
    return max_time + informTime[employee];
}
```
The algorithm first builds a data structure (adjacency list) to represent the tree of subordinates, and then performs a depth-first search from the headID to find the maximum time taken to inform all employees. In each step of the DFS, it iterates through the direct subordinates of the current employee and calculates the time required for that employee to inform everyone. The maximum time from all possible subordinates is added to the current employee's informTime and returned. This continues recursively until the entire organization is processed.

## A solution in Python

```python
def numOfMinutes(n, headID, manager, informTime):
    subordinates = [[] for _ in range(n)]
    for i in range(n):
        if manager[i] != -1:
            subordinates[manager[i]].append(i)
    return dfs(headID, subordinates, informTime)

def dfs(employee, subordinates, informTime):
    if informTime[employee] == 0:
        return 0
    max_time = 0
    for i in subordinates[employee]:
        max_time = max(max_time, dfs(i, subordinates, informTime))
    return max_time + informTime[employee]
```
The algorithm first builds a data structure (adjacency list) to represent the tree of subordinates, and then performs a depth-first search from the headID to find the maximum time taken to inform all employees. In each step of the DFS, it iterates through the direct subordinates of the current employee and calculates the time required for that employee to inform everyone. The maximum time from all possible subordinates is added to the current employee's informTime and returned. This continues recursively until the entire organization is processed.

## A solution in Javascript

```javascript
function numOfMinutes(n, headID, manager, informTime) {
    const subordinates = Array.from({length: n}, () => []);
    for (let i = 0; i < n; ++i) {
        if (manager[i] !== -1) {
            subordinates[manager[i]].push(i);
        }
    }
    return dfs(headID, subordinates, informTime);
}

function dfs(employee, subordinates, informTime) {
    if (informTime[employee] === 0) {
        return 0;
    }
    let max_time = 0;
    for (const i of subordinates[employee]) {
        max_time = Math.max(max_time, dfs(i, subordinates, informTime));
    }
    return max_time + informTime[employee];
}
```
The algorithm first builds a data structure (adjacency list) to represent the tree of subordinates, and then performs a depth-first search from the headID to find the maximum time taken to inform all employees. In each step of the DFS, it iterates through the direct subordinates of the current employee and calculates the time required for that employee to inform everyone. The maximum time from all possible subordinates is added to the current employee's informTime and returned. This continues recursively until the entire organization is processed.


# Frog Position After T Seconds

- slug: frog-position-after-t-seconds
- difficulty: Hard

Given an undirected tree consisting of `n` vertices numbered from `1` to `n`. A frog starts jumping from **vertex 1**. In one second, the frog jumps from its current vertex to another **unvisited** vertex if they are directly connected. The frog can not jump back to a visited vertex. In case the frog can jump to several vertices, it jumps randomly to one of them with the same probability. Otherwise, when the frog can not jump to any unvisited vertex, it jumps forever on the same vertex.

The edges of the undirected tree are given in the array `edges`, where `edges[i] = [ai, bi]` means that exists an edge connecting the vertices `ai` and `bi`.

_Return the probability that after `t` seconds the frog is on the vertex `target`._ Answers within `10-5` of the actual answer will be accepted.

**Example 1:**

**Input:** n = 7, edges = \[\[1,2\],\[1,3\],\[1,7\],\[2,4\],\[2,6\],\[3,5\]\], t = 2, target = 4
**Output:** 0.16666666666666666
**Explanation:** The figure above shows the given graph. The frog starts at vertex 1, jumping with 1/3 probability to the vertex 2 after **second 1** and then jumping with 1/2 probability to vertex 4 after **second 2**. Thus the probability for the frog is on the vertex 4 after 2 seconds is 1/3 \* 1/2 = 1/6 = 0.16666666666666666.

**Example 2:**

**Input:** n = 7, edges = \[\[1,2\],\[1,3\],\[1,7\],\[2,4\],\[2,6\],\[3,5\]\], t = 1, target = 7
**Output:** 0.3333333333333333
**Explanation:** The figure above shows the given graph. The frog starts at vertex 1, jumping with 1/3 = 0.3333333333333333 probability to the vertex 7 after **second 1**.

**Constraints:**

*   `1 <= n <= 100`
*   `edges.length == n - 1`
*   `edges[i].length == 2`
*   `1 <= ai, bi <= n`
*   `1 <= t <= 50`
*   `1 <= target <= n`

## A solution in Java

```java
import java.util.*;

class Solution {
    public void dfs(int node, int parent, int t, int target, List<List<Integer>> graph, double prob, double[] ans) {
        if (t == 0) {
            if(node == target) ans[0] += prob;
            return;
        }

        boolean has_child = false;
        for(Integer child : graph.get(node)) {
            if(child != parent) {
                has_child = true;
                dfs(child, node, t - 1, target, graph, prob / (graph.get(node).size() - (node != 1 ? 1 : 0)), ans);
            }
        }

        if(!has_child && node == target) ans[0] += prob;
    }

    public double frogPosition(int n, int[][] edges, int t, int target) {
        List<List<Integer>> graph = new ArrayList<>();
        for (int i = 0; i <= n; ++i) {
            graph.add(new ArrayList<Integer>());
        }
        for (int i = 0; i < n - 1; ++i) {
            int a = edges[i][0], b = edges[i][1];
            graph.get(a).add(b);
            graph.get(b).add(a);
        }

        double[] ans = {0.0};
        dfs(1, -1, t, target, graph, 1.0, ans);
        return ans[0];
    }
}
```
The problem can be solved using Depth First Search (DFS). The basic idea is to traverse the tree using DFS starting from the vertex 1 with a probability of 1.0. During the traversal, at each visited vertex we calculate the probability that the frog reaches the current vertex. To do this, we maintain the probability of the current subtree traversal, and at each step we update this probability by dividing it by the number of unvisited neighbor vertices (excluding the parent vertex of the current vertex).

We continue the traversal for t seconds. At each step, if the traversal time (t) is zero or the frog reaches the target vertex, we store the probability of reaching the target vertex into the answer.

Upon completion of the DFS traversal, we return the final answer, which is the probability of the frog being on the vertex target after t seconds.

## A solution in C++

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

void dfs(int node, int parent, int t, int target, vector<vector<int>>& graph, double prob, vector<double>& ans) {
    if (t == 0) {
        if(node == target) ans[0] += prob;
        return;
    }

    bool has_child = false;
    for(int i = 0; i < graph[node].size(); ++i) {
        if(graph[node][i] != parent) {
            has_child = true;
            dfs(graph[node][i], node, t - 1, target, graph, prob / (graph[node].size() - (node != 1)), ans);
        }
    }

    if(!has_child && node == target) ans[0] += prob;
}

double frogPosition(int n, vector<vector<int>>& edges, int t, int target) {
    vector<vector<int>> graph(n + 1);
    for (int i = 0; i < n - 1; ++i) {
        int a = edges[i][0], b = edges[i][1];
        graph[a].push_back(b);
        graph[b].push_back(a);
    }

    vector<double> ans(1, 0.0);
    dfs(1, -1, t, target, graph, 1.0, ans);
    return ans[0];
}
```
The problem can be solved using Depth First Search (DFS). The basic idea is to traverse the tree using DFS starting from the vertex 1 with a probability of 1.0. During the traversal, at each visited vertex we calculate the probability that the frog reaches the current vertex. To do this, we maintain the probability of the current subtree traversal, and at each step we update this probability by dividing it by the number of unvisited neighbor vertices (excluding the parent vertex of the current vertex).

We continue the traversal for t seconds. At each step, if the traversal time (t) is zero or the frog reaches the target vertex, we store the probability of reaching the target vertex into the answer.

Upon completion of the DFS traversal, we return the final answer, which is the probability of the frog being on the vertex target after t seconds.

## A solution in Python

```python
from collections import defaultdict

def dfs(node, parent, t, target, graph, prob, ans):
    if t == 0:
        if node == target:
            ans[0] += prob
        return

    has_child = False
    for neighbor in graph[node]:
        if neighbor != parent:
            has_child = True
            dfs(neighbor, node, t - 1, target, graph, prob / (len(graph[node]) - (1 if node != 1 else 0)), ans)

    if not has_child and node == target:
        ans[0] += prob

def frogPosition(n, edges, t, target):
    graph = defaultdict(list)
    for a, b in edges:
        graph[a].append(b)
        graph[b].append(a)

    ans = [0.0]
    dfs(1, -1, t, target, graph, 1.0, ans)
    return ans[0]
```
The problem can be solved using Depth First Search (DFS). The basic idea is to traverse the tree using DFS starting from the vertex 1 with a probability of 1.0. During the traversal, at each visited vertex we calculate the probability that the frog reaches the current vertex. To do this, we maintain the probability of the current subtree traversal, and at each step we update this probability by dividing it by the number of unvisited neighbor vertices (excluding the parent vertex of the current vertex).

We continue the traversal for t seconds. At each step, if the traversal time (t) is zero or the frog reaches the target vertex, we store the probability of reaching the target vertex into the answer.

Upon completion of the DFS traversal, we return the final answer, which is the probability of the frog being on the vertex target after t seconds.

## A solution in Javascript

```javascript
function dfs(node, parent, t, target, graph, prob, ans) {
    if (t === 0) {
        if (node === target) ans[0] += prob;
        return;
    }

    let hasChild = false;
    for (let neighbor of graph[node]) {
        if (neighbor !== parent) {
            hasChild = true;
            dfs(neighbor, node, t - 1, target, graph, prob / (graph[node].length - (node !== 1 ? 1 : 0)), ans);
        }
    }

    if (!hasChild && node === target) ans[0] += prob;
}

function frogPosition(n, edges, t, target) {
    const graph = new Map();
    for (let i = 1; i <= n; ++i) {
        graph.set(i, []);
    }
    for (let i = 0; i < n - 1; ++i) {
        const a = edges[i][0],
              b = edges[i][1];
        graph.get(a).push(b);
        graph.get(b).push(a);
    }

    const ans = [0.0];
    dfs(1, -1, t, target, graph, 1.0, ans);
    return ans[0];
}
```
The problem can be solved using Depth First Search (DFS). The basic idea is to traverse the tree using DFS starting from the vertex 1 with a probability of 1.0. During the traversal, at each visited vertex we calculate the probability that the frog reaches the current vertex. To do this, we maintain the probability of the current subtree traversal, and at each step we update this probability by dividing it by the number of unvisited neighbor vertices (excluding the parent vertex of the current vertex).

We continue the traversal for t seconds. At each step, if the traversal time (t) is zero or the frog reaches the target vertex, we store the probability of reaching the target vertex into the answer.

Upon completion of the DFS traversal, we return the final answer, which is the probability of the frog being on the vertex target after t seconds.


# Find a Corresponding Node of a Binary Tree in a Clone of That Tree

- slug: find-a-corresponding-node-of-a-binary-tree-in-a-clone-of-that-tree
- difficulty: Easy

Given two binary trees `original` and `cloned` and given a reference to a node `target` in the original tree.

The `cloned` tree is a **copy of** the `original` tree.

Return _a reference to the same node_ in the `cloned` tree.

**Note** that you are **not allowed** to change any of the two trees or the `target` node and the answer **must be** a reference to a node in the `cloned` tree.

**Example 1:**

**Input:** tree = \[7,4,3,null,null,6,19\], target = 3
**Output:** 3
**Explanation:** In all examples the original and cloned trees are shown. The target node is a green node from the original tree. The answer is the yellow node from the cloned tree.

**Example 2:**

**Input:** tree = \[7\], target =  7
**Output:** 7

**Example 3:**

**Input:** tree = \[8,null,6,null,5,null,4,null,3,null,2,null,1\], target = 4
**Output:** 4

**Constraints:**

*   The number of nodes in the `tree` is in the range `[1, 104]`.
*   The values of the nodes of the `tree` are unique.
*   `target` node is a node from the `original` tree and is not `null`.

**Follow up:** Could you solve the problem if repeated values on the tree are allowed?

## A solution in Java

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

public int[][] reconstructMatrix(int upper, int lower, int[] colsum) {
    int[][] result = new int[2][colsum.length];

    for (int i = 0; i < colsum.length; i++) {
        if (colsum[i] == 2) {
            result[0][i] = 1;
            result[1][i] = 1;
            upper--;
            lower--;
        } else if (colsum[i] == 1) {
            if (upper > lower) {
                result[0][i] = 1;
                upper--;
            } else {
                result[1][i] = 1;
                lower--;
            }
        }

        if (upper < 0 || lower < 0) {
            return new int[][]{};
        }
    }

    if (upper > 0 || lower > 0) {
        return new int[][]{};
    }

    return result;
}
```
First, initialize an empty 2D array with 2 rows and "n" columns, where "n" is the length of the `colsum` array.

Iterate through the `colsum` array, and for each element:
1. If the element is equal to 2, set both the upper row and lower row values to 1, and decrement both `upper` and `lower`.
2. If the element is equal to 1, check if `upper` is greater than `lower`. If so, set the value in the upper row to 1 and decrement `upper`, otherwise set the value in the lower row to 1 and decrement `lower`.

At any point, if either `upper` or `lower` becomes negative, return an empty array as there is no valid solution.

Finally, if either `upper` or `lower` is still greater than 0, return an empty array as there is no valid solution. Otherwise, return the reconstructed 2D array.

## A solution in C++

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

vector<vector<int>> reconstructMatrix(int upper, int lower, vector<int>& colsum) {
    vector<vector<int>> result(2, vector<int>(colsum.size(), 0));

    for (int i = 0; i < colsum.size(); i++) {
        if (colsum[i] == 2) {
            result[0][i] = 1;
            result[1][i] = 1;
            upper--;
            lower--;
        } else if (colsum[i] == 1) {
            if (upper > lower) {
                result[0][i] = 1;
                upper--;
            } else {
                result[1][i] = 1;
                lower--;
            }
        }

        if (upper < 0 || lower < 0) {
            return {};
        }
    }

    if (upper > 0 || lower > 0) {
        return {};
    }

    return result;
}
```
First, initialize an empty 2D array with 2 rows and "n" columns, where "n" is the length of the `colsum` array.

Iterate through the `colsum` array, and for each element:
1. If the element is equal to 2, set both the upper row and lower row values to 1, and decrement both `upper` and `lower`.
2. If the element is equal to 1, check if `upper` is greater than `lower`. If so, set the value in the upper row to 1 and decrement `upper`, otherwise set the value in the lower row to 1 and decrement `lower`.

At any point, if either `upper` or `lower` becomes negative, return an empty array as there is no valid solution.

Finally, if either `upper` or `lower` is still greater than 0, return an empty array as there is no valid solution. Otherwise, return the reconstructed 2D array.

## A solution in Python

```python
def reconstructMatrix(upper, lower, colsum):
    result = [[0] * len(colsum) for _ in range(2)]

    for i in range(len(colsum)):
        if colsum[i] == 2:
            result[0][i] = 1
            result[1][i] = 1
            upper -= 1
            lower -= 1
        elif colsum[i] == 1:
            if upper > lower:
                result[0][i] = 1
                upper -= 1
            else:
                result[1][i] = 1
                lower -= 1

        if upper < 0 or lower < 0:
            return []

    if upper > 0 or lower > 0:
        return []

    return result
```
First, initialize an empty 2D array with 2 rows and "n" columns, where "n" is the length of the `colsum` array.

Iterate through the `colsum` array, and for each element:
1. If the element is equal to 2, set both the upper row and lower row values to 1, and decrement both `upper` and `lower`.
2. If the element is equal to 1, check if `upper` is greater than `lower`. If so, set the value in the upper row to 1 and decrement `upper`, otherwise set the value in the lower row to 1 and decrement `lower`.

At any point, if either `upper` or `lower` becomes negative, return an empty array as there is no valid solution.

Finally, if either `upper` or `lower` is still greater than 0, return an empty array as there is no valid solution. Otherwise, return the reconstructed 2D array.

## A solution in Javascript

```javascript
function reconstructMatrix(upper, lower, colsum) {
    const result = Array.from({length: 2}, () => Array(colsum.length).fill(0));

    for (let i = 0; i < colsum.length; i++) {
        if (colsum[i] === 2) {
            result[0][i] = 1;
            result[1][i] = 1;
            upper--;
            lower--;
        } else if (colsum[i] === 1) {
            if (upper > lower) {
                result[0][i] = 1;
                upper--;
            } else {
                result[1][i] = 1;
                lower--;
            }
        }

        if (upper < 0 || lower < 0) {
            return [];
        }
    }

    if (upper > 0 || lower > 0) {
        return [];
    }

    return result;
}
```
First, initialize an empty 2D array with 2 rows and "n" columns, where "n" is the length of the `colsum` array.

Iterate through the `colsum` array, and for each element:
1. If the element is equal to 2, set both the upper row and lower row values to 1, and decrement both `upper` and `lower`.
2. If the element is equal to 1, check if `upper` is greater than `lower`. If so, set the value in the upper row to 1 and decrement `upper`, otherwise set the value in the lower row to 1 and decrement `lower`.

At any point, if either `upper` or `lower` becomes negative, return an empty array as there is no valid solution.

Finally, if either `upper` or `lower` is still greater than 0, return an empty array as there is no valid solution. Otherwise, return the reconstructed 2D array.


# Lucky Numbers in a Matrix

- slug: lucky-numbers-in-a-matrix
- difficulty: Easy

Given an `m x n` matrix of **distinct** numbers, return _all **lucky numbers** in the matrix in **any** order_.

A **lucky number** is an element of the matrix such that it is the minimum element in its row and maximum in its column.

**Example 1:**

**Input:** matrix = \[\[3,7,8\],\[9,11,13\],\[15,16,17\]\]
**Output:** \[15\]
**Explanation:** 15 is the only lucky number since it is the minimum in its row and the maximum in its column.

**Example 2:**

**Input:** matrix = \[\[1,10,4,2\],\[9,3,8,7\],\[15,16,17,12\]\]
**Output:** \[12\]
**Explanation:** 12 is the only lucky number since it is the minimum in its row and the maximum in its column.

**Example 3:**

**Input:** matrix = \[\[7,8\],\[1,2\]\]
**Output:** \[7\]
**Explanation:** 7 is the only lucky number since it is the minimum in its row and the maximum in its column.

**Constraints:**

*   `m == mat.length`
*   `n == mat[i].length`
*   `1 <= n, m <= 50`
*   `1 <= matrix[i][j] <= 105`.
*   All elements in the matrix are distinct.

## A solution in Java

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

void dfs(int[][] grid, int x, int y) {
    int n = grid.length, m = grid[0].length;
    grid[x][y] = 1;
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i], ny = y + dy[i];
        if (nx >= 0 && nx < n && ny >= 0 && ny < m && grid[nx][ny] == 0) {
            dfs(grid, nx, ny);
        }
    }
}

public int closedIsland(int[][] grid) {
    int n = grid.length, m = grid[0].length;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (i == 0 || i == n - 1 || j == 0 || j == m - 1) {
                if (grid[i][j] == 0) {
                    dfs(grid, i, j);
                }
            }
        }
    }
    int res = 0;
    for (int i = 1; i < n - 1; i++) {
        for (int j = 1; j < m - 1; j++) {
            if (grid[i][j] == 0) {
                dfs(grid, i, j);
                res++;
            }
        }
    }
    return res;
}
```
1. First, create a DFS function that traverses the grid and marks 0s as 1s if they are part of an island.
2. For each cell in the border of the grid, if it's a 0, use the DFS function to mark all border-connected islands (removing them from consideration).
3. Traverse the inner cells of the grid (excluding outer border cells) and use DFS to find closed islands by marking connected 0s as 1s. Increment the result counter for each closed island found.
4. Return the result (number of closed islands).

## A solution in C++

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

void dfs(vector<vector<int>>& grid, int x, int y) {
    int n = grid.size(), m = grid[0].size();
    grid[x][y] = 1;
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i], ny = y + dy[i];
        if (nx >= 0 && nx < n && ny >= 0 && ny < m && grid[nx][ny] == 0) {
            dfs(grid, nx, ny);
        }
    }
}

int closedIsland(vector<vector<int>>& grid) {
    int n = grid.size(), m = grid[0].size();
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (i == 0 || i == n - 1 || j == 0 || j == m - 1) {
                if (grid[i][j] == 0) {
                    dfs(grid, i, j);
                }
            }
        }
    }
    int res = 0;
    for (int i = 1; i < n - 1; i++) {
        for (int j = 1; j < m - 1; j++) {
            if (grid[i][j] == 0) {
                dfs(grid, i, j);
                res++;
            }
        }
    }
    return res;
}
```
1. First, create a DFS function that traverses the grid and marks 0s as 1s if they are part of an island.
2. For each cell in the border of the grid, if it's a 0, use the DFS function to mark all border-connected islands (removing them from consideration).
3. Traverse the inner cells of the grid (excluding outer border cells) and use DFS to find closed islands by marking connected 0s as 1s. Increment the result counter for each closed island found.
4. Return the result (number of closed islands).

## A solution in Python

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

def dfs(grid, x, y):
    n, m = len(grid), len(grid[0])
    grid[x][y] = 1
    for i in range(4):
        nx, ny = x + dx[i], y + dy[i]
        if 0 <= nx < n and 0 <= ny < m and grid[nx][ny] == 0:
            dfs(grid, nx, ny)

def closedIsland(grid):
    n, m = len(grid), len(grid[0])
    for i in range(n):
        for j in range(m):
            if i == 0 or i == n - 1 or j == 0 or j == m - 1:
                if grid[i][j] == 0:
                    dfs(grid, i, j)
    res = 0
    for i in range(1, n - 1):
        for j in range(1, m - 1):
            if grid[i][j] == 0:
                dfs(grid, i, j)
                res += 1
    return res
```
1. First, create a DFS function that traverses the grid and marks 0s as 1s if they are part of an island.
2. For each cell in the border of the grid, if it's a 0, use the DFS function to mark all border-connected islands (removing them from consideration).
3. Traverse the inner cells of the grid (excluding outer border cells) and use DFS to find closed islands by marking connected 0s as 1s. Increment the result counter for each closed island found.
4. Return the result (number of closed islands).

## A solution in Javascript

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

function dfs(grid, x, y) {
    const n = grid.length, m = grid[0].length;
    grid[x][y] = 1;
    for (let i = 0; i < 4; i++) {
        const nx = x + dx[i], ny = y + dy[i];
        if (0 <= nx && nx < n && 0 <= ny && ny < m && grid[nx][ny] === 0) {
            dfs(grid, nx, ny);
        }
    }
}

function closedIsland(grid) {
    const n = grid.length, m = grid[0].length;
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {
            if (i === 0 || i === n - 1 || j === 0 || j === m - 1) {
                if (grid[i][j] === 0) {
                    dfs(grid, i, j);
                }
            }
        }
    }
    let res = 0;
    for (let i = 1; i < n - 1; i++) {
        for (let j = 1; j < m - 1; j++) {
            if (grid[i][j] === 0) {
                dfs(grid, i, j);
                res++;
            }
        }
    }
    return res;
}
```
1. First, create a DFS function that traverses the grid and marks 0s as 1s if they are part of an island.
2. For each cell in the border of the grid, if it's a 0, use the DFS function to mark all border-connected islands (removing them from consideration).
3. Traverse the inner cells of the grid (excluding outer border cells) and use DFS to find closed islands by marking connected 0s as 1s. Increment the result counter for each closed island found.
4. Return the result (number of closed islands).


# Design a Stack With Increment Operation

- slug: design-a-stack-with-increment-operation
- difficulty: Medium

Design a stack that supports increment operations on its elements.

Implement the `CustomStack` class:

*   `CustomStack(int maxSize)` Initializes the object with `maxSize` which is the maximum number of elements in the stack.
*   `void push(int x)` Adds `x` to the top of the stack if the stack has not reached the `maxSize`.
*   `int pop()` Pops and returns the top of the stack or `-1` if the stack is empty.
*   `void inc(int k, int val)` Increments the bottom `k` elements of the stack by `val`. If there are less than `k` elements in the stack, increment all the elements in the stack.

**Example 1:**

**Input**
\[ "CustomStack ", "push ", "push ", "pop ", "push ", "push ", "push ", "increment ", "increment ", "pop ", "pop ", "pop ", "pop "\]
\[\[3\],\[1\],\[2\],\[\],\[2\],\[3\],\[4\],\[5,100\],\[2,100\],\[\],\[\],\[\],\[\]\]
**Output**
\[null,null,null,2,null,null,null,null,null,103,202,201,-1\]
**Explanation**
CustomStack stk = new CustomStack(3); // Stack is Empty \[\]
stk.push(1);                          // stack becomes \[1\]
stk.push(2);                          // stack becomes \[1, 2\]
stk.pop();                            // return 2 --> Return top of the stack 2, stack becomes \[1\]
stk.push(2);                          // stack becomes \[1, 2\]
stk.push(3);                          // stack becomes \[1, 2, 3\]
stk.push(4);                          // stack still \[1, 2, 3\], Do not add another elements as size is 4
stk.increment(5, 100);                // stack becomes \[101, 102, 103\]
stk.increment(2, 100);                // stack becomes \[201, 202, 103\]
stk.pop();                            // return 103 --> Return top of the stack 103, stack becomes \[201, 202\]
stk.pop();                            // return 202 --> Return top of the stack 202, stack becomes \[201\]
stk.pop();                            // return 201 --> Return top of the stack 201, stack becomes \[\]
stk.pop();                            // return -1 --> Stack is empty return -1.

**Constraints:**

*   `1 <= maxSize, x, k <= 1000`
*   `0 <= val <= 100`
*   At most `1000` calls will be made to each method of `increment`, `push` and `pop` each separately.

## A solution in Java

```java
import java.util.*;

public int getMaxScore(String word, int[] score) {
    int sum = 0;
    for (char c : word.toCharArray()) {
        sum += score[c - 'a'];
    }
    return sum;
}

public int getMaxScoreHelper(String[] words, int[] score, char[] letters, int i) {
    if (i == words.length) {
        return 0;
    }
    int withoutCurrentWord = getMaxScoreHelper(words, score, letters, i + 1);
    for (char c : words[i].toCharArray()) {
        if (--letters[c - 'a'] < 0) {
            break;
        }
    }
    int withCurrentWord = getMaxScore(words[i], score) + getMaxScoreHelper(words, score, letters, i + 1);
    return Math.max(withCurrentWord, withoutCurrentWord);
}

public int maxScoreWords(String[] words, String letters, int[] score) {
    return getMaxScoreHelper(words, score, letters.toCharArray(), 0);
}
```
This solution essentially performs a Depth-First search on the words given, selecting words[i] for a possible combination and then branching based on possibilities with and without words[i]. getMaxScoreHelper recurses through this branching until reaching the end of words where it stops and stores the score of the selected words in that path.

The get_max_score function calculates the score of a word by iterating over each character in the word and summing up their scores in the given array.

To check if we can use the word in the current path, we try to decrement the count of letters in the given set of letters. If there are enough letters in the set we can construct the word.

Finally, maxScoreWords ties all functions together, invoking getMaxScoreHelper for the DFS recursion and, in Python implementation, creating a hash table of the letter counts.

## A solution in C++

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

int getMaxScore(const std::string& word, const std::vector<int>& score) {
    int sum = 0;
    for (char c : word) {
        sum += score[c - 'a'];
    }
    return sum;
}

int getMaxScoreHelper(const std::vector<std::string>& words, const std::vector<int>& score,
                      std::string letters, int i) {
    if (i == words.size()) {
        return 0;
    }
    int withoutCurrentWord = getMaxScoreHelper(words, score, letters, i + 1);
    for (char c : words[i]) {
        if (--letters[c - 'a'] < 0) {
            break;
        }
    }
    int withCurrentWord = getMaxScore(words[i], score) + getMaxScoreHelper(words, score, letters, i + 1);
    return std::max(withCurrentWord, withoutCurrentWord);
}

int maxScoreWords(std::vector<std::string>& words, std::string letters,
                  std::vector<int>& score) {
    return getMaxScoreHelper(words, score, letters, 0);
}
```
This solution essentially performs a Depth-First search on the words given, selecting words[i] for a possible combination and then branching based on possibilities with and without words[i]. getMaxScoreHelper recurses through this branching until reaching the end of words where it stops and stores the score of the selected words in that path.

The get_max_score function calculates the score of a word by iterating over each character in the word and summing up their scores in the given array.

To check if we can use the word in the current path, we try to decrement the count of letters in the given set of letters. If there are enough letters in the set we can construct the word.

Finally, maxScoreWords ties all functions together, invoking getMaxScoreHelper for the DFS recursion and, in Python implementation, creating a hash table of the letter counts.

## A solution in Python

```python
def get_max_score(word, score):
    return sum(score[ord(c) - ord('a')] for c in word)

def get_max_score_helper(words, score, letters, i):
    if i == len(words):
        return 0
    letters_copy = letters.copy()
    for c in words[i]:
        if letters_copy[c] == 0:
            return get_max_score_helper(words, score, letters, i + 1)
        letters_copy[c] -= 1
    return max(get_max_score(words[i], score) + get_max_score_helper(words, score, letters_copy, i + 1),
               get_max_score_helper(words, score, letters, i + 1))

def max_score_words(words, letters, score):
    letters_count = {}
    for letter in letters:
        letters_count[letter] = letters_count.get(letter, 0) + 1
    return get_max_score_helper(words, score, letters_count, 0)
```
This solution essentially performs a Depth-First search on the words given, selecting words[i] for a possible combination and then branching based on possibilities with and without words[i]. getMaxScoreHelper recurses through this branching until reaching the end of words where it stops and stores the score of the selected words in that path.

The get_max_score function calculates the score of a word by iterating over each character in the word and summing up their scores in the given array.

To check if we can use the word in the current path, we try to decrement the count of letters in the given set of letters. If there are enough letters in the set we can construct the word.

Finally, maxScoreWords ties all functions together, invoking getMaxScoreHelper for the DFS recursion and, in Python implementation, creating a hash table of the letter counts.

## A solution in Javascript

```javascript
function getMaxScore(word, score) {
    let sum = 0;
    for (let c of word) {
        sum += score[c.charCodeAt(0) - 'a'.charCodeAt(0)];
    }
    return sum;
}

function getMaxScoreHelper(words, score, letters, i) {
    if (i == words.length) {
        return 0;
    }
    let withoutCurrentWord = getMaxScoreHelper(words, score, letters, i + 1);
    for (let c of words[i]) {
        if (--letters[c.charCodeAt(0) - 'a'.charCodeAt(0)] < 0) {
            break;
        }
    }
    let withCurrentWord = getMaxScore(words[i], score) + getMaxScoreHelper(words, score, letters, i + 1);
    return Math.max(withCurrentWord, withoutCurrentWord);
}

function maxScoreWords(words, letters, score) {
    return getMaxScoreHelper(words, score, Array.from(letters), 0);
}
```
This solution essentially performs a Depth-First search on the words given, selecting words[i] for a possible combination and then branching based on possibilities with and without words[i]. getMaxScoreHelper recurses through this branching until reaching the end of words where it stops and stores the score of the selected words in that path.

The get_max_score function calculates the score of a word by iterating over each character in the word and summing up their scores in the given array.

To check if we can use the word in the current path, we try to decrement the count of letters in the given set of letters. If there are enough letters in the set we can construct the word.

Finally, maxScoreWords ties all functions together, invoking getMaxScoreHelper for the DFS recursion and, in Python implementation, creating a hash table of the letter counts.


# Balance a Binary Search Tree

- slug: balance-a-binary-search-tree
- difficulty: Medium

Given the `root` of a binary search tree, return _a **balanced** binary search tree with the same node values_. If there is more than one answer, return **any of them**.

A binary search tree is **balanced** if the depth of the two subtrees of every node never differs by more than `1`.

**Example 1:**

**Input:** root = \[1,null,2,null,3,null,4,null,null\]
**Output:** \[2,1,3,null,null,null,4\]
**Explanation:** This is not the only correct answer, \[3,1,4,null,2\] is also correct.

**Example 2:**

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

**Constraints:**

*   The number of nodes in the tree is in the range `[1, 104]`.
*   `1 <= Node.val <= 105`

## A solution in Java

```java
public 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 TreeNode balanceBST(TreeNode root) {
        List<TreeNode> sortedNodes = new ArrayList<>();
        inorderTraversal(root, sortedNodes);
        return sortedArrayToBST(sortedNodes, 0, sortedNodes.size() - 1);
    }

    private void inorderTraversal(TreeNode node, List<TreeNode> sortedNodes) {
        if (node == null) return;
        inorderTraversal(node.left, sortedNodes);
        sortedNodes.add(node);
        inorderTraversal(node.right, sortedNodes);
    }

    private TreeNode sortedArrayToBST(List<TreeNode> sortedNodes, int start, int end) {
        if (start > end) return null;
        int mid = start + (end - start) / 2;
        TreeNode newNode = sortedNodes.get(mid);
        newNode.left = sortedArrayToBST(sortedNodes, start, mid - 1);
        newNode.right = sortedArrayToBST(sortedNodes, mid + 1, end);
        return newNode;
    }
}
```
The algorithm first traverses the input binary search tree using Inorder Traversal (Left-Root-Right) to obtain the ordered tree nodes in a sorted array. After that, it converts the sorted array recursively into a balanced binary search tree by picking the middle element as the root node and performing the same operation on the left and right subarrays. The middle element is chosen so the subtree depths remain no more than one level apart, fulfilling the balanced binary search tree constraint.

## 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:
    TreeNode* balanceBST(TreeNode* root) {
        vector<TreeNode*> sortedNodes;
        inorderTraversal(root, sortedNodes);
        return sortedArrayToBST(sortedNodes, 0, sortedNodes.size() - 1);
    }

    void inorderTraversal(TreeNode* node, vector<TreeNode*>& sortedNodes) {
        if (node == nullptr) return;
        inorderTraversal(node->left, sortedNodes);
        sortedNodes.push_back(node);
        inorderTraversal(node->right, sortedNodes);
    }

    TreeNode* sortedArrayToBST(vector<TreeNode*>& sortedNodes, int start, int end) {
        if (start > end) return nullptr;
        int mid = start + (end - start) / 2;
        TreeNode* newNode = sortedNodes[mid];
        newNode->left = sortedArrayToBST(sortedNodes, start, mid - 1);
        newNode->right = sortedArrayToBST(sortedNodes, mid + 1, end);
        return newNode;
    }
};
```
The algorithm first traverses the input binary search tree using Inorder Traversal (Left-Root-Right) to obtain the ordered tree nodes in a sorted array. After that, it converts the sorted array recursively into a balanced binary search tree by picking the middle element as the root node and performing the same operation on the left and right subarrays. The middle element is chosen so the subtree depths remain no more than one level apart, fulfilling the balanced binary search tree constraint.

## 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 balanceBST(self, root: TreeNode) -> TreeNode:
        sortedNodes = []
        self.inorderTraversal(root, sortedNodes)
        return self.sortedArrayToBST(sortedNodes, 0, len(sortedNodes) - 1)

    def inorderTraversal(self, node: TreeNode, sortedNodes: list):
        if node is None: return
        self.inorderTraversal(node.left, sortedNodes)
        sortedNodes.append(node)
        self.inorderTraversal(node.right, sortedNodes)

    def sortedArrayToBST(self, sortedNodes: list, start: int, end: int) -> TreeNode:
        if start > end: return None
        mid = start + (end - start) // 2
        newNode = sortedNodes[mid]
        newNode.left = self.sortedArrayToBST(sortedNodes, start, mid - 1)
        newNode.right = self.sortedArrayToBST(sortedNodes, mid + 1, end)
        return newNode
```
The algorithm first traverses the input binary search tree using Inorder Traversal (Left-Root-Right) to obtain the ordered tree nodes in a sorted array. After that, it converts the sorted array recursively into a balanced binary search tree by picking the middle element as the root node and performing the same operation on the left and right subarrays. The middle element is chosen so the subtree depths remain no more than one level apart, fulfilling the balanced binary search tree constraint.

## A solution in Javascript

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

function inorderTraversal(node, sortedNodes) {
    if (node === null) return;
    inorderTraversal(node.left, sortedNodes);
    sortedNodes.push(node);
    inorderTraversal(node.right, sortedNodes);
}

function sortedArrayToBST(sortedNodes, start, end) {
    if (start > end) return null;
    let mid = start + Math.floor((end - start) / 2);
    let newNode = sortedNodes[mid];
    newNode.left = sortedArrayToBST(sortedNodes, start, mid - 1);
    newNode.right = sortedArrayToBST(sortedNodes, mid + 1, end);
    return newNode;
}

function balanceBST(root) {
    let sortedNodes = [];
    inorderTraversal(root, sortedNodes);
    return sortedArrayToBST(sortedNodes, 0, sortedNodes.length - 1);
}
```
The algorithm first traverses the input binary search tree using Inorder Traversal (Left-Root-Right) to obtain the ordered tree nodes in a sorted array. After that, it converts the sorted array recursively into a balanced binary search tree by picking the middle element as the root node and performing the same operation on the left and right subarrays. The middle element is chosen so the subtree depths remain no more than one level apart, fulfilling the balanced binary search tree constraint.


# Maximum Performance of a Team

- slug: maximum-performance-of-a-team
- difficulty: Hard

You are given two integers `n` and `k` and two integer arrays `speed` and `efficiency` both of length `n`. There are `n` engineers numbered from `1` to `n`. `speed[i]` and `efficiency[i]` represent the speed and efficiency of the `ith` engineer respectively.

Choose **at most** `k` different engineers out of the `n` engineers to form a team with the maximum **performance**.

The performance of a team is the sum of their engineers' speeds multiplied by the minimum efficiency among their engineers.

Return _the maximum performance of this team_. Since the answer can be a huge number, return it **modulo** `109 + 7`.

**Example 1:**

**Input:** n = 6, speed = \[2,10,3,1,5,8\], efficiency = \[5,4,3,9,7,2\], k = 2
**Output:** 60
**Explanation:**
We have the maximum performance of the team by selecting engineer 2 (with speed=10 and efficiency=4) and engineer 5 (with speed=5 and efficiency=7). That is, performance = (10 + 5) \* min(4, 7) = 60.

**Example 2:**

**Input:** n = 6, speed = \[2,10,3,1,5,8\], efficiency = \[5,4,3,9,7,2\], k = 3
**Output:** 68
**Explanation:**
This is the same example as the first but k = 3. We can select engineer 1, engineer 2 and engineer 5 to get the maximum performance of the team. That is, performance = (2 + 10 + 5) \* min(5, 4, 7) = 68.

**Example 3:**

**Input:** n = 6, speed = \[2,10,3,1,5,8\], efficiency = \[5,4,3,9,7,2\], k = 4
**Output:** 72

**Constraints:**

*   `1 <= k <= n <= 105`
*   `speed.length == n`
*   `efficiency.length == n`
*   `1 <= speed[i] <= 105`
*   `1 <= efficiency[i] <= 108`

## A solution in Java

```java
import java.util.*;

public int maxPerformance(int n, int k, int[] speed, int[] efficiency) {
    int[][] engineers = new int[n][2];
    for (int i = 0; i < n; i++) {
        engineers[i] = new int[] {efficiency[i], speed[i]};
    }

    Arrays.sort(engineers, (a, b) -> b[0] - a[0]);

    PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, Comparator.reverseOrder());
    long speedSum = 0;
    long maxPerformance = 0;

    for (int[] engineer : engineers) {
        speedSum += engineer[1];
        minHeap.offer(engineer[1]);

        if (minHeap.size() > k) {
            speedSum -= minHeap.poll();
        }

        maxPerformance = Math.max(maxPerformance, speedSum * engineer[0]);
    }

    return (int) (maxPerformance % (1e9 + 7));
}
```
1. Store each engineer as pair of efficiency and speed in a list/array and sort that list/array in decreasing order based on efficiency.
2. Initialize an empty min-heap, speed_sum and max_performance.
3. Iterate over the sorted engineers list/array:
   a. Add the current engineer's speed to the speed_sum.
   b. Add the current engineer's speed to the min-heap.
   c. If the min-heap's size is greater than given k, remove the minimum speed from the min-heap and subtract it from the speed_sum.
   d. Update max_performance by comparing the current max_performance with the product of speed_sum and the current engineer's efficiency.
4. Return max_performance % (10^9 + 7).

## A solution in C++

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

int maxPerformance(int n, int k, std::vector<int>& speed, std::vector<int>& efficiency) {
    std::vector<std::pair<int, int>> engineers(n);
    for (int i = 0; i < n; ++i) {
        engineers[i] = {efficiency[i], speed[i]};
    }

    std::sort(engineers.rbegin(), engineers.rend());

    std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap;

    long long speed_sum = 0;
    long long max_performance = 0;

    for (auto& engineer : engineers) {
        speed_sum += engineer.second;
        min_heap.push(engineer.second);

        if (min_heap.size() > k) {
            speed_sum -= min_heap.top();
            min_heap.pop();
        }

        max_performance = std::max(max_performance, speed_sum * engineer.first);
    }

    return max_performance % 1000000007;
}
```
1. Store each engineer as pair of efficiency and speed in a list/array and sort that list/array in decreasing order based on efficiency.
2. Initialize an empty min-heap, speed_sum and max_performance.
3. Iterate over the sorted engineers list/array:
   a. Add the current engineer's speed to the speed_sum.
   b. Add the current engineer's speed to the min-heap.
   c. If the min-heap's size is greater than given k, remove the minimum speed from the min-heap and subtract it from the speed_sum.
   d. Update max_performance by comparing the current max_performance with the product of speed_sum and the current engineer's efficiency.
4. Return max_performance % (10^9 + 7).

## A solution in Python

```python
import heapq
from typing import List

def max_performance(n: int, k: int, speed: List[int], efficiency: List[int]) -> int:
    engineers = sorted(zip(efficiency, speed), reverse=True)
    min_heap = []
    speed_sum = 0
    max_performance = 0

    for e, s in engineers:
        speed_sum += s
        heapq.heappush(min_heap, s)

        if len(min_heap) > k:
            speed_sum -= heapq.heappop(min_heap)

        max_performance = max(max_performance, speed_sum * e)

    return max_performance % (10**9 + 7)
```
1. Store each engineer as pair of efficiency and speed in a list/array and sort that list/array in decreasing order based on efficiency.
2. Initialize an empty min-heap, speed_sum and max_performance.
3. Iterate over the sorted engineers list/array:
   a. Add the current engineer's speed to the speed_sum.
   b. Add the current engineer's speed to the min-heap.
   c. If the min-heap's size is greater than given k, remove the minimum speed from the min-heap and subtract it from the speed_sum.
   d. Update max_performance by comparing the current max_performance with the product of speed_sum and the current engineer's efficiency.
4. Return max_performance % (10^9 + 7).

## A solution in Javascript

```javascript
function maxPerformance(n, k, speed, efficiency) {
    const engineers = efficiency.map((e, i) => [e, speed[i]]).sort((a, b) => b[0] - a[0]);
    const minHeap = new MinHeap();

    let speedSum = 0;
    let maxPerformance = 0;

    for (const [e, s] of engineers) {
        speedSum += s;
        minHeap.insert(s);

        if (minHeap.size() > k) {
            speedSum -= minHeap.extractMin();
        }

        maxPerformance = Math.max(maxPerformance, speedSum * e);
    }

    return maxPerformance % (10**9 + 7);
}

class MinHeap {
    constructor() {
        this.heap = [];
    }
    insert(value) {
        this.heap.push(value);
        this.bubbleUp(this.heap.length - 1);
    }
    extractMin() {
        const min = this.heap[0];
        this.heap[0] = this.heap.pop();
        this.bubbleDown(0);
        return min;
    }
    size() {
        return this.heap.length;
    }
    bubbleUp(index) {
        while (index > 0) {
            const parentIndex = Math.floor((index - 1) / 2);
            if (this.heap[index] >= this.heap[parentIndex]) {
                break;
            }
            [this.heap[index], this.heap[parentIndex]] = [this.heap[parentIndex], this.heap[index]];
            index = parentIndex;
        }
    }
    bubbleDown(index) {
        while (true) {
            let minIndex = index;
            const leftChildIndex = 2 * index + 1;
            const rightChildIndex = 2 * index + 2;
            if (leftChildIndex < this.heap.length && this.heap[leftChildIndex] < this.heap[minIndex]) {
                minIndex = leftChildIndex;
            }
            if (rightChildIndex < this.heap.length && this.heap[rightChildIndex] < this.heap[minIndex]) {
                minIndex = rightChildIndex;
            }
            if (minIndex === index) {
                break;
            }
            [this.heap[index], this.heap[minIndex]] = [this.heap[minIndex], this.heap[index]];
            index = minIndex;
        }
    }
}
```
1. Store each engineer as pair of efficiency and speed in a list/array and sort that list/array in decreasing order based on efficiency.
2. Initialize an empty min-heap, speed_sum and max_performance.
3. Iterate over the sorted engineers list/array:
   a. Add the current engineer's speed to the speed_sum.
   b. Add the current engineer's speed to the min-heap.
   c. If the min-heap's size is greater than given k, remove the minimum speed from the min-heap and subtract it from the speed_sum.
   d. Update max_performance by comparing the current max_performance with the product of speed_sum and the current engineer's efficiency.
4. Return max_performance % (10^9 + 7).


# Find the Distance Value Between Two Arrays

- slug: find-the-distance-value-between-two-arrays
- difficulty: Easy

Given two integer arrays `arr1` and `arr2`, and the integer `d`, _return the distance value between the two arrays_.

The distance value is defined as the number of elements `arr1[i]` such that there is not any element `arr2[j]` where `|arr1[i]-arr2[j]| <= d`.

**Example 1:**

**Input:** arr1 = \[4,5,8\], arr2 = \[10,9,1,8\], d = 2
**Output:** 2
**Explanation:**
For arr1\[0\]=4 we have:
|4-10|=6 > d=2
|4-9|=5 > d=2
|4-1|=3 > d=2
|4-8|=4 > d=2
For arr1\[1\]=5 we have:
|5-10|=5 > d=2
|5-9|=4 > d=2
|5-1|=4 > d=2
|5-8|=3 > d=2
For arr1\[2\]=8 we have:
**|8-10|=2 <= d=2**
**|8-9|=1 <= d=2**
|8-1|=7 > d=2
**|8-8|=0 <= d=2**

**Example 2:**

**Input:** arr1 = \[1,4,2,3\], arr2 = \[-4,-3,6,10,20,30\], d = 3
**Output:** 2

**Example 3:**

**Input:** arr1 = \[2,1,100,3\], arr2 = \[-5,-2,10,-3,7\], d = 6
**Output:** 1

**Constraints:**

*   `1 <= arr1.length, arr2.length <= 500`
*   `-1000 <= arr1[i], arr2[j] <= 1000`
*   `0 <= d <= 100`

## A solution in Java

```java
public int findTheDistanceValue(int[] arr1, int[] arr2, int d) {
    int distance = 0;
    for (int a : arr1) {
        boolean found = true;
        for (int b : arr2) {
            if (Math.abs(a - b) <= d) {
                found = false;
                break;
            }
        }
        if (found) distance++;
    }
    return distance;
}
```
For each element `a` in array `arr1`, we iterate through all elements `b` in array `arr2` and check the condition `|a-b| <= d`. If we find an element `b` that satisfies the condition, we stop searching and move to the next element of `arr1`. If we haven't found any such element, we increment the distance value. Finally, we return the distance value after processing all elements of `arr1`.

## A solution in C++

```cpp
int findTheDistanceValue(vector<int>& arr1, vector<int>& arr2, int d) {
    int distance = 0;
    for (int a : arr1) {
        bool found = true;
        for (int b : arr2) {
            if (abs(a - b) <= d) {
                found = false;
                break;
            }
        }
        if (found) distance++;
    }
    return distance;
}
```
For each element `a` in array `arr1`, we iterate through all elements `b` in array `arr2` and check the condition `|a-b| <= d`. If we find an element `b` that satisfies the condition, we stop searching and move to the next element of `arr1`. If we haven't found any such element, we increment the distance value. Finally, we return the distance value after processing all elements of `arr1`.

## A solution in Python

```python
def findTheDistanceValue(arr1, arr2, d):
    distance = 0
    for a in arr1:
        found = True
        for b in arr2:
            if abs(a - b) <= d:
                found = False
                break
        if found:
            distance += 1
    return distance
```
For each element `a` in array `arr1`, we iterate through all elements `b` in array `arr2` and check the condition `|a-b| <= d`. If we find an element `b` that satisfies the condition, we stop searching and move to the next element of `arr1`. If we haven't found any such element, we increment the distance value. Finally, we return the distance value after processing all elements of `arr1`.

## A solution in Javascript

```javascript
function findTheDistanceValue(arr1, arr2, d) {
    let distance = 0;
    for (let a of arr1) {
        let found = true;
        for (let b of arr2) {
            if (Math.abs(a - b) <= d) {
                found = false;
                break;
            }
        }
        if (found) distance++;
    }
    return distance;
}
```
For each element `a` in array `arr1`, we iterate through all elements `b` in array `arr2` and check the condition `|a-b| <= d`. If we find an element `b` that satisfies the condition, we stop searching and move to the next element of `arr1`. If we haven't found any such element, we increment the distance value. Finally, we return the distance value after processing all elements of `arr1`.


# Cinema Seat Allocation

- slug: cinema-seat-allocation
- difficulty: Medium

A cinema has `n` rows of seats, numbered from 1 to `n` and there are ten seats in each row, labelled from 1 to 10 as shown in the figure above.

Given the array `reservedSeats` containing the numbers of seats already reserved, for example, `reservedSeats[i] = [3,8]` means the seat located in row **3** and labelled with **8** is already reserved.

_Return the maximum number of four-person groups you can assign on the cinema seats._ A four-person group occupies four adjacent seats **in one single row**. Seats across an aisle (such as \[3,3\] and \[3,4\]) are not considered to be adjacent, but there is an exceptional case on which an aisle split a four-person group, in that case, the aisle split a four-person group in the middle, which means to have two people on each side.

**Example 1:**

**Input:** n = 3, reservedSeats = \[\[1,2\],\[1,3\],\[1,8\],\[2,6\],\[3,1\],\[3,10\]\]
**Output:** 4
**Explanation:** The figure above shows the optimal allocation for four groups, where seats mark with blue are already reserved and contiguous seats mark with orange are for one group.

**Example 2:**

**Input:** n = 2, reservedSeats = \[\[2,1\],\[1,8\],\[2,6\]\]
**Output:** 2

**Example 3:**

**Input:** n = 4, reservedSeats = \[\[4,3\],\[1,4\],\[4,6\],\[1,7\]\]
**Output:** 4

**Constraints:**

*   `1 <= n <= 10^9`
*   `1 <= reservedSeats.length <= min(10*n, 10^4)`
*   `reservedSeats[i].length == 2`
*   `1 <= reservedSeats[i][0] <= n`
*   `1 <= reservedSeats[i][1] <= 10`
*   All `reservedSeats[i]` are distinct.

## A solution in Java

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

public List<List<Integer>> shiftGrid(int[][] grid, int k) {
    int m = grid.length, n = grid[0].length;
    k %= (m * n);
    List<List<Integer>> res = new ArrayList<>();
    for (int i = 0; i < m; ++i) {
        List<Integer> row = new ArrayList<>();
        for (int j = 0; j < n; ++j) {
            int idx = (i * n + j + k) % (m * n);
            row.add(grid[idx / n][idx % n]);
        }
        res.add(row);
    }
    return res;
}
```
The algorithm works as follows:
1. Get the dimensions of the grid, `m` and `n`, and calculate the total number of elements.
2. Take the modulo of `k` with the total number of elements, so that `k` doesn't exceed the grid size.
3. Initialize a result grid `res` with the same dimensions, filled with 0s.
4. Iterate through the original grid using two nested loops, one for rows and one for columns.
5. For each element in the original grid, calculate its new position in the result grid, using the formula `(i * n + j + k) % (m * n)` for the flattened indices.
6. Assign the grid element to its new position in the result grid.
7. Return the result grid after iterating through all elements.

## A solution in C++

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

vector<vector<int>> shiftGrid(vector<vector<int>>& grid, int k) {
    int m = grid.size(), n = grid[0].size();
    k %= (m * n);
    vector<vector<int>> res(m, vector<int>(n));
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            int idx = (i * n + j + k) % (m * n);
            res[idx / n][idx % n] = grid[i][j];
        }
    }
    return res;
}
```
The algorithm works as follows:
1. Get the dimensions of the grid, `m` and `n`, and calculate the total number of elements.
2. Take the modulo of `k` with the total number of elements, so that `k` doesn't exceed the grid size.
3. Initialize a result grid `res` with the same dimensions, filled with 0s.
4. Iterate through the original grid using two nested loops, one for rows and one for columns.
5. For each element in the original grid, calculate its new position in the result grid, using the formula `(i * n + j + k) % (m * n)` for the flattened indices.
6. Assign the grid element to its new position in the result grid.
7. Return the result grid after iterating through all elements.

## A solution in Python

```python
def shiftGrid(grid, k):
    m, n = len(grid), len(grid[0])
    k %= (m * n)
    res = [[0] * n for _ in range(m)]
    for i in range(m):
        for j in range(n):
            idx = (i * n + j + k) % (m * n)
            res[idx // n][idx % n] = grid[i][j]
    return res
```
The algorithm works as follows:
1. Get the dimensions of the grid, `m` and `n`, and calculate the total number of elements.
2. Take the modulo of `k` with the total number of elements, so that `k` doesn't exceed the grid size.
3. Initialize a result grid `res` with the same dimensions, filled with 0s.
4. Iterate through the original grid using two nested loops, one for rows and one for columns.
5. For each element in the original grid, calculate its new position in the result grid, using the formula `(i * n + j + k) % (m * n)` for the flattened indices.
6. Assign the grid element to its new position in the result grid.
7. Return the result grid after iterating through all elements.

## A solution in Javascript

```javascript
function shiftGrid(grid, k) {
    const m = grid.length, n = grid[0].length;
    k %= (m * n);
    const res = Array.from({length: m}, () => Array(n).fill(0));
    for (let i = 0; i < m; ++i) {
        for (let j = 0; j < n; ++j) {
            let idx = (i * n + j + k) % (m * n);
            res[Math.floor(idx / n)][idx % n] = grid[i][j];
        }
    }
    return res;
}
```
The algorithm works as follows:
1. Get the dimensions of the grid, `m` and `n`, and calculate the total number of elements.
2. Take the modulo of `k` with the total number of elements, so that `k` doesn't exceed the grid size.
3. Initialize a result grid `res` with the same dimensions, filled with 0s.
4. Iterate through the original grid using two nested loops, one for rows and one for columns.
5. For each element in the original grid, calculate its new position in the result grid, using the formula `(i * n + j + k) % (m * n)` for the flattened indices.
6. Assign the grid element to its new position in the result grid.
7. Return the result grid after iterating through all elements.


# Pizza With 3n Slices

- slug: pizza-with-3n-slices
- difficulty: Hard

There is a pizza with `3n` slices of varying size, you and your friends will take slices of pizza as follows:

*   You will pick **any** pizza slice.
*   Your friend Alice will pick the next slice in the anti-clockwise direction of your pick.
*   Your friend Bob will pick the next slice in the clockwise direction of your pick.
*   Repeat until there are no more slices of pizzas.

Given an integer array `slices` that represent the sizes of the pizza slices in a clockwise direction, return _the maximum possible sum of slice sizes that you can pick_.

**Example 1:**

**Input:** slices = \[1,2,3,4,5,6\]
**Output:** 10
**Explanation:** Pick pizza slice of size 4, Alice and Bob will pick slices with size 3 and 5 respectively. Then Pick slices with size 6, finally Alice and Bob will pick slice of size 2 and 1 respectively. Total = 4 + 6.

**Example 2:**

**Input:** slices = \[8,9,8,6,1,1\]
**Output:** 16
**Explanation:** Pick pizza slice of size 8 in each turn. If you pick slice with size 9 your partners will pick slices of size 8.

**Constraints:**

*   `3 * n == slices.length`
*   `1 <= slices.length <= 500`
*   `1 <= slices[i] <= 1000`

## A solution in Java

```java
public int maxSumDivThree(int[] nums) {
    int[] dp = new int[3];
    for (int num : nums) {
        int[] temp = Arrays.copyOf(dp, 3);
        for (int s : temp) {
            dp[(s + num) % 3] = Math.max(dp[(s + num) % 3], s + num);
        }
    }
    return dp[0];
}
```
1. Initialize a dynamic programming array `dp` having 3 elements with all 0's. This will store the maximum sum for % 3 == 0, % 3 == 1, and % 3 == 2.
2. Iterate through the input array `nums`.
3. For each number, create a temporary copy of the current `dp` state, as we want to make changes to the original `dp` array based on the original state.
4. For each number, iterate through the temporary copy of `dp` (temp). Calculate `(s + num) % 3` for the current number and the sum, and update the respective position in `dp` array with the maximum sum.
5. The answer will be stored at `dp[0]`, which is the maximum sum that is divisible by three.

## A solution in C++

```cpp
int maxSumDivThree(vector<int>& nums) {
    vector<int> dp(3, 0);
    for (int num : nums) {
        vector<int> temp(dp);
        for (int s : temp) {
            dp[(s + num) % 3] = max(dp[(s + num) % 3], s + num);
        }
    }
    return dp[0];
}
```
1. Initialize a dynamic programming array `dp` having 3 elements with all 0's. This will store the maximum sum for % 3 == 0, % 3 == 1, and % 3 == 2.
2. Iterate through the input array `nums`.
3. For each number, create a temporary copy of the current `dp` state, as we want to make changes to the original `dp` array based on the original state.
4. For each number, iterate through the temporary copy of `dp` (temp). Calculate `(s + num) % 3` for the current number and the sum, and update the respective position in `dp` array with the maximum sum.
5. The answer will be stored at `dp[0]`, which is the maximum sum that is divisible by three.

## A solution in Python

```python
def maxSumDivThree(nums):
    dp = [0, 0, 0]
    for num in nums:
        temp = dp[:]
        for s in temp:
            dp[(s + num) % 3] = max(dp[(s + num) % 3], s + num)
    return dp[0]
```
1. Initialize a dynamic programming array `dp` having 3 elements with all 0's. This will store the maximum sum for % 3 == 0, % 3 == 1, and % 3 == 2.
2. Iterate through the input array `nums`.
3. For each number, create a temporary copy of the current `dp` state, as we want to make changes to the original `dp` array based on the original state.
4. For each number, iterate through the temporary copy of `dp` (temp). Calculate `(s + num) % 3` for the current number and the sum, and update the respective position in `dp` array with the maximum sum.
5. The answer will be stored at `dp[0]`, which is the maximum sum that is divisible by three.

## A solution in Javascript

```javascript
function maxSumDivThree(nums) {
    let dp = [0, 0, 0];
    for (let num of nums) {
        let temp = [...dp];
        for (let s of temp) {
            dp[(s + num) % 3] = Math.max(dp[(s + num) % 3], s + num);
        }
    }
    return dp[0];
}
```
1. Initialize a dynamic programming array `dp` having 3 elements with all 0's. This will store the maximum sum for % 3 == 0, % 3 == 1, and % 3 == 2.
2. Iterate through the input array `nums`.
3. For each number, create a temporary copy of the current `dp` state, as we want to make changes to the original `dp` array based on the original state.
4. For each number, iterate through the temporary copy of `dp` (temp). Calculate `(s + num) % 3` for the current number and the sum, and update the respective position in `dp` array with the maximum sum.
5. The answer will be stored at `dp[0]`, which is the maximum sum that is divisible by three.


# Four Divisors

- slug: four-divisors
- difficulty: Medium

Given an integer array `nums`, return _the sum of divisors of the integers in that array that have exactly four divisors_. If there is no such integer in the array, return `0`.

**Example 1:**

**Input:** nums = \[21,4,7\]
**Output:** 32
**Explanation:**
21 has 4 divisors: 1, 3, 7, 21
4 has 3 divisors: 1, 2, 4
7 has 2 divisors: 1, 7
The answer is the sum of divisors of 21 only.

**Example 2:**

**Input:** nums = \[21,21\]
**Output:** 64

**Example 3:**

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

**Constraints:**

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

## A solution in Java

```java
public int sumOfFourDivisors(int[] nums) {
    int sum = 0;
    for (int num : nums) {
        int count = 0;
        int div_sum = 0;
        for (int i = 1; i * i <= num; ++i) {
            if (num % i == 0) {
                count += (i * i == num) ? 1 : 2;
                div_sum += i + (num / i);
                if (count > 4) break;
            }
        }
        if (count == 4) sum += div_sum;
    }
    return sum;
}
```
The algorithm iterates through each number in the `nums` array. For each number, it calculates the number of divisors and their sum. If a number has a square root, the count of divisors is incremented once, instead of twice, and the divisor sum is incremented by that number and its corresponding divisor, except when the loop finds a square root divisor. When the count of divisors exceeds 4, the loop breaks. If a number has exactly 4 divisors, the sum of its divisors is added to the final answer. The result is returned after processing all the numbers in the input array.

## A solution in C++

```cpp
int sumOfFourDivisors(std::vector<int>& nums) {
    int sum = 0;
    for (int num : nums) {
        int count = 0;
        int div_sum = 0;
        for (int i = 1; i * i <= num; ++i) {
            if (num % i == 0) {
                count += (i * i == num) ? 1 : 2;
                div_sum += i + (num / i);
                if (count > 4) break;
            }
        }
        if (count == 4) sum += div_sum;
    }
    return sum;
}
```
The algorithm iterates through each number in the `nums` array. For each number, it calculates the number of divisors and their sum. If a number has a square root, the count of divisors is incremented once, instead of twice, and the divisor sum is incremented by that number and its corresponding divisor, except when the loop finds a square root divisor. When the count of divisors exceeds 4, the loop breaks. If a number has exactly 4 divisors, the sum of its divisors is added to the final answer. The result is returned after processing all the numbers in the input array.

## A solution in Python

```python
def sum_of_four_divisors(nums):
    total_sum = 0
    for num in nums:
        count = 0
        div_sum = 0
        i = 1
        while i * i <= num:
            if num % i == 0:
                count += 1 if i * i == num else 2
                div_sum += i + (num // i)
                if count > 4:
                    break
            i += 1
        if count == 4:
            total_sum += div_sum
    return total_sum
```
The algorithm iterates through each number in the `nums` array. For each number, it calculates the number of divisors and their sum. If a number has a square root, the count of divisors is incremented once, instead of twice, and the divisor sum is incremented by that number and its corresponding divisor, except when the loop finds a square root divisor. When the count of divisors exceeds 4, the loop breaks. If a number has exactly 4 divisors, the sum of its divisors is added to the final answer. The result is returned after processing all the numbers in the input array.

## A solution in Javascript

```javascript
function sumOfFourDivisors(nums) {
    let sum = 0;
    for (let num of nums) {
        let count = 0;
        let div_sum = 0;
        for (let i = 1; i * i <= num; ++i) {
            if (num % i === 0) {
                count += (i * i === num) ? 1 : 2;
                div_sum += i + (num / i);
                if (count > 4) break;
            }
        }
        if (count === 4) sum += div_sum;
    }
    return sum;
}
```
The algorithm iterates through each number in the `nums` array. For each number, it calculates the number of divisors and their sum. If a number has a square root, the count of divisors is incremented once, instead of twice, and the divisor sum is incremented by that number and its corresponding divisor, except when the loop finds a square root divisor. When the count of divisors exceeds 4, the loop breaks. If a number has exactly 4 divisors, the sum of its divisors is added to the final answer. The result is returned after processing all the numbers in the input array.