# Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree

- slug: find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree
- difficulty: Hard

Given a weighted undirected connected graph with `n` vertices numbered from `0` to `n - 1`, and an array `edges` where `edges[i] = [ai, bi, weighti]` represents a bidirectional and weighted edge between nodes `ai` and `bi`. A minimum spanning tree (MST) is a subset of the graph's edges that connects all vertices without cycles and with the minimum possible total edge weight.

Find _all the critical and pseudo-critical edges in the given graph's minimum spanning tree (MST)_. An MST edge whose deletion from the graph would cause the MST weight to increase is called a _critical edge_. On the other hand, a pseudo-critical edge is that which can appear in some MSTs but not all.

Note that you can return the indices of the edges in any order.

**Example 1:**

**Input:** n = 5, edges = \[\[0,1,1\],\[1,2,1\],\[2,3,2\],\[0,3,2\],\[0,4,3\],\[3,4,3\],\[1,4,6\]\]
**Output:** \[\[0,1\],\[2,3,4,5\]\]
**Explanation:** The figure above describes the graph.
The following figure shows all the possible MSTs:

Notice that the two edges 0 and 1 appear in all MSTs, therefore they are critical edges, so we return them in the first list of the output.
The edges 2, 3, 4, and 5 are only part of some MSTs, therefore they are considered pseudo-critical edges. We add them to the second list of the output.

**Example 2:**

**Input:** n = 4, edges = \[\[0,1,1\],\[1,2,1\],\[2,3,1\],\[0,3,1\]\]
**Output:** \[\[\],\[0,1,2,3\]\]
**Explanation:** We can observe that since all 4 edges have equal weight, choosing any 3 edges from the given 4 will yield an MST. Therefore all 4 edges are pseudo-critical.

**Constraints:**

*   `2 <= n <= 100`
*   `1 <= edges.length <= min(200, n * (n - 1) / 2)`
*   `edges[i].length == 3`
*   `0 <= ai < bi < n`
*   `1 <= weighti <= 1000`
*   All pairs `(ai, bi)` are **distinct**.

## A solution in Java

```java
public int maxSizeSlices(int[] slices) {
    int n = slices.length / 3;
    int[][] memo1 = new int[slices.length][n + 1];
    for (int[] row : memo1) {
        Arrays.fill(row, -1);
    }
    int[][] memo2 = new int[slices.length][n + 1];
    for (int[] row : memo2) {
        Arrays.fill(row, -1);
    }

    return Math.max(maxSum(slices, 0, slices.length - 1, n, memo1),
                    maxSum(slices, 1, slices.length, n, memo2));
}

int maxSum(int[] slices, int start, int end, int n, int[][] memo) {
    if (n == 0) return 0;
    if (end - start + 1 < n * 2) return Integer.MIN_VALUE;
    if (memo[start][n] != -1) return memo[start][n];

    int pick = maxSum(slices, start + 2, end, n - 1, memo) + slices[start];
    int notPick = maxSum(slices, start + 1, end, n, memo);

    memo[start][n] = Math.max(pick, notPick);
    return memo[start][n];
}
```
We take a dynamic programming approach to solve the problem. Since we cannot take adjacent slices, we can start from the first slice and recurse with the remaining slices when we have taken the first slice, and when we haven't taken the first slice. When our n equals 0, that means we have taken all slices we can, and we should return 0.

If the remaining slices are less than 2 * n, we return the minimum sum possible. We store the memo for each case, the memo when we have taken the first slice and memo when we haven't taken the first slice. We return the max from both the memos, which is the maximum possible sum of slice sizes that we can pick.

## A solution in C++

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

int maxSum(vector<int>& slices, int start, int end, int n, vector<vector<int>>& memo) {
    if (n == 0) return 0;
    if (end - start + 1 < n * 2) return INT_MIN;
    if (memo[start][n] != -1) return memo[start][n];

    int pick = maxSum(slices, start + 2, end, n - 1, memo) + slices[start];
    int notPick = maxSum(slices, start + 1, end, n, memo);

    memo[start][n] = max(pick, notPick);
    return memo[start][n];
}

int maxSizeSlices(vector<int>& slices) {
    int n = slices.size() / 3;
    vector<vector<int>> memo1(slices.size(), vector<int>(n + 1, -1));
    vector<vector<int>> memo2(slices.size(), vector<int>(n + 1, -1));

    return max(maxSum(slices, 0, slices.size() - 1, n, memo1),
               maxSum(slices, 1, slices.size(), n, memo2));
}
```
We take a dynamic programming approach to solve the problem. Since we cannot take adjacent slices, we can start from the first slice and recurse with the remaining slices when we have taken the first slice, and when we haven't taken the first slice. When our n equals 0, that means we have taken all slices we can, and we should return 0.

If the remaining slices are less than 2 * n, we return the minimum sum possible. We store the memo for each case, the memo when we have taken the first slice and memo when we haven't taken the first slice. We return the max from both the memos, which is the maximum possible sum of slice sizes that we can pick.

## A solution in Python

```python
def max_size_slices(slices):
    def max_sum(slices, start, end, n, memo):
        if n == 0:
            return 0
        if end - start + 1 < n * 2:
            return float('-inf')
        if memo[start][n] != -1:
            return memo[start][n]

        pick = max_sum(slices, start + 2, end, n - 1, memo) + slices[start]
        not_pick = max_sum(slices, start + 1, end, n, memo)

        memo[start][n] = max(pick, not_pick)
        return memo[start][n]

    n = len(slices) // 3
    memo1 = [[-1] * (n + 1) for _ in range(len(slices))]
    memo2 = [[-1] * (n + 1) for _ in range(len(slices))]

    return max(max_sum(slices, 0, len(slices) - 1, n, memo1),
               max_sum(slices, 1, len(slices), n, memo2))
```
We take a dynamic programming approach to solve the problem. Since we cannot take adjacent slices, we can start from the first slice and recurse with the remaining slices when we have taken the first slice, and when we haven't taken the first slice. When our n equals 0, that means we have taken all slices we can, and we should return 0.

If the remaining slices are less than 2 * n, we return the minimum sum possible. We store the memo for each case, the memo when we have taken the first slice and memo when we haven't taken the first slice. We return the max from both the memos, which is the maximum possible sum of slice sizes that we can pick.

## A solution in Javascript

```javascript
function maxSizeSlices(slices) {
    function maxSum(slices, start, end, n, memo) {
        if (n === 0) return 0;
        if (end - start + 1 < n * 2) return Number.NEGATIVE_INFINITY;
        if (memo[start][n] !== -1) return memo[start][n];

        const pick = maxSum(slices, start + 2, end, n - 1, memo) + slices[start];
        const notPick = maxSum(slices, start + 1, end, n, memo);

        memo[start][n] = Math.max(pick, notPick);
        return memo[start][n];
    }

    const n = slices.length / 3;
    const memo1 = Array.from({ length: slices.length }, () => Array(n + 1).fill(-1));
    const memo2 = Array.from({ length: slices.length }, () => Array(n + 1).fill(-1));

    return Math.max(maxSum(slices, 0, slices.length - 1, n, memo1),
                   maxSum(slices, 1, slices.length, n, memo2));
}
```
We take a dynamic programming approach to solve the problem. Since we cannot take adjacent slices, we can start from the first slice and recurse with the remaining slices when we have taken the first slice, and when we haven't taken the first slice. When our n equals 0, that means we have taken all slices we can, and we should return 0.

If the remaining slices are less than 2 * n, we return the minimum sum possible. We store the memo for each case, the memo when we have taken the first slice and memo when we haven't taken the first slice. We return the max from both the memos, which is the maximum possible sum of slice sizes that we can pick.


# Clone N-ary Tree

- slug: clone-n-ary-tree
- difficulty: Medium

Given a `root` of an N-ary tree, return a [**deep copy**](https://en.wikipedia.org/wiki/Object_copying#Deep_copy) (clone) of the tree.

Each node in the n-ary tree contains a val (`int`) and a list (`List[Node]`) of its children.

class Node {
    public int val;
    public List children;
}

_Nary-Tree input serialization is represented in their level order traversal, each group of children is separated by the null value (See examples)._

**Example 1:**

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

**Example 2:**

**Input:** root = \[1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14\]
**Output:** \[1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14\]

**Constraints:**

*   The depth of the n-ary tree is less than or equal to `1000`.
*   The total number of nodes is between `[0, 104]`.

**Follow up:** Can your solution work for the [graph problem](https://leetcode.com/problems/clone-graph/)?

## A solution in Java

```java
public class Solution {
    public String generateTheString(int n) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < n - 1; i++) {
            sb.append('a');
        }
        if (n % 2 == 0) {
            sb.append('b');
        } else {
            sb.append('a');
        }
        return sb.toString();
    }
}
```
The algorithm constructs a string with 'n' characters, making sure that the count of every character is odd.

Here is a simple approach:
1. We start by adding 'n' times the character 'a' to the string.
2. If 'n' is odd, then the string already satisfies the condition, and we return it.
3. If 'n' is even, we change the last character of the string to 'b'. Now, the string has 'n - 1' occurrences of 'a' (which is odd) and 1 occurrence of 'b' (also odd), and then we return the string.
4. With this approach, at most, two different characters are used, and both their counts are odd, satisfying the problem conditions.

Thus, we have a valid solution with a time complexity of O(n) for string construction, and it's possible to return any of the multiple valid strings.

## A solution in C++

```cpp
#include <string>

std::string generateTheString(int n) {
    std::string result(n, 'a');
    if (n % 2 == 0) {
        result[n - 1] = 'b';
    }
    return result;
}
```
The algorithm constructs a string with 'n' characters, making sure that the count of every character is odd.

Here is a simple approach:
1. We start by adding 'n' times the character 'a' to the string.
2. If 'n' is odd, then the string already satisfies the condition, and we return it.
3. If 'n' is even, we change the last character of the string to 'b'. Now, the string has 'n - 1' occurrences of 'a' (which is odd) and 1 occurrence of 'b' (also odd), and then we return the string.
4. With this approach, at most, two different characters are used, and both their counts are odd, satisfying the problem conditions.

Thus, we have a valid solution with a time complexity of O(n) for string construction, and it's possible to return any of the multiple valid strings.

## A solution in Python

```python
def generate_the_string(n: int) -> str:
    if n % 2 == 0:
        return 'a' * (n - 1) + 'b'
    else:
        return 'a' * n
```
The algorithm constructs a string with 'n' characters, making sure that the count of every character is odd.

Here is a simple approach:
1. We start by adding 'n' times the character 'a' to the string.
2. If 'n' is odd, then the string already satisfies the condition, and we return it.
3. If 'n' is even, we change the last character of the string to 'b'. Now, the string has 'n - 1' occurrences of 'a' (which is odd) and 1 occurrence of 'b' (also odd), and then we return the string.
4. With this approach, at most, two different characters are used, and both their counts are odd, satisfying the problem conditions.

Thus, we have a valid solution with a time complexity of O(n) for string construction, and it's possible to return any of the multiple valid strings.

## A solution in Javascript

```javascript
function generateTheString(n) {
    let result = "";
    for (let i = 0; i < n - 1; i++) {
        result += 'a';
    }
    if (n % 2 === 0) {
        result += 'b';
    } else {
        result += 'a';
    }
    return result;
}
```
The algorithm constructs a string with 'n' characters, making sure that the count of every character is odd.

Here is a simple approach:
1. We start by adding 'n' times the character 'a' to the string.
2. If 'n' is odd, then the string already satisfies the condition, and we return it.
3. If 'n' is even, we change the last character of the string to 'b'. Now, the string has 'n - 1' occurrences of 'a' (which is odd) and 1 occurrence of 'b' (also odd), and then we return the string.
4. With this approach, at most, two different characters are used, and both their counts are odd, satisfying the problem conditions.

Thus, we have a valid solution with a time complexity of O(n) for string construction, and it's possible to return any of the multiple valid strings.


# Average Salary Excluding the Minimum and Maximum Salary

- slug: average-salary-excluding-the-minimum-and-maximum-salary
- difficulty: Easy

You are given an array of **unique** integers `salary` where `salary[i]` is the salary of the `ith` employee.

Return _the average salary of employees excluding the minimum and maximum salary_. Answers within `10-5` of the actual answer will be accepted.

**Example 1:**

**Input:** salary = \[4000,3000,1000,2000\]
**Output:** 2500.00000
**Explanation:** Minimum salary and maximum salary are 1000 and 4000 respectively.
Average salary excluding minimum and maximum salary is (2000+3000) / 2 = 2500

**Example 2:**

**Input:** salary = \[1000,2000,3000\]
**Output:** 2000.00000
**Explanation:** Minimum salary and maximum salary are 1000 and 3000 respectively.
Average salary excluding minimum and maximum salary is (2000) / 1 = 2000

**Constraints:**

*   `3 <= salary.length <= 100`
*   `1000 <= salary[i] <= 106`
*   All the integers of `salary` are **unique**.

## A solution in Java

```java
public int countPrefixAligned(int[] flips) {
    int count = 0;
    for (int i = 0; i < flips.length; i++) {
        if (flips[i] == i + 1) {
            count++;
        }
    }
    return count;
}
```
The algorithm iterates through the given `flips` list (or array) and, at each step, checks if the value of `flips[i]` is equal to the 1-indexed position (i.e., `i+1`). If the condition is true, it means that the bit is flipped at the correct position to make the binary string prefix-aligned at that step, so we increment the counter. At the end of the loop, the counter represents the total number of prefix-aligned steps in the flipping process.

## A solution in C++

```cpp
int countPrefixAligned(const vector<int>& flips) {
    int count = 0;
    for (int i = 0; i < flips.size(); i++) {
        if (flips[i] == i + 1) {
            count++;
        }
    }
    return count;
}
```
The algorithm iterates through the given `flips` list (or array) and, at each step, checks if the value of `flips[i]` is equal to the 1-indexed position (i.e., `i+1`). If the condition is true, it means that the bit is flipped at the correct position to make the binary string prefix-aligned at that step, so we increment the counter. At the end of the loop, the counter represents the total number of prefix-aligned steps in the flipping process.

## A solution in Python

```python
def count_prefix_aligned(flips):
    count = 0
    for i in range(len(flips)):
        if flips[i] == i + 1:
            count += 1
    return count
```
The algorithm iterates through the given `flips` list (or array) and, at each step, checks if the value of `flips[i]` is equal to the 1-indexed position (i.e., `i+1`). If the condition is true, it means that the bit is flipped at the correct position to make the binary string prefix-aligned at that step, so we increment the counter. At the end of the loop, the counter represents the total number of prefix-aligned steps in the flipping process.

## A solution in Javascript

```javascript
function countPrefixAligned(flips) {
    let count = 0;
    for (let i = 0; i < flips.length; i++) {
        if (flips[i] === i + 1) {
            count++;
        }
    }
    return count;
}
```
The algorithm iterates through the given `flips` list (or array) and, at each step, checks if the value of `flips[i]` is equal to the 1-indexed position (i.e., `i+1`). If the condition is true, it means that the bit is flipped at the correct position to make the binary string prefix-aligned at that step, so we increment the counter. At the end of the loop, the counter represents the total number of prefix-aligned steps in the flipping process.


# The kth Factor of n

- slug: the-kth-factor-of-n
- difficulty: Medium

You are given two positive integers `n` and `k`. A factor of an integer `n` is defined as an integer `i` where `n % i == 0`.

Consider a list of all factors of `n` sorted in **ascending order**, return _the_ `kth` _factor_ in this list or return `-1` if `n` has less than `k` factors.

**Example 1:**

**Input:** n = 12, k = 3
**Output:** 3
**Explanation:** Factors list is \[1, 2, 3, 4, 6, 12\], the 3rd factor is 3.

**Example 2:**

**Input:** n = 7, k = 2
**Output:** 7
**Explanation:** Factors list is \[1, 7\], the 2nd factor is 7.

**Example 3:**

**Input:** n = 4, k = 4
**Output:** -1
**Explanation:** Factors list is \[1, 2, 4\], there is only 3 factors. We should return -1.

**Constraints:**

*   `1 <= k <= n <= 1000`

**Follow up:**

Could you solve this problem in less than O(n) complexity?

## A solution in Java

```java
import java.util.*;

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 LinkedList<>());
    }
    for (int i = 0; i < n; i++) {
        if (manager[i] != -1) {
            subordinates.get(manager[i]).add(i);
        }
    }

    Queue<Pair> queue = new LinkedList<>();
    queue.offer(new Pair(headID, 0));
    int totalTime = 0;

    while (!queue.isEmpty()) {
        Pair pair = queue.poll();
        int current = pair.employeeID;
        int time = pair.time;
        totalTime = Math.max(totalTime, time);
        for (int sub : subordinates.get(current)) {
            queue.offer(new Pair(sub, time + informTime[current]));
        }
    }
    return totalTime;
}

class Pair {
    int employeeID;
    int time;

    Pair(int employeeID, int time) {
        this.employeeID = employeeID;
        this.time = time;
    }
}
```
We create a list or array of subordinates for each employee, where the indices of this list represent the employee IDs, and the values are lists of their direct subordinates' IDs. We iterate through the `manager` array and populate the `subordinates` list based on the manager of each employee.

Next, we initialize a queue with a pair or tuple, representing the `headID` employee and `0` minute, indicating the start of the process. We also initialize a `totalTime` variable with the value `0` to store the total time required to inform all employees.

We then perform a Breadth-First Search (BFS) by iterating through the queue, retrieving and processing each employee and their respective inform time. In each iteration, we update the `totalTime` with the maximum between its current value and the time of the current employee.

We then add the employee's direct subordinates to the queue with their respective total inform time calculated as the sum of the current employee's inform time and their parent employee's inform time. We repeat this process until the queue is empty.

Finally, we return the `totalTime` as the required time to inform all employees.

## A solution in C++

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

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

    std::queue<std::pair<int, int>> q;
    q.push({headID, 0});
    int totalTime = 0;

    while (!q.empty()) {
        auto [current, time] = q.front();
        q.pop();
        totalTime = std::max(totalTime, time);
        for (int sub : subordinates[current]) {
            q.push({sub, time + informTime[current]});
        }
    }
    return totalTime;
}
```
We create a list or array of subordinates for each employee, where the indices of this list represent the employee IDs, and the values are lists of their direct subordinates' IDs. We iterate through the `manager` array and populate the `subordinates` list based on the manager of each employee.

Next, we initialize a queue with a pair or tuple, representing the `headID` employee and `0` minute, indicating the start of the process. We also initialize a `totalTime` variable with the value `0` to store the total time required to inform all employees.

We then perform a Breadth-First Search (BFS) by iterating through the queue, retrieving and processing each employee and their respective inform time. In each iteration, we update the `totalTime` with the maximum between its current value and the time of the current employee.

We then add the employee's direct subordinates to the queue with their respective total inform time calculated as the sum of the current employee's inform time and their parent employee's inform time. We repeat this process until the queue is empty.

Finally, we return the `totalTime` as the required time to inform all employees.

## A solution in Python

```python
from collections import deque

def numOfMinutes(n, headID, manager, informTime):
    subordinates = {i: [] for i in range(n)}
    for i in range(n):
        if manager[i] != -1:
            subordinates[manager[i]].append(i)

    queue = deque([(headID, 0)])
    totalTime = 0

    while queue:
        current, time = queue.popleft()
        totalTime = max(totalTime, time)
        for sub in subordinates[current]:
            queue.append((sub, time + informTime[current]))

    return totalTime
```
We create a list or array of subordinates for each employee, where the indices of this list represent the employee IDs, and the values are lists of their direct subordinates' IDs. We iterate through the `manager` array and populate the `subordinates` list based on the manager of each employee.

Next, we initialize a queue with a pair or tuple, representing the `headID` employee and `0` minute, indicating the start of the process. We also initialize a `totalTime` variable with the value `0` to store the total time required to inform all employees.

We then perform a Breadth-First Search (BFS) by iterating through the queue, retrieving and processing each employee and their respective inform time. In each iteration, we update the `totalTime` with the maximum between its current value and the time of the current employee.

We then add the employee's direct subordinates to the queue with their respective total inform time calculated as the sum of the current employee's inform time and their parent employee's inform time. We repeat this process until the queue is empty.

Finally, we return the `totalTime` as the required time to inform all employees.

## A solution in Javascript

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

    const queue = [[headID, 0]];
    let totalTime = 0;

    while (queue.length) {
        const [current, time] = queue.shift();
        totalTime = Math.max(totalTime, time);
        for (const sub of subordinates[current]) {
            queue.push([sub, time + informTime[current]]);
        }
    }

    return totalTime;
}
```
We create a list or array of subordinates for each employee, where the indices of this list represent the employee IDs, and the values are lists of their direct subordinates' IDs. We iterate through the `manager` array and populate the `subordinates` list based on the manager of each employee.

Next, we initialize a queue with a pair or tuple, representing the `headID` employee and `0` minute, indicating the start of the process. We also initialize a `totalTime` variable with the value `0` to store the total time required to inform all employees.

We then perform a Breadth-First Search (BFS) by iterating through the queue, retrieving and processing each employee and their respective inform time. In each iteration, we update the `totalTime` with the maximum between its current value and the time of the current employee.

We then add the employee's direct subordinates to the queue with their respective total inform time calculated as the sum of the current employee's inform time and their parent employee's inform time. We repeat this process until the queue is empty.

Finally, we return the `totalTime` as the required time to inform all employees.


# Longest Subarray of 1's After Deleting One Element

- slug: longest-subarray-of-1s-after-deleting-one-element
- difficulty: Medium

Given a binary array `nums`, you should delete one element from it.

Return _the size of the longest non-empty subarray containing only_ `1`_'s in the resulting array_. Return `0` if there is no such subarray.

**Example 1:**

**Input:** nums = \[1,1,0,1\]
**Output:** 3
**Explanation:** After deleting the number in position 2, \[1,1,1\] contains 3 numbers with value of 1's.

**Example 2:**

**Input:** nums = \[0,1,1,1,0,1,1,0,1\]
**Output:** 5
**Explanation:** After deleting the number in position 4, \[0,1,1,1,1,1,0,1\] longest subarray with value of 1's is \[1,1,1,1,1\].

**Example 3:**

**Input:** nums = \[1,1,1\]
**Output:** 2
**Explanation:** You must delete one element.

**Constraints:**

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

## A solution in Java

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

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

private double dfs(int node, int parent, int t, int target, List<Integer>[] graph) {
    if (t == 0) {
        return node == target ? 1.0 : 0.0;
    }
    double probability = 0.0;
    for (int neighbor : graph[node]) {
        if (neighbor != parent) {
            probability += dfs(neighbor, node, t - 1, target, graph);
        }
    }
    return probability / (graph[node].size() - (parent == -1 ? 0 : 1));
}
```
The algorithm can be solved using Depth-First Search. To set up the environment, we first create an adjacency list called `graph` to represent the tree. We then perform the DFS from the first vertex, passing the parent, remaining time, target vertex, and graph as arguments.

Inside the helper function `dfs`, we have a base case when there are no more remaining seconds. In that case, we return 1.0 if the current node matches the target, otherwise, we return 0.0.

Next, we traverse the neighbors of the current node, skipping the parent node to avoid cycles. We perform DFS for each neighbor, subtracting one from the remaining time. As we recurse back, we accumulate the probability from each DFS call and divide it by the number of neighbors minus one (the parent). This correctly calculates the probability of reaching the target vertex after a certain period of time.

Finally, we return the probability from the DFS call.

## A solution in C++

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

double dfs(int node, int parent, int t, int target, vector<vector<int>>& graph) {
    if (t == 0) {
        return node == target ? 1.0 : 0.0;
    }
    double probability = 0.0;
    for (int neighbor : graph[node]) {
        if (neighbor != parent) {
            probability += dfs(neighbor, node, t - 1, target, graph);
        }
    }
    return probability / (graph[node].size() - (parent == -1 ? 0 : 1));
}

double frogPosition(int n, vector<vector<int>>& edges, int t, int target) {
    vector<vector<int>> graph(n + 1);
    for (vector<int>& edge : edges) {
        graph[edge[0]].push_back(edge[1]);
        graph[edge[1]].push_back(edge[0]);
    }
    return dfs(1, -1, t, target, graph);
}
```
The algorithm can be solved using Depth-First Search. To set up the environment, we first create an adjacency list called `graph` to represent the tree. We then perform the DFS from the first vertex, passing the parent, remaining time, target vertex, and graph as arguments.

Inside the helper function `dfs`, we have a base case when there are no more remaining seconds. In that case, we return 1.0 if the current node matches the target, otherwise, we return 0.0.

Next, we traverse the neighbors of the current node, skipping the parent node to avoid cycles. We perform DFS for each neighbor, subtracting one from the remaining time. As we recurse back, we accumulate the probability from each DFS call and divide it by the number of neighbors minus one (the parent). This correctly calculates the probability of reaching the target vertex after a certain period of time.

Finally, we return the probability from the DFS call.

## A solution in Python

```python
from collections import defaultdict

def frogPosition(n, edges, t, target):
    graph = defaultdict(list)
    for edge in edges:
        graph[edge[0]].append(edge[1])
        graph[edge[1]].append(edge[0])
    return dfs(1, -1, t, target, graph)

def dfs(node, parent, t, target, graph):
    if t == 0:
        return 1.0 if node == target else 0.0
    probability = 0.0
    for neighbor in graph[node]:
        if neighbor != parent:
            probability += dfs(neighbor, node, t - 1, target, graph)
    return probability / (len(graph[node]) - (0 if parent == -1 else 1))
```
The algorithm can be solved using Depth-First Search. To set up the environment, we first create an adjacency list called `graph` to represent the tree. We then perform the DFS from the first vertex, passing the parent, remaining time, target vertex, and graph as arguments.

Inside the helper function `dfs`, we have a base case when there are no more remaining seconds. In that case, we return 1.0 if the current node matches the target, otherwise, we return 0.0.

Next, we traverse the neighbors of the current node, skipping the parent node to avoid cycles. We perform DFS for each neighbor, subtracting one from the remaining time. As we recurse back, we accumulate the probability from each DFS call and divide it by the number of neighbors minus one (the parent). This correctly calculates the probability of reaching the target vertex after a certain period of time.

Finally, we return the probability from the DFS call.

## A solution in Javascript

```javascript
function frogPosition(n, edges, t, target) {
    const graph = Array.from({ length: n + 1 }, () => []);
    for (const edge of edges) {
        graph[edge[0]].push(edge[1]);
        graph[edge[1]].push(edge[0]);
    }
    return dfs(1, -1, t, target, graph);
}

function dfs(node, parent, t, target, graph) {
    if (t === 0) {
        return node === target ? 1.0 : 0.0;
    }
    let probability = 0.0;
    for (const neighbor of graph[node]) {
        if (neighbor !== parent) {
            probability += dfs(neighbor, node, t - 1, target, graph);
        }
    }
    return probability / (graph[node].length - (parent === -1 ? 0 : 1));
}
```
The algorithm can be solved using Depth-First Search. To set up the environment, we first create an adjacency list called `graph` to represent the tree. We then perform the DFS from the first vertex, passing the parent, remaining time, target vertex, and graph as arguments.

Inside the helper function `dfs`, we have a base case when there are no more remaining seconds. In that case, we return 1.0 if the current node matches the target, otherwise, we return 0.0.

Next, we traverse the neighbors of the current node, skipping the parent node to avoid cycles. We perform DFS for each neighbor, subtracting one from the remaining time. As we recurse back, we accumulate the probability from each DFS call and divide it by the number of neighbors minus one (the parent). This correctly calculates the probability of reaching the target vertex after a certain period of time.

Finally, we return the probability from the DFS call.


# Parallel Courses II

- slug: parallel-courses-ii
- difficulty: Hard

You are given an integer `n`, which indicates that there are `n` courses labeled from `1` to `n`. You are also given an array `relations` where `relations[i] = [prevCoursei, nextCoursei]`, representing a prerequisite relationship between course `prevCoursei` and course `nextCoursei`: course `prevCoursei` has to be taken before course `nextCoursei`. Also, you are given the integer `k`.

In one semester, you can take **at most** `k` courses as long as you have taken all the prerequisites in the **previous** semesters for the courses you are taking.

Return _the **minimum** number of semesters needed to take all courses_. The testcases will be generated such that it is possible to take every course.

**Example 1:**

**Input:** n = 4, relations = \[\[2,1\],\[3,1\],\[1,4\]\], k = 2
**Output:** 3
**Explanation:** The figure above represents the given graph.
In the first semester, you can take courses 2 and 3.
In the second semester, you can take course 1.
In the third semester, you can take course 4.

**Example 2:**

**Input:** n = 5, relations = \[\[2,1\],\[3,1\],\[4,1\],\[1,5\]\], k = 2
**Output:** 4
**Explanation:** The figure above represents the given graph.
In the first semester, you can only take courses 2 and 3 since you cannot take more than two per semester.
In the second semester, you can take course 4.
In the third semester, you can take course 1.
In the fourth semester, you can take course 5.

**Constraints:**

*   `1 <= n <= 15`
*   `1 <= k <= n`
*   `0 <= relations.length <= n * (n-1) / 2`
*   `relations[i].length == 2`
*   `1 <= prevCoursei, nextCoursei <= n`
*   `prevCoursei != nextCoursei`
*   All the pairs `[prevCoursei, nextCoursei]` are **unique**.
*   The given graph is a directed acyclic graph.

## A solution in Java

```java
import java.util.*;

public int minNumberOfSemesters(int n, int[][] relations, int k) {
    int[] indegree = new int[n + 1];
    List<List<Integer>> graph = new ArrayList<>();
    for (int i = 0; i <= n; i++) {
        graph.add(new ArrayList<>());
    }

    for (int[] relation : relations) {
        graph.get(relation[0]).add(relation[1]);
        indegree[relation[1]]++;
    }

    int semesters = 0;
    while (n > 0) {
        Queue<Integer> zero_indegree = new LinkedList<>();
        for (int i = 1; i < indegree.length; i++) {
            if (indegree[i] == 0) {
                zero_indegree.add(i);
                indegree[i] = -1;
            }
        }

        int courses = 0;
        while (!zero_indegree.isEmpty() && courses < k) {
            int curr_course = zero_indegree.poll();
            n--;

            for (int next_course : graph.get(curr_course)) {
                indegree[next_course]--;
            }
            courses++;
        }
        semesters++;
    }
    return semesters;
}
```
The algorithm uses the topological sorting approach to solve the problem.

1. First, initialize an indegree array that stores the indegree of each node (course) and a graph array, which will store the adjacency list representation of the given directed graph.

2. Iterate through the relations and construct the adjacency list and update the indegree array.

3. Initialize a variable `semesters` to keep track of the minimum number of semesters.

4. Until all courses have been taken (n > 0), perform the following steps:
   a. Initialize a queue `zero_indegree` and iterate through the indegree array to push nodes with indegree 0 into the queue. Also, mark the indegree at that position as -1 to avoid duplicates.
   b. Initialize a variable `courses` to keep track of courses taken this semester.
   c. While there are still courses to take this semester and `courses` is less than k, do the following:
      i. Dequeue a course with 0 indegree from the queue, decrease the total number of courses to be taken(n--).
      ii. Update the indegree for each next course adjacent to the dequeued course.
      iii. Increment the `courses` counter.
   d. Increment the `semesters` counter.

5. Return the `semesters` as the minimum number of semesters to take all courses.

This approach guarantees a minimal number of semesters because it first takes the courses that have no prerequisites in each semester up to the limit k, and then the courses with the least pre-requisites, making it possible to take as many courses as possible in each semester.

## A solution in C++

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

int minNumberOfSemesters(int n, vector<vector<int>>& relations, int k) {
    vector<int> indegree(n + 1, 0);
    vector<vector<int>> graph(n + 1);

    for (const auto& relation : relations) {
        graph[relation[0]].push_back(relation[1]);
        indegree[relation[1]]++;
    }

    int semesters = 0;
    while (n > 0) {
        queue<int> zero_indegree;
        for (int i = 1; i < indegree.size(); ++i) {
            if (indegree[i] == 0) {
                zero_indegree.push(i);
                indegree[i] = -1;
            }
        }

        int courses = 0;
        while (!zero_indegree.empty() && courses < k) {
            int curr_course = zero_indegree.front();
            zero_indegree.pop();
            n--;

            for (int next_course : graph[curr_course]) {
                indegree[next_course]--;
            }
            courses++;
        }
        semesters++;
    }
    return semesters;
}
```
The algorithm uses the topological sorting approach to solve the problem.

1. First, initialize an indegree array that stores the indegree of each node (course) and a graph array, which will store the adjacency list representation of the given directed graph.

2. Iterate through the relations and construct the adjacency list and update the indegree array.

3. Initialize a variable `semesters` to keep track of the minimum number of semesters.

4. Until all courses have been taken (n > 0), perform the following steps:
   a. Initialize a queue `zero_indegree` and iterate through the indegree array to push nodes with indegree 0 into the queue. Also, mark the indegree at that position as -1 to avoid duplicates.
   b. Initialize a variable `courses` to keep track of courses taken this semester.
   c. While there are still courses to take this semester and `courses` is less than k, do the following:
      i. Dequeue a course with 0 indegree from the queue, decrease the total number of courses to be taken(n--).
      ii. Update the indegree for each next course adjacent to the dequeued course.
      iii. Increment the `courses` counter.
   d. Increment the `semesters` counter.

5. Return the `semesters` as the minimum number of semesters to take all courses.

This approach guarantees a minimal number of semesters because it first takes the courses that have no prerequisites in each semester up to the limit k, and then the courses with the least pre-requisites, making it possible to take as many courses as possible in each semester.

## A solution in Python

```python
from collections import deque

def minNumberOfSemesters(n, relations, k):
    indegree = [0] * (n + 1)
    graph = [[] for _ in range(n + 1)]

    for prev_course, next_course in relations:
        graph[prev_course].append(next_course)
        indegree[next_course] += 1

    semesters = 0
    while n > 0:
        zero_indegree = deque()
        for i in range(1, len(indegree)):
            if indegree[i] == 0:
                zero_indegree.append(i)
                indegree[i] = -1

        courses = 0
        while zero_indegree and courses < k:
            curr_course = zero_indegree.popleft()
            n -= 1

            for next_course in graph[curr_course]:
                indegree[next_course] -= 1
            courses += 1
        semesters += 1
    return semesters
```
The algorithm uses the topological sorting approach to solve the problem.

1. First, initialize an indegree array that stores the indegree of each node (course) and a graph array, which will store the adjacency list representation of the given directed graph.

2. Iterate through the relations and construct the adjacency list and update the indegree array.

3. Initialize a variable `semesters` to keep track of the minimum number of semesters.

4. Until all courses have been taken (n > 0), perform the following steps:
   a. Initialize a queue `zero_indegree` and iterate through the indegree array to push nodes with indegree 0 into the queue. Also, mark the indegree at that position as -1 to avoid duplicates.
   b. Initialize a variable `courses` to keep track of courses taken this semester.
   c. While there are still courses to take this semester and `courses` is less than k, do the following:
      i. Dequeue a course with 0 indegree from the queue, decrease the total number of courses to be taken(n--).
      ii. Update the indegree for each next course adjacent to the dequeued course.
      iii. Increment the `courses` counter.
   d. Increment the `semesters` counter.

5. Return the `semesters` as the minimum number of semesters to take all courses.

This approach guarantees a minimal number of semesters because it first takes the courses that have no prerequisites in each semester up to the limit k, and then the courses with the least pre-requisites, making it possible to take as many courses as possible in each semester.

## A solution in Javascript

```javascript
function minNumberOfSemesters(n, relations, k) {
    const indegree = new Array(n + 1).fill(0);
    const graph = new Array(n + 1).fill().map(() => []);

    for (const [prevCourse, nextCourse] of relations) {
        graph[prevCourse].push(nextCourse);
        indegree[nextCourse]++;
    }

    let semesters = 0;
    while (n > 0) {
        const zero_indegree = [];
        for (let i = 1; i < indegree.length; i++) {
            if (indegree[i] === 0) {
                zero_indegree.push(i);
                indegree[i] = -1;
            }
        }

        let courses = 0;
        while (zero_indegree.length > 0 && courses < k) {
            const curr_course = zero_indegree.shift();
            n--;

            for (const next_course of graph[curr_course]) {
                indegree[next_course]--;
            }
            courses++;
        }
        semesters++;
    }
    return semesters;
}
```
The algorithm uses the topological sorting approach to solve the problem.

1. First, initialize an indegree array that stores the indegree of each node (course) and a graph array, which will store the adjacency list representation of the given directed graph.

2. Iterate through the relations and construct the adjacency list and update the indegree array.

3. Initialize a variable `semesters` to keep track of the minimum number of semesters.

4. Until all courses have been taken (n > 0), perform the following steps:
   a. Initialize a queue `zero_indegree` and iterate through the indegree array to push nodes with indegree 0 into the queue. Also, mark the indegree at that position as -1 to avoid duplicates.
   b. Initialize a variable `courses` to keep track of courses taken this semester.
   c. While there are still courses to take this semester and `courses` is less than k, do the following:
      i. Dequeue a course with 0 indegree from the queue, decrease the total number of courses to be taken(n--).
      ii. Update the indegree for each next course adjacent to the dequeued course.
      iii. Increment the `courses` counter.
   d. Increment the `semesters` counter.

5. Return the `semesters` as the minimum number of semesters to take all courses.

This approach guarantees a minimal number of semesters because it first takes the courses that have no prerequisites in each semester up to the limit k, and then the courses with the least pre-requisites, making it possible to take as many courses as possible in each semester.


# Path Crossing

- slug: path-crossing
- difficulty: Easy

Given a string `path`, where `path[i] = 'N'`, `'S'`, `'E'` or `'W'`, each representing moving one unit north, south, east, or west, respectively. You start at the origin `(0, 0)` on a 2D plane and walk on the path specified by `path`.

Return `true` _if the path crosses itself at any point, that is, if at any time you are on a location you have previously visited_. Return `false` otherwise.

**Example 1:**

**Input:** path =  "NES "
**Output:** false
**Explanation:** Notice that the path doesn't cross any point more than once.

**Example 2:**

**Input:** path =  "NESWW "
**Output:** true
**Explanation:** Notice that the path visits the origin twice.

**Constraints:**

*   `1 <= path.length <= 104`
*   `path[i]` is either `'N'`, `'S'`, `'E'`, or `'W'`.

## A solution in Java

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

public List<Integer> luckyNumbers(int[][] matrix) {
    int m = matrix.length, n = matrix[0].length;
    List<Integer> luckyNumbers = new ArrayList<>();

    for (int i = 0; i < m; i++) {
        int minRow = matrix[i][0];
        int minRowIndex = 0;
        for (int j = 0; j < n; j++) {
            if (matrix[i][j] < minRow) {
                minRow = matrix[i][j];
                minRowIndex = j;
            }
        }

        boolean isLucky = true;
        for (int k = 0; k < m; k++) {
            if (matrix[k][minRowIndex] > minRow) {
                isLucky = false;
                break;
            }
        }

        if (isLucky)
            luckyNumbers.add(minRow);
    }

    return luckyNumbers;
}
```
1. Initialize a list `lucky_numbers` to store the final lucky numbers from the matrix.
2. Iterate through all rows in the matrix, and for each row:
   - Find the minimum element `min_row` in the row and its index `min_row_idx`.
   - Check if `min_row` is the maximum element in its column `min_row_idx`. If so, add `min_row` to the list of `lucky_numbers`.
3. Return the `lucky_numbers` list.

## A solution in C++

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

vector<int> luckyNumbers(vector<vector<int>>& matrix) {
    int m = matrix.size(), n = matrix[0].size();
    vector<int> lucky_numbers;
    for (int i = 0; i < m; ++i) {
        int min_row = matrix[i][0], min_row_idx = 0;
        for (int j = 0; j < n; ++j) {
            if (matrix[i][j] < min_row) {
                min_row = matrix[i][j];
                min_row_idx = j;
            }
        }
        bool is_lucky = true;
        for (int k = 0; k < m; ++k) {
            if (matrix[k][min_row_idx] > min_row) {
                is_lucky = false;
                break;
            }
        }
        if (is_lucky)
            lucky_numbers.push_back(min_row);
    }
    return lucky_numbers;
}
```
1. Initialize a list `lucky_numbers` to store the final lucky numbers from the matrix.
2. Iterate through all rows in the matrix, and for each row:
   - Find the minimum element `min_row` in the row and its index `min_row_idx`.
   - Check if `min_row` is the maximum element in its column `min_row_idx`. If so, add `min_row` to the list of `lucky_numbers`.
3. Return the `lucky_numbers` list.

## A solution in Python

```python
def lucky_numbers(matrix):
    m, n = len(matrix), len(matrix[0])
    lucky_numbers = []

    for i in range(m):
        min_row = min(matrix[i])
        min_row_idx = matrix[i].index(min_row)
        is_lucky = all(matrix[k][min_row_idx] <= min_row for k in range(m))

        if is_lucky:
            lucky_numbers.append(min_row)

    return lucky_numbers
```
1. Initialize a list `lucky_numbers` to store the final lucky numbers from the matrix.
2. Iterate through all rows in the matrix, and for each row:
   - Find the minimum element `min_row` in the row and its index `min_row_idx`.
   - Check if `min_row` is the maximum element in its column `min_row_idx`. If so, add `min_row` to the list of `lucky_numbers`.
3. Return the `lucky_numbers` list.

## A solution in Javascript

```javascript
function luckyNumbers(matrix) {
    const m = matrix.length, n = matrix[0].length;
    const luckyNumbers = [];

    for (let i = 0; i < m; i++) {
        let minRow = matrix[i][0];
        let minRowIndex = 0;
        for (let j = 0; j < n; j++) {
            if (matrix[i][j] < minRow) {
                minRow = matrix[i][j];
                minRowIndex = j;
            }
        }

        let isLucky = true;
        for (let k = 0; k < m; k++) {
            if (matrix[k][minRowIndex] > minRow) {
                isLucky = false;
                break;
            }
        }

        if (isLucky)
            luckyNumbers.push(minRow);
    }

    return luckyNumbers;
}
```
1. Initialize a list `lucky_numbers` to store the final lucky numbers from the matrix.
2. Iterate through all rows in the matrix, and for each row:
   - Find the minimum element `min_row` in the row and its index `min_row_idx`.
   - Check if `min_row` is the maximum element in its column `min_row_idx`. If so, add `min_row` to the list of `lucky_numbers`.
3. Return the `lucky_numbers` list.


# Number of Subsequences That Satisfy the Given Sum Condition

- slug: number-of-subsequences-that-satisfy-the-given-sum-condition
- difficulty: Medium

You are given an array of integers `nums` and an integer `target`.

Return _the number of **non-empty** subsequences of_ `nums` _such that the sum of the minimum and maximum element on it is less or equal to_ `target`. Since the answer may be too large, return it **modulo** `109 + 7`.

**Example 1:**

**Input:** nums = \[3,5,6,7\], target = 9
**Output:** 4
**Explanation:** There are 4 subsequences that satisfy the condition.
\[3\] -> Min value + max value <= target (3 + 3 <= 9)
\[3,5\] -> (3 + 5 <= 9)
\[3,5,6\] -> (3 + 6 <= 9)
\[3,6\] -> (3 + 6 <= 9)

**Example 2:**

**Input:** nums = \[3,3,6,8\], target = 10
**Output:** 6
**Explanation:** There are 6 subsequences that satisfy the condition. (nums can have repeated numbers).
\[3\] , \[3\] , \[3,3\], \[3,6\] , \[3,6\] , \[3,3,6\]

**Example 3:**

**Input:** nums = \[2,3,3,4,6,7\], target = 12
**Output:** 61
**Explanation:** There are 63 non-empty subsequences, two of them do not satisfy the condition (\[6,7\], \[7\]).
Number of valid subsequences (63 - 2 = 61).

**Constraints:**

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

## A solution in Java

```java
public TreeNode getTargetCopy(TreeNode original, TreeNode cloned, TreeNode target) {
    if (original == null)
        return null;
    if (original == target)
        return cloned;

    TreeNode left = getTargetCopy(original.left, cloned.left, target);
    return left != null ? left : getTargetCopy(original.right, cloned.right, target);
}
```
The algorithm is a simple binary tree traversal using recursion. It starts at the roots of both the original and cloned trees. Since the cloned tree is an exact copy of the original, their structure is the same.

For each node, the algorithm checks:
1. If the current 'original' node is null, return null, because it means we've reached the end of a branch without finding the target.
2. If the current 'original' node is the target node, return the current 'cloned' node, as we've found the corresponding node in the cloned tree.
3. If neither condition is met, call the function recursively on both the left and right subtrees of the current nodes.

When the recursion returns a non-null result, it means the target node has been found, and the reference to the corresponding node in the cloned tree is returned. If the recursion returns null, it means the target node has not been found in the currently explored branches, and the algorithm continues searching.

## A solution in C++

```cpp
TreeNode* getTargetCopy(TreeNode* original, TreeNode* cloned, TreeNode* target) {
    if (original == nullptr)
        return nullptr;
    if (original == target)
        return cloned;

    TreeNode* left = getTargetCopy(original->left, cloned->left, target);
    return left ? left : getTargetCopy(original->right, cloned->right, target);
}
```
The algorithm is a simple binary tree traversal using recursion. It starts at the roots of both the original and cloned trees. Since the cloned tree is an exact copy of the original, their structure is the same.

For each node, the algorithm checks:
1. If the current 'original' node is null, return null, because it means we've reached the end of a branch without finding the target.
2. If the current 'original' node is the target node, return the current 'cloned' node, as we've found the corresponding node in the cloned tree.
3. If neither condition is met, call the function recursively on both the left and right subtrees of the current nodes.

When the recursion returns a non-null result, it means the target node has been found, and the reference to the corresponding node in the cloned tree is returned. If the recursion returns null, it means the target node has not been found in the currently explored branches, and the algorithm continues searching.

## A solution in Python

```python
def getTargetCopy(self, original: TreeNode, cloned: TreeNode, target: TreeNode) -> TreeNode:
    if original is None:
        return None
    if original is target:
        return cloned

    left = self.getTargetCopy(original.left, cloned.left, target)
    return left if left else self.getTargetCopy(original.right, cloned.right, target)
```
The algorithm is a simple binary tree traversal using recursion. It starts at the roots of both the original and cloned trees. Since the cloned tree is an exact copy of the original, their structure is the same.

For each node, the algorithm checks:
1. If the current 'original' node is null, return null, because it means we've reached the end of a branch without finding the target.
2. If the current 'original' node is the target node, return the current 'cloned' node, as we've found the corresponding node in the cloned tree.
3. If neither condition is met, call the function recursively on both the left and right subtrees of the current nodes.

When the recursion returns a non-null result, it means the target node has been found, and the reference to the corresponding node in the cloned tree is returned. If the recursion returns null, it means the target node has not been found in the currently explored branches, and the algorithm continues searching.

## A solution in Javascript

```javascript
function getTargetCopy(original, cloned, target) {
    if (original === null)
        return null;
    if (original === target)
        return cloned;

    let left = getTargetCopy(original.left, cloned.left, target);
    return left ? left : getTargetCopy(original.right, cloned.right, target);
}
```
The algorithm is a simple binary tree traversal using recursion. It starts at the roots of both the original and cloned trees. Since the cloned tree is an exact copy of the original, their structure is the same.

For each node, the algorithm checks:
1. If the current 'original' node is null, return null, because it means we've reached the end of a branch without finding the target.
2. If the current 'original' node is the target node, return the current 'cloned' node, as we've found the corresponding node in the cloned tree.
3. If neither condition is met, call the function recursively on both the left and right subtrees of the current nodes.

When the recursion returns a non-null result, it means the target node has been found, and the reference to the corresponding node in the cloned tree is returned. If the recursion returns null, it means the target node has not been found in the currently explored branches, and the algorithm continues searching.


# Max Value of Equation

- slug: max-value-of-equation
- difficulty: Hard

You are given an array `points` containing the coordinates of points on a 2D plane, sorted by the x-values, where `points[i] = [xi, yi]` such that `xi < xj` for all `1 <= i < j <= points.length`. You are also given an integer `k`.

Return _the maximum value of the equation_ `yi + yj + |xi - xj|` where `|xi - xj| <= k` and `1 <= i < j <= points.length`.

It is guaranteed that there exists at least one pair of points that satisfy the constraint `|xi - xj| <= k`.

**Example 1:**

**Input:** points = \[\[1,3\],\[2,0\],\[5,10\],\[6,-10\]\], k = 1
**Output:** 4
**Explanation:** The first two points satisfy the condition |xi - xj| <= 1 and if we calculate the equation we get 3 + 0 + |1 - 2| = 4. Third and fourth points also satisfy the condition and give a value of 10 + -10 + |5 - 6| = 1.
No other pairs satisfy the condition, so we return the max of 4 and 1.

**Example 2:**

**Input:** points = \[\[0,0\],\[3,0\],\[9,2\]\], k = 3
**Output:** 3
**Explanation:** Only the first two points have an absolute difference of 3 or less in the x-values, and give the value of 0 + 0 + |0 - 3| = 3.

**Constraints:**

*   `2 <= points.length <= 105`
*   `points[i].length == 2`
*   `-108 <= xi, yi <= 108`
*   `0 <= k <= 2 * 108`
*   `xi < xj` for all `1 <= i < j <= points.length`
*   `xi` form a strictly increasing sequence.

## A solution in Java

```java
import java.util.*;

class Solution {
    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]);

        long sum = 0, result = 0;
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
        for (int[] engineer : engineers) {
            if (minHeap.size() >= k) {
                sum -= minHeap.poll();
            }
            minHeap.offer(engineer[1]);
            sum += engineer[1];
            result = Math.max(result, engineer[0] * sum);
        }
        return (int) (result % 1000000007);
    }
}
```
1. Create an array of engineers where each element is a pair of efficiency and speed. Sort the array in descending order based on efficiency.
2. Initialize a sum variable to store the sum of chosen engineers' speeds, and a result variable to store the maximum performance.
3. Create and use a min heap (priority queue). Iterate through the sorted engineer array:
   a. If the size of the min heap is equal to or greater than k, remove the smallest speed from the sum and min heap.
   b. Add the engineer's speed to the min heap and the sum.
   c. Calculate the performance (current efficiency * sum) and keep track of the maximum performance.
4. Return the maximum performance modulo 10^9 + 7.

## A solution in C++

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

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

    long long sum = 0;
    long long result = 0;
    std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap;
    for (const auto& engineer : engineers) {
        if (min_heap.size() >= k) {
            sum -= min_heap.top();
            min_heap.pop();
        }
        min_heap.push(engineer.second);
        sum += engineer.second;
        result = std::max(result, engineer.first * sum);
    }
    return result % 1000000007;
}
```
1. Create an array of engineers where each element is a pair of efficiency and speed. Sort the array in descending order based on efficiency.
2. Initialize a sum variable to store the sum of chosen engineers' speeds, and a result variable to store the maximum performance.
3. Create and use a min heap (priority queue). Iterate through the sorted engineer array:
   a. If the size of the min heap is equal to or greater than k, remove the smallest speed from the sum and min heap.
   b. Add the engineer's speed to the min heap and the sum.
   c. Calculate the performance (current efficiency * sum) and keep track of the maximum performance.
4. Return the maximum performance modulo 10^9 + 7.

## A solution in Python

```python
import heapq

def max_performance(n, k, speed, efficiency):
    engineers = sorted(zip(efficiency, speed), reverse=True)

    result = 0
    sum_speed = 0
    min_heap = []
    for e, s in engineers:
        if len(min_heap) >= k:
            sum_speed -= heapq.heappop(min_heap)

        heapq.heappush(min_heap, s)
        sum_speed += s
        result = max(result, e * sum_speed)

    return result % (10**9 + 7)
```
1. Create an array of engineers where each element is a pair of efficiency and speed. Sort the array in descending order based on efficiency.
2. Initialize a sum variable to store the sum of chosen engineers' speeds, and a result variable to store the maximum performance.
3. Create and use a min heap (priority queue). Iterate through the sorted engineer array:
   a. If the size of the min heap is equal to or greater than k, remove the smallest speed from the sum and min heap.
   b. Add the engineer's speed to the min heap and the sum.
   c. Calculate the performance (current efficiency * sum) and keep track of the maximum performance.
4. Return the maximum performance modulo 10^9 + 7.

## A solution in Javascript

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

  let sum = 0, result = 0;
  const minHeap = new MinHeap();
  for (const [e, s] of engineers) {
    if (minHeap.size() >= k) {
      sum -= minHeap.poll();
    }
    minHeap.offer(s);
    sum += s;
    result = Math.max(result, e * sum);
  }

  return result % 1000000007;
}

class MinHeap {
  constructor() {
    this.data = [];
  }

  offer(value) {
    this.data.push(value);
    this._bubbleUp(this.data.length - 1);
  }

  poll() {
    if (this.data.length === 0) {
      return null;
    }
    if (this.data.length === 1) {
      return this.data.pop();
    }
    const result = this.data[0];
    this.data[0] = this.data.pop();
    this._sinkDown(0);

    return result;
  }

  size() {
    return this.data.length;
  }

  _bubbleUp(index) {
    while (index > 0) {
      const parentIndex = Math.floor((index - 1) / 2);
      const value = this.data[index];
      const parentValue = this.data[parentIndex];
      if (value >= parentValue) {
        break;
      }
      this.data[parentIndex] = value;
      this.data[index] = parentValue;
      index = parentIndex;
    }
  }

  _sinkDown(index) {
    const last = this.data.length - 1;
    while (true) {
      const leftChildIndex = index * 2 + 1;
      const rightChildIndex = leftChildIndex + 1;
      let swapIndex = index;

      if (leftChildIndex <= last && this.data[leftChildIndex] < this.data[swapIndex]) {
        swapIndex = leftChildIndex;
      }
      if (rightChildIndex <= last && this.data[rightChildIndex] < this.data[swapIndex]) {
        swapIndex = rightChildIndex;
      }
      if (swapIndex === index) {
        break;
      }
      [this.data[index], this.data[swapIndex]] = [this.data[swapIndex], this.data[index]];
      index = swapIndex;
    }
  }
}
```
1. Create an array of engineers where each element is a pair of efficiency and speed. Sort the array in descending order based on efficiency.
2. Initialize a sum variable to store the sum of chosen engineers' speeds, and a result variable to store the maximum performance.
3. Create and use a min heap (priority queue). Iterate through the sorted engineer array:
   a. If the size of the min heap is equal to or greater than k, remove the smallest speed from the sum and min heap.
   b. Add the engineer's speed to the min heap and the sum.
   c. Calculate the performance (current efficiency * sum) and keep track of the maximum performance.
4. Return the maximum performance modulo 10^9 + 7.


# Design a File Sharing System

- slug: design-a-file-sharing-system
- difficulty: Medium

We will use a file-sharing system to share a very large file which consists of `m` small **chunks** with IDs from `1` to `m`.

When users join the system, the system should assign **a unique** ID to them. The unique ID should be used **once** for each user, but when a user leaves the system, the ID can be **reused** again.

Users can request a certain chunk of the file, the system should return a list of IDs of all the users who own this chunk. If the user receives a non-empty list of IDs, they receive the requested chunk successfully.

Implement the `FileSharing` class:

*   `FileSharing(int m)` Initializes the object with a file of `m` chunks.
*   `int join(int[] ownedChunks)`: A new user joined the system owning some chunks of the file, the system should assign an id to the user which is the **smallest positive integer** not taken by any other user. Return the assigned id.
*   `void leave(int userID)`: The user with `userID` will leave the system, you cannot take file chunks from them anymore.
*   `int[] request(int userID, int chunkID)`: The user `userID` requested the file chunk with `chunkID`. Return a list of the IDs of all users that own this chunk sorted in ascending order.

**Example:**

**Input:**
\[ "FileSharing ", "join ", "join ", "join ", "request ", "request ", "leave ", "request ", "leave ", "join "\]
\[\[4\],\[\[1,2\]\],\[\[2,3\]\],\[\[4\]\],\[1,3\],\[2,2\],\[1\],\[2,1\],\[2\],\[\[\]\]\]
**Output:**
\[null,1,2,3,\[2\],\[1,2\],null,\[\],null,1\]
**Explanation:**
FileSharing fileSharing = new FileSharing(4); // We use the system to share a file of 4 chunks.

fileSharing.join(\[1, 2\]);    // A user who has chunks \[1,2\] joined the system, assign id = 1 to them and return 1.

fileSharing.join(\[2, 3\]);    // A user who has chunks \[2,3\] joined the system, assign id = 2 to them and return 2.

fileSharing.join(\[4\]);       // A user who has chunk \[4\] joined the system, assign id = 3 to them and return 3.

fileSharing.request(1, 3);   // The user with id = 1 requested the third file chunk, as only the user with id = 2 has the file, return \[2\] . Notice that user 1 now has chunks \[1,2,3\].

fileSharing.request(2, 2);   // The user with id = 2 requested the second file chunk, users with ids \[1,2\] have this chunk, thus we return \[1,2\].

fileSharing.leave(1);        // The user with id = 1 left the system, all the file chunks with them are no longer available for other users.

fileSharing.request(2, 1);   // The user with id = 2 requested the first file chunk, no one in the system has this chunk, we return empty list \[\].

fileSharing.leave(2);        // The user with id = 2 left the system.

fileSharing.join(\[\]);        // A user who doesn't have any chunks joined the system, assign id = 1 to them and return 1. Notice that ids 1 and 2 are free and we can reuse them.

**Constraints:**

*   `1 <= m <= 105`
*   `0 <= ownedChunks.length <= min(100, m)`
*   `1 <= ownedChunks[i] <= m`
*   Values of `ownedChunks` are unique.
*   `1 <= chunkID <= m`
*   `userID` is guaranteed to be a user in the system if you **assign** the IDs **correctly**.
*   At most `104` calls will be made to `join`, `leave` and `request`.
*   Each call to `leave` will have a matching call for `join`.

**Follow-up:**

*   What happens if the system identifies the user by their IP address instead of their unique ID and users disconnect and connect from the system with the same IP?
*   If the users in the system join and leave the system frequently without requesting any chunks, will your solution still be efficient?
*   If all users join the system one time, request all files, and then leave, will your solution still be efficient?
*   If the system will be used to share `n` files where the `ith` file consists of `m[i]`, what are the changes you have to make?

## A solution in Java

```java
public int countLargestGroup(int n) {
    int[] freq = new int[37];
    int maxGroupSize = 0, maxGroupCount = 0;

    for (int i = 1; i <= n; i++) {
        int sum = 0, num = i;
        while (num != 0) {
            sum += num % 10;
            num = num / 10;
        }
        freq[sum]++;
        maxGroupSize = Math.max(maxGroupSize, freq[sum]);
    }

    for (int i = 0; i < 37; i++) {
        if (freq[i] == maxGroupSize) {
            maxGroupCount++;
        }
    }

    return maxGroupCount;
}
```
We create an array `freq` to store the frequency of the sizes of the groups. Iterate through numbers 1 to `n` and calculate the sum of the digits of each number. Use this sum as an index to increment the frequency count in the array. At each step, we also update the maximum group size.

After that, we iterate through the frequency array and count the number of groups that have the maximum group size.

Finally, return the count of the largest groups.

## A solution in C++

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

int countLargestGroup(int n) {
    int freq[37] = {0}, maxGroupSize = 0, maxGroupCount = 0;

    for(int i = 1; i <= n; i++) {
        int sum = 0, num = i;
        while(num) {
            sum += num % 10;
            num /= 10;
        }
        freq[sum]++;
        maxGroupSize = max(maxGroupSize, freq[sum]);
    }

    for(int i = 0; i < 37; i++)
        if(freq[i] == maxGroupSize)
            maxGroupCount++;

    return maxGroupCount;
}
```
We create an array `freq` to store the frequency of the sizes of the groups. Iterate through numbers 1 to `n` and calculate the sum of the digits of each number. Use this sum as an index to increment the frequency count in the array. At each step, we also update the maximum group size.

After that, we iterate through the frequency array and count the number of groups that have the maximum group size.

Finally, return the count of the largest groups.

## A solution in Python

```python
def countLargestGroup(n: int) -> int:
    freq = [0] * 37
    max_group_size = 0
    max_group_count = 0

    for i in range(1, n + 1):
        _sum = sum(map(int, str(i)))
        freq[_sum] += 1
        max_group_size = max(max_group_size, freq[_sum])

    for count in freq:
        if count == max_group_size:
            max_group_count += 1

    return max_group_count
```
We create an array `freq` to store the frequency of the sizes of the groups. Iterate through numbers 1 to `n` and calculate the sum of the digits of each number. Use this sum as an index to increment the frequency count in the array. At each step, we also update the maximum group size.

After that, we iterate through the frequency array and count the number of groups that have the maximum group size.

Finally, return the count of the largest groups.

## A solution in Javascript

```javascript
function countLargestGroup(n) {
    let freq = new Array(37).fill(0);
    let maxGroupSize = 0, maxGroupCount = 0;

    for (let i = 1; i <= n; i++) {
        let sum = 0, num = i;
        while (num !== 0) {
            sum += num % 10;
            num = Math.floor(num / 10);
        }
        freq[sum]++;
        maxGroupSize = Math.max(maxGroupSize, freq[sum]);
    }

    for (let i = 0; i < 37; i++) {
        if (freq[i] === maxGroupSize) {
            maxGroupCount++;
        }
    }

    return maxGroupCount;
}
```
We create an array `freq` to store the frequency of the sizes of the groups. Iterate through numbers 1 to `n` and calculate the sum of the digits of each number. Use this sum as an index to increment the frequency count in the array. At each step, we also update the maximum group size.

After that, we iterate through the frequency array and count the number of groups that have the maximum group size.

Finally, return the count of the largest groups.


# Can Make Arithmetic Progression From Sequence

- slug: can-make-arithmetic-progression-from-sequence
- difficulty: Easy

A sequence of numbers is called an **arithmetic progression** if the difference between any two consecutive elements is the same.

Given an array of numbers `arr`, return `true` _if the array can be rearranged to form an **arithmetic progression**. Otherwise, return_ `false`.

**Example 1:**

**Input:** arr = \[3,5,1\]
**Output:** true
**Explanation:** We can reorder the elements as \[1,3,5\] or \[5,3,1\] with differences 2 and -2 respectively, between each consecutive elements.

**Example 2:**

**Input:** arr = \[1,2,4\]
**Output:** false
**Explanation:** There is no way to reorder the elements to obtain an arithmetic progression.

**Constraints:**

*   `2 <= arr.length <= 1000`
*   `-106 <= arr[i] <= 106`

## A solution in Java

```java
public boolean canConstruct(String s, int k) {
    int[] charCounts = new int[26];

    for (char c : s.toCharArray())
        charCounts[c - 'a']++;

    int oddCount = 0;
    for (int count : charCounts)
        oddCount += count % 2;

    return oddCount <= k && k <= s.length();
}
```
The algorithm counts the occurrences of each character in the input string s. For each character count, it checks if it is odd - if so, it increases the odd count.

Then, the function checks if the odd count is less than or equal to k (the number of palindrome strings required) and if k is less than or equal to the length of the input string s. If both these conditions are satisfied, the function returns true, meaning it is possible to construct k palindrome strings using all the characters in s. Otherwise, it returns false.

## A solution in C++

```cpp
bool canConstruct(std::string s, int k) {
    int char_counts[26] = {0};

    for (char c : s)
        char_counts[c - 'a']++;

    int odd_count = 0;
    for (int count : char_counts)
        odd_count += count % 2;

    return odd_count <= k && k <= s.length();
}
```
The algorithm counts the occurrences of each character in the input string s. For each character count, it checks if it is odd - if so, it increases the odd count.

Then, the function checks if the odd count is less than or equal to k (the number of palindrome strings required) and if k is less than or equal to the length of the input string s. If both these conditions are satisfied, the function returns true, meaning it is possible to construct k palindrome strings using all the characters in s. Otherwise, it returns false.

## A solution in Python

```python
def can_construct(s, k):
    char_counts = [0] * 26

    for c in s:
        char_counts[ord(c) - ord('a')] += 1

    odd_count = sum(count % 2 for count in char_counts)

    return odd_count <= k <= len(s)
```
The algorithm counts the occurrences of each character in the input string s. For each character count, it checks if it is odd - if so, it increases the odd count.

Then, the function checks if the odd count is less than or equal to k (the number of palindrome strings required) and if k is less than or equal to the length of the input string s. If both these conditions are satisfied, the function returns true, meaning it is possible to construct k palindrome strings using all the characters in s. Otherwise, it returns false.

## A solution in Javascript

```javascript
function canConstruct(s, k) {
    let charCounts = new Array(26).fill(0);

    for (let c of s)
        charCounts[c.charCodeAt(0) - 'a'.charCodeAt(0)]++;

    let oddCount = charCounts.reduce((acc, count) => acc + (count % 2), 0);

    return oddCount <= k && k <= s.length;
}
```
The algorithm counts the occurrences of each character in the input string s. For each character count, it checks if it is odd - if so, it increases the odd count.

Then, the function checks if the odd count is less than or equal to k (the number of palindrome strings required) and if k is less than or equal to the length of the input string s. If both these conditions are satisfied, the function returns true, meaning it is possible to construct k palindrome strings using all the characters in s. Otherwise, it returns false.


# Last Moment Before All Ants Fall Out of a Plank

- slug: last-moment-before-all-ants-fall-out-of-a-plank
- difficulty: Medium

We have a wooden plank of the length `n` **units**. Some ants are walking on the plank, each ant moves with a speed of **1 unit per second**. Some of the ants move to the **left**, the other move to the **right**.

When two ants moving in two **different** directions meet at some point, they change their directions and continue moving again. Assume changing directions does not take any additional time.

When an ant reaches **one end** of the plank at a time `t`, it falls out of the plank immediately.

Given an integer `n` and two integer arrays `left` and `right`, the positions of the ants moving to the left and the right, return _the moment when the last ant(s) fall out of the plank_.

**Example 1:**

**Input:** n = 4, left = \[4,3\], right = \[0,1\]
**Output:** 4
**Explanation:** In the image above:
-The ant at index 0 is named A and going to the right.
-The ant at index 1 is named B and going to the right.
-The ant at index 3 is named C and going to the left.
-The ant at index 4 is named D and going to the left.
The last moment when an ant was on the plank is t = 4 seconds. After that, it falls immediately out of the plank. (i.e., We can say that at t = 4.0000000001, there are no ants on the plank).

**Example 2:**

**Input:** n = 7, left = \[\], right = \[0,1,2,3,4,5,6,7\]
**Output:** 7
**Explanation:** All ants are going to the right, the ant at index 0 needs 7 seconds to fall.

**Example 3:**

**Input:** n = 7, left = \[0,1,2,3,4,5,6,7\], right = \[\]
**Output:** 7
**Explanation:** All ants are going to the left, the ant at index 7 needs 7 seconds to fall.

**Constraints:**

*   `1 <= n <= 104`
*   `0 <= left.length <= n + 1`
*   `0 <= left[i] <= n`
*   `0 <= right.length <= n + 1`
*   `0 <= right[i] <= n`
*   `1 <= left.length + right.length <= n + 1`
*   All values of `left` and `right` are unique, and each value can appear **only in one** of the two arrays.

## A solution in Java

```java
import java.util.Arrays;

public int maxSatisfaction(int[] satisfaction) {
    Arrays.sort(satisfaction);
    int ans = 0, total = 0, sum = 0;
    for (int i = satisfaction.length - 1; i >= 0; i--) {
        total += satisfaction[i];
        if (total > 0) {
            sum += total;
            ans = Math.max(ans, sum);
        }
    }
    return ans;
}
```
1. Sort the satisfaction array in descending order.
2. Initialize `ans`, `total`, and `sum` as zero.
3. Iterate through the satisfaction array, adding each element to `total`.
4. If `total` is greater than zero, add `total` to `sum`. Set `ans` as the maximum of `ans` and `sum`.
5. Return `ans` as the maximum sum of like-time coefficients.

## A solution in C++

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

int maxSatisfaction(std::vector<int>& satisfaction) {
    std::sort(satisfaction.begin(), satisfaction.end(), std::greater<int>());
    int ans = 0, total = 0, sum = 0;
    for (int i : satisfaction) {
        total += i;
        if (total > 0) {
            sum += total;
            ans = std::max(ans, sum);
        }
    }
    return ans;
}
```
1. Sort the satisfaction array in descending order.
2. Initialize `ans`, `total`, and `sum` as zero.
3. Iterate through the satisfaction array, adding each element to `total`.
4. If `total` is greater than zero, add `total` to `sum`. Set `ans` as the maximum of `ans` and `sum`.
5. Return `ans` as the maximum sum of like-time coefficients.

## A solution in Python

```python
def max_satisfaction(satisfaction):
    satisfaction.sort(reverse=True)
    ans = total = sum = 0
    for i in satisfaction:
        total += i
        if total > 0:
            sum += total
            ans = max(ans, sum)
    return ans
```
1. Sort the satisfaction array in descending order.
2. Initialize `ans`, `total`, and `sum` as zero.
3. Iterate through the satisfaction array, adding each element to `total`.
4. If `total` is greater than zero, add `total` to `sum`. Set `ans` as the maximum of `ans` and `sum`.
5. Return `ans` as the maximum sum of like-time coefficients.

## A solution in Javascript

```javascript
function maxSatisfaction(satisfaction) {
    satisfaction.sort((a, b) => b - a);
    let ans = 0, total = 0, sum = 0;
    for (let i of satisfaction) {
        total += i;
        if (total > 0) {
            sum += total;
            ans = Math.max(ans, sum);
        }
    }
    return ans;
}
```
1. Sort the satisfaction array in descending order.
2. Initialize `ans`, `total`, and `sum` as zero.
3. Iterate through the satisfaction array, adding each element to `total`.
4. If `total` is greater than zero, add `total` to `sum`. Set `ans` as the maximum of `ans` and `sum`.
5. Return `ans` as the maximum sum of like-time coefficients.


# Count Submatrices With All Ones

- slug: count-submatrices-with-all-ones
- difficulty: Medium

Given an `m x n` binary matrix `mat`, _return the number of **submatrices** that have all ones_.

**Example 1:**

**Input:** mat = \[\[1,0,1\],\[1,1,0\],\[1,1,0\]\]
**Output:** 13
**Explanation:**
There are 6 rectangles of side 1x1.
There are 2 rectangles of side 1x2.
There are 3 rectangles of side 2x1.
There is 1 rectangle of side 2x2.
There is 1 rectangle of side 3x1.
Total number of rectangles = 6 + 2 + 3 + 1 + 1 = 13.

**Example 2:**

**Input:** mat = \[\[0,1,1,0\],\[0,1,1,1\],\[1,1,1,0\]\]
**Output:** 24
**Explanation:**
There are 8 rectangles of side 1x1.
There are 5 rectangles of side 1x2.
There are 2 rectangles of side 1x3.
There are 4 rectangles of side 2x1.
There are 2 rectangles of side 2x2.
There are 2 rectangles of side 3x1.
There is 1 rectangle of side 3x2.
Total number of rectangles = 8 + 5 + 2 + 4 + 2 + 2 + 1 = 24.

**Constraints:**

*   `1 <= m, n <= 150`
*   `mat[i][j]` is either `0` or `1`.

## A solution in Java

```java
public int numSubmat(int[][] mat) {
    int m = mat.length, n = mat[0].length;
    int[][] dp = new int[m][n];
    int ans = 0;

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (mat[i][j] == 1) {
                dp[i][j] = j == 0 ? 1 : dp[i][j-1] + 1;
                int width = dp[i][j];
                for (int k = i; k >= 0; k--) {
                    width = Math.min(width, dp[k][j]);
                    ans += width;
                }
            }
        }
    }
    return ans;
}
```
The algorithm uses dynamic programming to solve the problem. We first create a 2D array `dp` of the same size as `mat`. Then, we iterate through each element `mat[i][j]`. If `mat[i][j]` is 1, we calculate the value of `dp[i][j]`. The value `dp[i][j]` represents the number of continuous 1s in the row from the current position to the left. Thus, `dp[i][j] = 1` if `j == 0` (i.e., this is the first element in the row), otherwise `dp[i][j] = dp[i][j-1] + 1`.

Then, we iterate from the current row `i` to the first row (0) and calculate the minimum width of the continuous 1s in the columns at position `j` for each row. The sum of these minimum widths gives the total number of submatrices containing all 1s.

Finally, the function returns the sum of all submatrices.

Time complexity: O(m * n * m) since we have to iterate through all the elements in the matrix and then again for each row from the current row to the first.
Space complexity: O(m * n) for the `dp` array.

## A solution in C++

```cpp
int numSubmat(vector<vector<int>>& mat) {
    int m = mat.size(), n = mat[0].size();
    vector<vector<int>> dp(m, vector<int>(n));
    int ans = 0;

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (mat[i][j]) {
                dp[i][j] = j == 0 ? 1 : dp[i][j-1] + 1;
                int width = dp[i][j];
                for (int k = i; k >= 0; k--) {
                    width = min(width, dp[k][j]);
                    ans += width;
                }
            }
        }
    }
    return ans;
}
```
The algorithm uses dynamic programming to solve the problem. We first create a 2D array `dp` of the same size as `mat`. Then, we iterate through each element `mat[i][j]`. If `mat[i][j]` is 1, we calculate the value of `dp[i][j]`. The value `dp[i][j]` represents the number of continuous 1s in the row from the current position to the left. Thus, `dp[i][j] = 1` if `j == 0` (i.e., this is the first element in the row), otherwise `dp[i][j] = dp[i][j-1] + 1`.

Then, we iterate from the current row `i` to the first row (0) and calculate the minimum width of the continuous 1s in the columns at position `j` for each row. The sum of these minimum widths gives the total number of submatrices containing all 1s.

Finally, the function returns the sum of all submatrices.

Time complexity: O(m * n * m) since we have to iterate through all the elements in the matrix and then again for each row from the current row to the first.
Space complexity: O(m * n) for the `dp` array.

## A solution in Python

```python
def numSubmat(mat: List[List[int]]) -> int:
    m, n = len(mat), len(mat[0])
    dp = [[0] * n for _ in range(m)]
    ans = 0

    for i in range(m):
        for j in range(n):
            if mat[i][j]:
                dp[i][j] = 1 if j == 0 else dp[i][j-1] + 1
                width = dp[i][j]
                for k in range(i, -1, -1):
                    width = min(width, dp[k][j])
                    ans += width

    return ans
```
The algorithm uses dynamic programming to solve the problem. We first create a 2D array `dp` of the same size as `mat`. Then, we iterate through each element `mat[i][j]`. If `mat[i][j]` is 1, we calculate the value of `dp[i][j]`. The value `dp[i][j]` represents the number of continuous 1s in the row from the current position to the left. Thus, `dp[i][j] = 1` if `j == 0` (i.e., this is the first element in the row), otherwise `dp[i][j] = dp[i][j-1] + 1`.

Then, we iterate from the current row `i` to the first row (0) and calculate the minimum width of the continuous 1s in the columns at position `j` for each row. The sum of these minimum widths gives the total number of submatrices containing all 1s.

Finally, the function returns the sum of all submatrices.

Time complexity: O(m * n * m) since we have to iterate through all the elements in the matrix and then again for each row from the current row to the first.
Space complexity: O(m * n) for the `dp` array.

## A solution in Javascript

```javascript
function numSubmat(mat) {
    const m = mat.length, n = mat[0].length;
    const dp = Array.from({ length: m }, () => Array.from({ length: n }, () => 0));
    let ans = 0;

    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            if (mat[i][j] === 1) {
                dp[i][j] = j === 0 ? 1 : dp[i][j-1] + 1;
                let width = dp[i][j];
                for (let k = i; k >= 0; k--) {
                    width = Math.min(width, dp[k][j]);
                    ans += width;
                }
            }
        }
    }
    return ans;
}
```
The algorithm uses dynamic programming to solve the problem. We first create a 2D array `dp` of the same size as `mat`. Then, we iterate through each element `mat[i][j]`. If `mat[i][j]` is 1, we calculate the value of `dp[i][j]`. The value `dp[i][j]` represents the number of continuous 1s in the row from the current position to the left. Thus, `dp[i][j] = 1` if `j == 0` (i.e., this is the first element in the row), otherwise `dp[i][j] = dp[i][j-1] + 1`.

Then, we iterate from the current row `i` to the first row (0) and calculate the minimum width of the continuous 1s in the columns at position `j` for each row. The sum of these minimum widths gives the total number of submatrices containing all 1s.

Finally, the function returns the sum of all submatrices.

Time complexity: O(m * n * m) since we have to iterate through all the elements in the matrix and then again for each row from the current row to the first.
Space complexity: O(m * n) for the `dp` array.


# Minimum Possible Integer After at Most K Adjacent Swaps On Digits

- slug: minimum-possible-integer-after-at-most-k-adjacent-swaps-on-digits
- difficulty: Hard

You are given a string `num` representing **the digits** of a very large integer and an integer `k`. You are allowed to swap any two adjacent digits of the integer **at most** `k` times.

Return _the minimum integer you can obtain also as a string_.

**Example 1:**

**Input:** num =  "4321 ", k = 4
**Output:**  "1342 "
**Explanation:** The steps to obtain the minimum integer from 4321 with 4 adjacent swaps are shown.

**Example 2:**

**Input:** num =  "100 ", k = 1
**Output:**  "010 "
**Explanation:** It's ok for the output to have leading zeros, but the input is guaranteed not to have any leading zeros.

**Example 3:**

**Input:** num =  "36789 ", k = 1000
**Output:**  "36789 "
**Explanation:** We can keep the number without any swaps.

**Constraints:**

*   `1 <= num.length <= 3 * 104`
*   `num` consists of only **digits** and does not contain **leading zeros**.
*   `1 <= k <= 109`

## A solution in Java

```java
import java.util.ArrayList;

public int[] createTargetArray(int[] nums, int[] index) {
    ArrayList<Integer> target = new ArrayList<>();
    for (int i = 0; i < nums.length; ++i) {
        target.add(index[i], nums[i]);
    }
    int[] result = new int[target.size()];
    for (int i = 0; i < target.size(); ++i) {
        result[i] = target.get(i);
    }
    return result;
}
```
The algorithm first initializes an empty target array (or ArrayList in Java). Then, it iterates through the nums and index arrays. At each iteration, it inserts the current number from the nums array at the position specified by the current value in the index array. This is done using the insert function in C++ and Python, the splice function in JavaScript, and the add function in Java. At the end, the target array is returned.

## A solution in C++

```cpp
#include <vector>

std::vector<int> createTargetArray(std::vector<int>& nums, std::vector<int>& index) {
    std::vector<int> target;
    for (int i = 0; i < nums.size(); ++i) {
        target.insert(target.begin() + index[i], nums[i]);
    }
    return target;
}
```
The algorithm first initializes an empty target array (or ArrayList in Java). Then, it iterates through the nums and index arrays. At each iteration, it inserts the current number from the nums array at the position specified by the current value in the index array. This is done using the insert function in C++ and Python, the splice function in JavaScript, and the add function in Java. At the end, the target array is returned.

## A solution in Python

```python
def createTargetArray(nums, index):
    target = []
    for i in range(len(nums)):
        target.insert(index[i], nums[i])
    return target
```
The algorithm first initializes an empty target array (or ArrayList in Java). Then, it iterates through the nums and index arrays. At each iteration, it inserts the current number from the nums array at the position specified by the current value in the index array. This is done using the insert function in C++ and Python, the splice function in JavaScript, and the add function in Java. At the end, the target array is returned.

## A solution in Javascript

```javascript
function createTargetArray(nums, index) {
    let target = [];
    for (let i = 0; i < nums.length; ++i) {
        target.splice(index[i], 0, nums[i]);
    }
    return target;
}
```
The algorithm first initializes an empty target array (or ArrayList in Java). Then, it iterates through the nums and index arrays. At each iteration, it inserts the current number from the nums array at the position specified by the current value in the index array. This is done using the insert function in C++ and Python, the splice function in JavaScript, and the add function in Java. At the end, the target array is returned.


# Find Root of N-Ary Tree

- slug: find-root-of-n-ary-tree
- difficulty: Medium

You are given all the nodes of an **[N-ary tree](https://leetcode.com/explore/learn/card/n-ary-tree/)** as an array of `Node` objects, where each node has a **unique value**.

Return _the **root** of the N-ary tree_.

**Custom testing:**

An N-ary tree can be serialized as represented in its level order traversal where each group of children is separated by the `null` value (see examples).

For example, the above tree is serialized as `[1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]`.

The testing will be done in the following way:

1.  The **input data** should be provided as a serialization of the tree.
2.  The driver code will construct the tree from the serialized input data and put each `Node` object into an array **in an arbitrary order**.
3.  The driver code will pass the array to `findRoot`, and your function should find and return the root `Node` object in the array.
4.  The driver code will take the returned `Node` object and serialize it. If the serialized value and the input data are the **same**, the test **passes**.

**Example 1:**

**Input:** tree = \[1,null,3,2,4,null,5,6\]
**Output:** \[1,null,3,2,4,null,5,6\]
**Explanation:** The tree from the input data is shown above.
The driver code creates the tree and gives findRoot the Node objects in an arbitrary order.
For example, the passed array could be \[Node(5),Node(4),Node(3),Node(6),Node(2),Node(1)\] or \[Node(2),Node(6),Node(1),Node(3),Node(5),Node(4)\].
The findRoot function should return the root Node(1), and the driver code will serialize it and compare with the input data.
The input data and serialized Node(1) are the same, so the test passes.

**Example 2:**

**Input:** tree = \[1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14\]
**Output:** \[1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14\]

**Constraints:**

*   The total number of nodes is between `[1, 5 * 104]`.
*   Each node has a **unique** value.

**Follow up:**

*   Could you solve this problem in constant space complexity with a linear time algorithm?

## A solution in Java

```java
class Solution {
    public Node findRoot(List<Node> nodes) {
        int valueSum = 0;

        for (Node node : nodes) {
            valueSum += node.val;

            for (Node child : node.children) {
                valueSum -= child.val;
            }
        }

        for (Node node : nodes) {
            if (node.val == valueSum) {
                return node;
            }
        }

        return null;
    }
}
```
The solution iterates over all the nodes twice. In the first iteration, the sum of the node values is calculated, and for each child node, its value is subtracted from the sum. This will result in the root value being stored in the `value_sum`. In the second iteration, we simply iterated over the nodes to find the node with the `value_sum` and return it as a root node.

This solution has a linear time complexity O(n), and the space complexity is constant as no extra data structure is being used.

## A solution in C++

```cpp
class Solution {
public:
    Node* findRoot(vector<Node*> nodes) {
        int value_sum = 0;

        for (auto& node : nodes) {
            value_sum += node->val;

            for (auto& child : node->children) {
                value_sum -= child->val;
            }
        }

        for (auto& node : nodes) {
            if (node->val == value_sum) {
                return node;
            }
        }

        return nullptr;
    }
};
```
The solution iterates over all the nodes twice. In the first iteration, the sum of the node values is calculated, and for each child node, its value is subtracted from the sum. This will result in the root value being stored in the `value_sum`. In the second iteration, we simply iterated over the nodes to find the node with the `value_sum` and return it as a root node.

This solution has a linear time complexity O(n), and the space complexity is constant as no extra data structure is being used.

## A solution in Python

```python
class Solution:
    def findRoot(self, nodes: List['Node']) -> 'Node':
        value_sum = 0

        for node in nodes:
            value_sum += node.val

            for child in node.children:
                value_sum -= child.val

        for node in nodes:
            if node.val == value_sum:
                return node

        return None
```
The solution iterates over all the nodes twice. In the first iteration, the sum of the node values is calculated, and for each child node, its value is subtracted from the sum. This will result in the root value being stored in the `value_sum`. In the second iteration, we simply iterated over the nodes to find the node with the `value_sum` and return it as a root node.

This solution has a linear time complexity O(n), and the space complexity is constant as no extra data structure is being used.

## A solution in Javascript

```javascript
class Solution {
    findRoot(nodes) {
        let valueSum = 0;

        for (let node of nodes) {
            valueSum += node.val;

            for (let child of node.children) {
                valueSum -= child.val;
            }
        }

        for (let node of nodes) {
            if (node.val === valueSum) {
                return node;
            }
        }

        return null;
    }
}
```
The solution iterates over all the nodes twice. In the first iteration, the sum of the node values is calculated, and for each child node, its value is subtracted from the sum. This will result in the root value being stored in the `value_sum`. In the second iteration, we simply iterated over the nodes to find the node with the `value_sum` and return it as a root node.

This solution has a linear time complexity O(n), and the space complexity is constant as no extra data structure is being used.