# Binary Trees With Factors

- slug: binary-trees-with-factors
- difficulty: Medium

Given an array of unique integers, `arr`, where each integer `arr[i]` is strictly greater than `1`.

We make a binary tree using these integers, and each number may be used for any number of times. Each non-leaf node's value should be equal to the product of the values of its children.

Return _the number of binary trees we can make_. The answer may be too large so return the answer **modulo** `109 + 7`.

**Example 1:**

**Input:** arr = \[2,4\]
**Output:** 3
**Explanation:** We can make these trees: `[2], [4], [4, 2, 2]`

**Example 2:**

**Input:** arr = \[2,4,5,10\]
**Output:** 7
**Explanation:** We can make these trees: `[2], [4], [5], [10], [4, 2, 2], [10, 2, 5], [10, 5, 2]`.

**Constraints:**

*   `1 <= arr.length <= 1000`
*   `2 <= arr[i] <= 109`
*   All the values of `arr` are **unique**.

## A solution in Java

```java
public boolean isPossibleToSplit(int[] nums) {
    int n = nums.length;
    int total_sum = 0;
    for (int num : nums) {
        total_sum += num;
    }

    if (total_sum % n != 0) return false;

    int target_sum = total_sum * (n / 2) / n;
    boolean[][] dp = new boolean[n / 2 + 1][target_sum + 1];
    dp[0][0] = true;

    for (int num : nums) {
        for (int count = n / 2; count >= 1; --count) {
            for (int sum = target_sum; sum >= num; --sum) {
                dp[count][sum] = dp[count][sum] || dp[count - 1][sum - num];
            }
        }
        if (dp[n / 2][target_sum]) return true;
    }

    return false;
}
```
The algorithm uses a dynamic programming approach to solve the problem. We calculate the total sum of the nums array and check if it can be divided evenly into two parts. If the sum is not divisible by the length of the array, then it is impossible to create two arrays with equal average.

Next, we create a 2D boolean dp table with dimensions `(n / 2 + 1)` by `(target_sum + 1)`. The table represents whether it's possible to create a subset with a given count of elements and a given sum. Initially, we set `dp[0][0]` to True as it represents an empty subset.

We iterate through each element in the nums array, and for each element, we check all combinations of remaining count and sum values. If we find any subset of required size and target_sum in dp table, we return True.

Once all iterations are completed and no required subsets are found, we return False, meaning it's not possible to create two arrays with equal average.

## A solution in C++

```cpp
bool isPossibleToSplit(const vector<int>& nums) {
    int n = nums.size();
    int total_sum = accumulate(nums.begin(), nums.end(), 0);

    if (total_sum % n != 0) return false;

    int target_sum = total_sum * (n / 2) / n;
    vector<vector<bool>> dp(n / 2 + 1, vector<bool>(target_sum + 1, false));
    dp[0][0] = true;

    for (int num : nums) {
        for (int count = n / 2; count >= 1; --count) {
            for (int sum = target_sum; sum >= num; --sum) {
                dp[count][sum] = dp[count][sum] || dp[count - 1][sum - num];
            }
        }
        if (dp[n / 2][target_sum]) return true;
    }

    return false;
}
```
The algorithm uses a dynamic programming approach to solve the problem. We calculate the total sum of the nums array and check if it can be divided evenly into two parts. If the sum is not divisible by the length of the array, then it is impossible to create two arrays with equal average.

Next, we create a 2D boolean dp table with dimensions `(n / 2 + 1)` by `(target_sum + 1)`. The table represents whether it's possible to create a subset with a given count of elements and a given sum. Initially, we set `dp[0][0]` to True as it represents an empty subset.

We iterate through each element in the nums array, and for each element, we check all combinations of remaining count and sum values. If we find any subset of required size and target_sum in dp table, we return True.

Once all iterations are completed and no required subsets are found, we return False, meaning it's not possible to create two arrays with equal average.

## A solution in Python

```python
def isPossibleToSplit(nums):
    n = len(nums)
    total_sum = sum(nums)

    if total_sum % n != 0:
        return False

    target_sum = total_sum * (n // 2) // n
    dp = [[False] * (target_sum + 1) for _ in range(n // 2 + 1)]
    dp[0][0] = True

    for num in nums:
        for count in range(n // 2, 0, -1):
            for sum_ in range(target_sum, num - 1, -1):
                dp[count][sum_] = dp[count][sum_] or dp[count - 1][sum_ - num]

        if dp[n // 2][target_sum]:
            return True

    return False
```
The algorithm uses a dynamic programming approach to solve the problem. We calculate the total sum of the nums array and check if it can be divided evenly into two parts. If the sum is not divisible by the length of the array, then it is impossible to create two arrays with equal average.

Next, we create a 2D boolean dp table with dimensions `(n / 2 + 1)` by `(target_sum + 1)`. The table represents whether it's possible to create a subset with a given count of elements and a given sum. Initially, we set `dp[0][0]` to True as it represents an empty subset.

We iterate through each element in the nums array, and for each element, we check all combinations of remaining count and sum values. If we find any subset of required size and target_sum in dp table, we return True.

Once all iterations are completed and no required subsets are found, we return False, meaning it's not possible to create two arrays with equal average.

## A solution in Javascript

```javascript
function isPossibleToSplit(nums) {
    const n = nums.length;
    const total_sum = nums.reduce((a, b) => a + b, 0);

    if (total_sum % n !== 0) return false;

    const target_sum = (total_sum * (n / 2)) / n;
    const dp = Array.from(Array(n / 2 + 1), () => Array(target_sum + 1).fill(false));
    dp[0][0] = true;

    for (const num of nums) {
        for (let count = n / 2; count >= 1; --count) {
            for (let sum = target_sum; sum >= num; --sum) {
                dp[count][sum] = dp[count][sum] || dp[count - 1][sum - num];
            }
        }
        if (dp[n / 2][target_sum]) return true;
    }

    return false;
}
```
The algorithm uses a dynamic programming approach to solve the problem. We calculate the total sum of the nums array and check if it can be divided evenly into two parts. If the sum is not divisible by the length of the array, then it is impossible to create two arrays with equal average.

Next, we create a 2D boolean dp table with dimensions `(n / 2 + 1)` by `(target_sum + 1)`. The table represents whether it's possible to create a subset with a given count of elements and a given sum. Initially, we set `dp[0][0]` to True as it represents an empty subset.

We iterate through each element in the nums array, and for each element, we check all combinations of remaining count and sum values. If we find any subset of required size and target_sum in dp table, we return True.

Once all iterations are completed and no required subsets are found, we return False, meaning it's not possible to create two arrays with equal average.


# Goat Latin

- slug: goat-latin
- difficulty: Easy

You are given a string `sentence` that consist of words separated by spaces. Each word consists of lowercase and uppercase letters only.

We would like to convert the sentence to "Goat Latin " (a made-up language similar to Pig Latin.) The rules of Goat Latin are as follows:

*   If a word begins with a vowel (`'a'`, `'e'`, `'i'`, `'o'`, or `'u'`), append `"ma "` to the end of the word.
    *   For example, the word `"apple "` becomes `"applema "`.
*   If a word begins with a consonant (i.e., not a vowel), remove the first letter and append it to the end, then add `"ma "`.
    *   For example, the word `"goat "` becomes `"oatgma "`.
*   Add one letter `'a'` to the end of each word per its word index in the sentence, starting with `1`.
    *   For example, the first word gets `"a "` added to the end, the second word gets `"aa "` added to the end, and so on.

Return _the final sentence representing the conversion from sentence to Goat Latin_.

**Example 1:**

**Input:** sentence = "I speak Goat Latin"
**Output:** "Imaa peaksmaaa oatGmaaaa atinLmaaaaa"

**Example 2:**

**Input:** sentence = "The quick brown fox jumped over the lazy dog"
**Output:** "heTmaa uickqmaaa rownbmaaaa oxfmaaaaa umpedjmaaaaaa overmaaaaaaa hetmaaaaaaaa azylmaaaaaaaaa ogdmaaaaaaaaaa"

**Constraints:**

*   `1 <= sentence.length <= 150`
*   `sentence` consists of English letters and spaces.
*   `sentence` has no leading or trailing spaces.
*   All the words in `sentence` are separated by a single space.

## A solution in Java

```java
public int[] numberOfLines(int[] widths, String s) {
    int lines = 1;
    int currentPixel = 0;
    for (char c : s.toCharArray()) {
        int letterPixels = widths[c - 'a'];
        if (currentPixel + letterPixels > 100) {
            lines++;
            currentPixel = 0;
        }
        currentPixel += letterPixels;
    }
    return new int[]{lines, currentPixel};
}
```
The algorithm starts by initializing two variables, `lines` and `currentPixel`. `lines` denotes the number of lines it has taken so far to type out the string `s`, and `currentPixel` stores the width of the characters typed on the current line.

The algorithm iterates through each character `c` in the input string `s`. For each character, it calculates its width in pixels by using its respective entry in the `widths` array. If the addition of the width of the character to the `currentPixel` would cause it go over 100 pixels, it increases the line count by 1, resets the `currentPixel` to 0, and continues processing the rest of the string `s`. Otherwise, add the character width to the `currentPixel`.

Finally, when the loop finishes iterating all characters in the string `s`, the algorithm returns the `lines` and `currentPixel` as a result array of length 2.

## A solution in C++

```cpp
#include <vector>
#include <string>
std::vector<int> numberOfLines(std::vector<int>& widths, std::string s) {
    int lines = 1;
    int currentPixel = 0;
    for (char c : s) {
        int letterPixels = widths[c - 'a'];
        if (currentPixel + letterPixels > 100) {
            lines++;
            currentPixel = 0;
        }
        currentPixel += letterPixels;
    }
    return {lines, currentPixel};
}
```
The algorithm starts by initializing two variables, `lines` and `currentPixel`. `lines` denotes the number of lines it has taken so far to type out the string `s`, and `currentPixel` stores the width of the characters typed on the current line.

The algorithm iterates through each character `c` in the input string `s`. For each character, it calculates its width in pixels by using its respective entry in the `widths` array. If the addition of the width of the character to the `currentPixel` would cause it go over 100 pixels, it increases the line count by 1, resets the `currentPixel` to 0, and continues processing the rest of the string `s`. Otherwise, add the character width to the `currentPixel`.

Finally, when the loop finishes iterating all characters in the string `s`, the algorithm returns the `lines` and `currentPixel` as a result array of length 2.

## A solution in Python

```python
def number_of_lines(widths, s):
    lines = 1
    current_pixel = 0
    for c in s:
        letter_pixels = widths[ord(c) - ord('a')]
        if current_pixel + letter_pixels > 100:
            lines += 1
            current_pixel = 0
        current_pixel += letter_pixels
    return [lines, current_pixel]
```
The algorithm starts by initializing two variables, `lines` and `currentPixel`. `lines` denotes the number of lines it has taken so far to type out the string `s`, and `currentPixel` stores the width of the characters typed on the current line.

The algorithm iterates through each character `c` in the input string `s`. For each character, it calculates its width in pixels by using its respective entry in the `widths` array. If the addition of the width of the character to the `currentPixel` would cause it go over 100 pixels, it increases the line count by 1, resets the `currentPixel` to 0, and continues processing the rest of the string `s`. Otherwise, add the character width to the `currentPixel`.

Finally, when the loop finishes iterating all characters in the string `s`, the algorithm returns the `lines` and `currentPixel` as a result array of length 2.

## A solution in Javascript

```javascript
function numberOfLines(widths, s) {
    let lines = 1;
    let currentPixel = 0;
    for (let c of s) {
        let letterPixels = widths[c.charCodeAt(0) - 'a'.charCodeAt(0)];
        if (currentPixel + letterPixels > 100) {
            lines++;
            currentPixel = 0;
        }
        currentPixel += letterPixels;
    }
    return [lines, currentPixel];
}
```
The algorithm starts by initializing two variables, `lines` and `currentPixel`. `lines` denotes the number of lines it has taken so far to type out the string `s`, and `currentPixel` stores the width of the characters typed on the current line.

The algorithm iterates through each character `c` in the input string `s`. For each character, it calculates its width in pixels by using its respective entry in the `widths` array. If the addition of the width of the character to the `currentPixel` would cause it go over 100 pixels, it increases the line count by 1, resets the `currentPixel` to 0, and continues processing the rest of the string `s`. Otherwise, add the character width to the `currentPixel`.

Finally, when the loop finishes iterating all characters in the string `s`, the algorithm returns the `lines` and `currentPixel` as a result array of length 2.


# Friends Of Appropriate Ages

- slug: friends-of-appropriate-ages
- difficulty: Medium

There are `n` persons on a social media website. You are given an integer array `ages` where `ages[i]` is the age of the `ith` person.

A Person `x` will not send a friend request to a person `y` (`x != y`) if any of the following conditions is true:

*   `age[y] <= 0.5 * age[x] + 7`
*   `age[y] > age[x]`
*   `age[y] > 100 && age[x] < 100`

Otherwise, `x` will send a friend request to `y`.

Note that if `x` sends a request to `y`, `y` will not necessarily send a request to `x`. Also, a person will not send a friend request to themself.

Return _the total number of friend requests made_.

**Example 1:**

**Input:** ages = \[16,16\]
**Output:** 2
**Explanation:** 2 people friend request each other.

**Example 2:**

**Input:** ages = \[16,17,18\]
**Output:** 2
**Explanation:** Friend requests are made 17 -> 16, 18 -> 17.

**Example 3:**

**Input:** ages = \[20,30,100,110,120\]
**Output:** 3
**Explanation:** Friend requests are made 110 -> 100, 120 -> 110, 120 -> 100.

**Constraints:**

*   `n == ages.length`
*   `1 <= n <= 2 * 104`
*   `1 <= ages[i] <= 120`

## A solution in Java

```java
public int maxIncreaseKeepingSkyline(int[][] grid) {
    int n = grid.length;
    int[] row_max = new int[n];
    int[] col_max = new int[n];

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            row_max[i] = Math.max(row_max[i], grid[i][j]);
            col_max[j] = Math.max(col_max[j], grid[i][j]);
        }
    }

    int total_sum = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            total_sum += Math.min(row_max[i], col_max[j]) - grid[i][j];
        }
    }

    return total_sum;
}
```
1. Find the maximum height of the buildings in each row and store them in 'row_max'.
2. Find the maximum height of the buildings in each column and store them in 'col_max'.
3. Iterate through each building in the grid and calculate the minimum of the row_max and col_max for the current building.
4. Subtract the current building height from the minimum value found in step 3 and add the result to the total_sum.
5. Return the total_sum.

## A solution in C++

```cpp
int maxIncreaseKeepingSkyline(vector<vector<int>>& grid) {
    int n = grid.size();
    vector<int> row_max(n, 0);
    vector<int> col_max(n, 0);

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            row_max[i] = max(row_max[i], grid[i][j]);
            col_max[j] = max(col_max[j], grid[i][j]);
        }
    }

    int total_sum = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            total_sum += min(row_max[i], col_max[j]) - grid[i][j];
        }
    }

    return total_sum;
}
```
1. Find the maximum height of the buildings in each row and store them in 'row_max'.
2. Find the maximum height of the buildings in each column and store them in 'col_max'.
3. Iterate through each building in the grid and calculate the minimum of the row_max and col_max for the current building.
4. Subtract the current building height from the minimum value found in step 3 and add the result to the total_sum.
5. Return the total_sum.

## A solution in Python

```python
def max_increase_keeping_skyline(grid):
    n = len(grid)
    row_max = [0] * n
    col_max = [0] * n

    for i in range(n):
        for j in range(n):
            row_max[i] = max(row_max[i], grid[i][j])
            col_max[j] = max(col_max[j], grid[i][j])

    total_sum = 0
    for i in range(n):
        for j in range(n):
            total_sum += min(row_max[i], col_max[j]) - grid[i][j]

    return total_sum
```
1. Find the maximum height of the buildings in each row and store them in 'row_max'.
2. Find the maximum height of the buildings in each column and store them in 'col_max'.
3. Iterate through each building in the grid and calculate the minimum of the row_max and col_max for the current building.
4. Subtract the current building height from the minimum value found in step 3 and add the result to the total_sum.
5. Return the total_sum.

## A solution in Javascript

```javascript
function maxIncreaseKeepingSkyline(grid) {
    const n = grid.length;
    const row_max = new Array(n).fill(0);
    const col_max = new Array(n).fill(0);

    for (let i = 0; i < n; ++i) {
        for (let j = 0; j < n; ++j) {
            row_max[i] = Math.max(row_max[i], grid[i][j]);
            col_max[j] = Math.max(col_max[j], grid[i][j]);
        }
    }

    let total_sum = 0;
    for (let i = 0; i < n; ++i) {
        for (let j = 0; j < n; ++j) {
            total_sum += Math.min(row_max[i], col_max[j]) - grid[i][j];
        }
    }

    return total_sum;
}
```
1. Find the maximum height of the buildings in each row and store them in 'row_max'.
2. Find the maximum height of the buildings in each column and store them in 'col_max'.
3. Iterate through each building in the grid and calculate the minimum of the row_max and col_max for the current building.
4. Subtract the current building height from the minimum value found in step 3 and add the result to the total_sum.
5. Return the total_sum.


# Most Profit Assigning Work

- slug: most-profit-assigning-work
- difficulty: Medium

You have `n` jobs and `m` workers. You are given three arrays: `difficulty`, `profit`, and `worker` where:

*   `difficulty[i]` and `profit[i]` are the difficulty and the profit of the `ith` job, and
*   `worker[j]` is the ability of `jth` worker (i.e., the `jth` worker can only complete a job with difficulty at most `worker[j]`).

Every worker can be assigned **at most one job**, but one job can be **completed multiple times**.

*   For example, if three workers attempt the same job that pays `$1`, then the total profit will be `$3`. If a worker cannot complete any job, their profit is `$0`.

Return the maximum profit we can achieve after assigning the workers to the jobs.

**Example 1:**

**Input:** difficulty = \[2,4,6,8,10\], profit = \[10,20,30,40,50\], worker = \[4,5,6,7\]
**Output:** 100
**Explanation:** Workers are assigned jobs of difficulty \[4,4,6,6\] and they get a profit of \[20,20,30,30\] separately.

**Example 2:**

**Input:** difficulty = \[85,47,57\], profit = \[24,66,99\], worker = \[40,25,25\]
**Output:** 0

**Constraints:**

*   `n == difficulty.length`
*   `n == profit.length`
*   `m == worker.length`
*   `1 <= n, m <= 104`
*   `1 <= difficulty[i], profit[i], worker[i] <= 105`

## A solution in Java

```java
import java.util.Arrays;

public int maxProfitAssignment(int[] difficulty, int[] profit, int[] worker) {
    int n = difficulty.length;
    int[][] jobs = new int[n][2];

    for (int i = 0; i < n; ++i) {
        jobs[i] = new int[]{difficulty[i], profit[i]};
    }

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

    int max_profit = 0;
    int total_profit = 0;
    int job_idx = 0;

    for (int w : worker) {
        while (job_idx < n && w >= jobs[job_idx][0]) {
            max_profit = Math.max(max_profit, jobs[job_idx][1]);
            job_idx++;
        }
        total_profit += max_profit;
    }

    return total_profit;
}
```
1. Combine the difficulty and profit arrays into one array, called jobs, containing pairs of the values (in JavaScript, arrays of arrays), and sort it based on the difficulty values.
2. Sort the worker array in ascending order.
3. Initially, set the max_profit and total_profit to 0, and job_idx to 0.
4. Iterate over the worker array.
   a. Inside the loop, while job_idx is less than n (number of jobs) and the current worker's ability is greater than or equal to the current job's difficulty, update the max_profit to be the maximum of the current max_profit and the current job's profit, and increment job_idx.
   b. After the inner loop, add max_profit to the total_profit.
5. Return the total_profit.

## A solution in C++

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

int maxProfitAssignment(std::vector<int>& difficulty, std::vector<int>& profit, std::vector<int>& worker) {
    int n = difficulty.size();
    std::vector<std::pair<int, int>> jobs(n);

    for (int i = 0; i < n; ++i) {
        jobs[i] = {difficulty[i], profit[i]};
    }

    std::sort(jobs.begin(), jobs.end());
    std::sort(worker.begin(), worker.end());

    int max_profit = 0;
    int total_profit = 0;
    int job_idx = 0;

    for (int w : worker) {
        while (job_idx < n && w >= jobs[job_idx].first) {
            max_profit = std::max(max_profit, jobs[job_idx].second);
            job_idx++;
        }
        total_profit += max_profit;
    }

    return total_profit;
}
```
1. Combine the difficulty and profit arrays into one array, called jobs, containing pairs of the values (in JavaScript, arrays of arrays), and sort it based on the difficulty values.
2. Sort the worker array in ascending order.
3. Initially, set the max_profit and total_profit to 0, and job_idx to 0.
4. Iterate over the worker array.
   a. Inside the loop, while job_idx is less than n (number of jobs) and the current worker's ability is greater than or equal to the current job's difficulty, update the max_profit to be the maximum of the current max_profit and the current job's profit, and increment job_idx.
   b. After the inner loop, add max_profit to the total_profit.
5. Return the total_profit.

## A solution in Python

```python
def maxProfitAssignment(difficulty, profit, worker):
    n = len(difficulty)
    jobs = sorted(zip(difficulty, profit))
    worker.sort()

    max_profit = 0
    total_profit = 0
    job_idx = 0

    for w in worker:
        while job_idx < n and w >= jobs[job_idx][0]:
            max_profit = max(max_profit, jobs[job_idx][1])
            job_idx += 1
        total_profit += max_profit

    return total_profit
```
1. Combine the difficulty and profit arrays into one array, called jobs, containing pairs of the values (in JavaScript, arrays of arrays), and sort it based on the difficulty values.
2. Sort the worker array in ascending order.
3. Initially, set the max_profit and total_profit to 0, and job_idx to 0.
4. Iterate over the worker array.
   a. Inside the loop, while job_idx is less than n (number of jobs) and the current worker's ability is greater than or equal to the current job's difficulty, update the max_profit to be the maximum of the current max_profit and the current job's profit, and increment job_idx.
   b. After the inner loop, add max_profit to the total_profit.
5. Return the total_profit.

## A solution in Javascript

```javascript
function maxProfitAssignment(difficulty, profit, worker) {
    const n = difficulty.length;
    const jobs = difficulty.map((d, i) => [d, profit[i]]).sort((a, b) => a[0] - b[0]);

    worker.sort((a, b) => a - b);

    let max_profit = 0;
    let total_profit = 0;
    let job_idx = 0;

    for (const w of worker) {
        while (job_idx < n && w >= jobs[job_idx][0]) {
            max_profit = Math.max(max_profit, jobs[job_idx][1]);
            job_idx++;
        }
        total_profit += max_profit;
    }

    return total_profit;
}
```
1. Combine the difficulty and profit arrays into one array, called jobs, containing pairs of the values (in JavaScript, arrays of arrays), and sort it based on the difficulty values.
2. Sort the worker array in ascending order.
3. Initially, set the max_profit and total_profit to 0, and job_idx to 0.
4. Iterate over the worker array.
   a. Inside the loop, while job_idx is less than n (number of jobs) and the current worker's ability is greater than or equal to the current job's difficulty, update the max_profit to be the maximum of the current max_profit and the current job's profit, and increment job_idx.
   b. After the inner loop, add max_profit to the total_profit.
5. Return the total_profit.


# Making A Large Island

- slug: making-a-large-island
- difficulty: Hard

You are given an `n x n` binary matrix `grid`. You are allowed to change **at most one** `0` to be `1`.

Return _the size of the largest **island** in_ `grid` _after applying this operation_.

An **island** is a 4-directionally connected group of `1`s.

**Example 1:**

**Input:** grid = \[\[1,0\],\[0,1\]\]
**Output:** 3
**Explanation:** Change one 0 to 1 and connect two 1s, then we get an island with area = 3.

**Example 2:**

**Input:** grid = \[\[1,1\],\[1,0\]\]
**Output:** 4
**Explanation:** Change the 0 to 1 and make the island bigger, only one island with area = 4.

**Example 3:**

**Input:** grid = \[\[1,1\],\[1,1\]\]
**Output:** 4
**Explanation:** Can't change any 0 to 1, only one island with area = 4.

**Constraints:**

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

## A solution in Java

```java
public int maxAreaOfIsland(int[][] grid) {
    int ans = 0;
    for (int i = 0; i < grid.length; ++i)
        for (int j = 0; j < grid[i].length; ++j)
            if (grid[i][j] == 0) {
                grid[i][j] = 1;
                ans = Math.max(ans, dfs(grid, i, j));
                grid[i][j] = 0;
            }
    return ans;
}

private int dfs(int[][] grid, int x, int y) {
    if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] == 0) {
        return 0;
    }
    grid[x][y] = 0;
    return dfs(grid, x - 1, y) + dfs(grid, x + 1, y) + dfs(grid, x, y - 1) + dfs(grid, x, y + 1) + 1;
}
```
The algorithm follows a Depth-First Search (DFS) approach. We iterate through each cell in the grid. If the current cell has a value of 0, we change it to 1 and call the DFS function starting from that cell. After the DFS call, we change the value back to 0.

The DFS function checks if the current position (x, y) is a valid position in the grid and if the value of the cell is 1. If not, the function returns 0. If the current cell has a value of 1, we change it to 0 to mark it as visited and make the recursive DFS calls for adjacent cells. We add 1 to the sum of return values from the recursive calls and return the result.

After performing DFS for all 0-cells, we return the maximum island size found during the process. The time complexity of this algorithm is O(n^4) since we iterate through the whole grid at each cell that has a value of 0.

## A solution in C++

```cpp
int maxAreaOfIsland(vector<vector<int>>& grid)
{
    function<int(int, int)> dfs = [&](int x, int y) {
        if (x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size() || grid[x][y] == 0) {
            return 0;
        }
        grid[x][y] = 0;
        return dfs(x - 1, y) + dfs(x + 1, y) + dfs(x, y - 1) + dfs(x, y + 1) + 1;
    };

    int ans = 0;
    for (int i = 0; i < grid.size(); ++i)
        for (int j = 0; j < grid[i].size(); ++j)
            if (grid[i][j] == 0) {
                grid[i][j] = 1;
                ans = max(ans, dfs(i, j));
                grid[i][j] = 0;
            }
    return ans;
}
```
The algorithm follows a Depth-First Search (DFS) approach. We iterate through each cell in the grid. If the current cell has a value of 0, we change it to 1 and call the DFS function starting from that cell. After the DFS call, we change the value back to 0.

The DFS function checks if the current position (x, y) is a valid position in the grid and if the value of the cell is 1. If not, the function returns 0. If the current cell has a value of 1, we change it to 0 to mark it as visited and make the recursive DFS calls for adjacent cells. We add 1 to the sum of return values from the recursive calls and return the result.

After performing DFS for all 0-cells, we return the maximum island size found during the process. The time complexity of this algorithm is O(n^4) since we iterate through the whole grid at each cell that has a value of 0.

## A solution in Python

```python
def maxAreaOfIsland(grid):
    def dfs(x, y):
        if x < 0 or x >= len(grid) or y < 0 or y >= len(grid[0]) or grid[x][y] == 0:
            return 0
        grid[x][y] = 0
        return dfs(x - 1, y) + dfs(x + 1, y) + dfs(x, y - 1) + dfs(x, y + 1) + 1

    ans = 0
    for i, row in enumerate(grid):
        for j, cell in enumerate(row):
            if cell == 0:
                grid[i][j] = 1
                ans = max(ans, dfs(i, j))
                grid[i][j] = 0
    return ans
```
The algorithm follows a Depth-First Search (DFS) approach. We iterate through each cell in the grid. If the current cell has a value of 0, we change it to 1 and call the DFS function starting from that cell. After the DFS call, we change the value back to 0.

The DFS function checks if the current position (x, y) is a valid position in the grid and if the value of the cell is 1. If not, the function returns 0. If the current cell has a value of 1, we change it to 0 to mark it as visited and make the recursive DFS calls for adjacent cells. We add 1 to the sum of return values from the recursive calls and return the result.

After performing DFS for all 0-cells, we return the maximum island size found during the process. The time complexity of this algorithm is O(n^4) since we iterate through the whole grid at each cell that has a value of 0.

## A solution in Javascript

```javascript
function maxAreaOfIsland(grid) {
    function dfs(x, y) {
        if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] === 0) {
            return 0;
        }
        grid[x][y] = 0;
        return dfs(x - 1, y) + dfs(x + 1, y) + dfs(x, y - 1) + dfs(x, y + 1) + 1;
    }

    let ans = 0;
    for (let i = 0; i < grid.length; ++i)
        for (let j = 0; j < grid[i].length; ++j)
            if (grid[i][j] === 0) {
                grid[i][j] = 1;
                ans = Math.max(ans, dfs(i, j));
                grid[i][j] = 0;
            }
    return ans;
}
```
The algorithm follows a Depth-First Search (DFS) approach. We iterate through each cell in the grid. If the current cell has a value of 0, we change it to 1 and call the DFS function starting from that cell. After the DFS call, we change the value back to 0.

The DFS function checks if the current position (x, y) is a valid position in the grid and if the value of the cell is 1. If not, the function returns 0. If the current cell has a value of 1, we change it to 0 to mark it as visited and make the recursive DFS calls for adjacent cells. We add 1 to the sum of return values from the recursive calls and return the result.

After performing DFS for all 0-cells, we return the maximum island size found during the process. The time complexity of this algorithm is O(n^4) since we iterate through the whole grid at each cell that has a value of 0.


# Count Unique Characters of All Substrings of a Given String

- slug: count-unique-characters-of-all-substrings-of-a-given-string
- difficulty: Hard

Let's define a function `countUniqueChars(s)` that returns the number of unique characters on `s`.

*   For example, calling `countUniqueChars(s)` if `s = "LEETCODE "` then `"L "`, `"T "`, `"C "`, `"O "`, `"D "` are the unique characters since they appear only once in `s`, therefore `countUniqueChars(s) = 5`.

Given a string `s`, return the sum of `countUniqueChars(t)` where `t` is a substring of `s`. The test cases are generated such that the answer fits in a 32-bit integer.

Notice that some substrings can be repeated so in this case you have to count the repeated ones too.

**Example 1:**

**Input:** s =  "ABC "
**Output:** 10
**Explanation:** All possible substrings are:  "A ", "B ", "C ", "AB ", "BC " and  "ABC ".
Every substring is composed with only unique letters.
Sum of lengths of all substring is 1 + 1 + 1 + 2 + 2 + 3 = 10

**Example 2:**

**Input:** s =  "ABA "
**Output:** 8
**Explanation:** The same as example 1, except `countUniqueChars`( "ABA ") = 1.

**Example 3:**

**Input:** s =  "LEETCODE "
**Output:** 92

**Constraints:**

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

## A solution in Java

```java
public boolean xorGame(int[] nums) {
    int xorSum = 0;
    for (int num : nums) {
        xorSum ^= num;
    }
    return xorSum == 0 || nums.length % 2 == 0;
}
```
The algorithm first calculates the bitwise XOR of all elements in the array. Then, it checks if the XOR of all elements is zero or if the total number of elements in the array is even.

If the bitwise XOR of all elements is zero, Alice wins because the game condition is already satisfied and it is her turn. If the total number of elements in the array is even, Alice wins because she can always force a situation where the bitwise XOR of the remaining elements is non-zero when it is Bob's turn to play. In all other cases, Alice will lose, and the function returns false.

## A solution in C++

```cpp
bool xorGame(const std::vector<int>& nums) {
    int xorSum = 0;
    for (int num : nums) {
        xorSum ^= num;
    }
    return xorSum == 0 || nums.size() % 2 == 0;
}
```
The algorithm first calculates the bitwise XOR of all elements in the array. Then, it checks if the XOR of all elements is zero or if the total number of elements in the array is even.

If the bitwise XOR of all elements is zero, Alice wins because the game condition is already satisfied and it is her turn. If the total number of elements in the array is even, Alice wins because she can always force a situation where the bitwise XOR of the remaining elements is non-zero when it is Bob's turn to play. In all other cases, Alice will lose, and the function returns false.

## A solution in Python

```python
def xor_game(nums: List[int]) -> bool:
    xor_sum = 0
    for num in nums:
        xor_sum ^= num
    return xor_sum == 0 or len(nums) % 2 == 0
```
The algorithm first calculates the bitwise XOR of all elements in the array. Then, it checks if the XOR of all elements is zero or if the total number of elements in the array is even.

If the bitwise XOR of all elements is zero, Alice wins because the game condition is already satisfied and it is her turn. If the total number of elements in the array is even, Alice wins because she can always force a situation where the bitwise XOR of the remaining elements is non-zero when it is Bob's turn to play. In all other cases, Alice will lose, and the function returns false.

## A solution in Javascript

```javascript
function xorGame(nums) {
    let xorSum = 0;
    for (let num of nums) {
        xorSum ^= num;
    }
    return xorSum === 0 || nums.length % 2 === 0;
}
```
The algorithm first calculates the bitwise XOR of all elements in the array. Then, it checks if the XOR of all elements is zero or if the total number of elements in the array is even.

If the bitwise XOR of all elements is zero, Alice wins because the game condition is already satisfied and it is her turn. If the total number of elements in the array is even, Alice wins because she can always force a situation where the bitwise XOR of the remaining elements is non-zero when it is Bob's turn to play. In all other cases, Alice will lose, and the function returns false.


# Consecutive Numbers Sum

- slug: consecutive-numbers-sum
- difficulty: Hard

Given an integer `n`, return _the number of ways you can write_ `n` _as the sum of consecutive positive integers._

**Example 1:**

**Input:** n = 5
**Output:** 2
**Explanation:** 5 = 2 + 3

**Example 2:**

**Input:** n = 9
**Output:** 3
**Explanation:** 9 = 4 + 5 = 2 + 3 + 4

**Example 3:**

**Input:** n = 15
**Output:** 4
**Explanation:** 15 = 8 + 7 = 4 + 5 + 6 = 1 + 2 + 3 + 4 + 5

**Constraints:**

*   `1 <= n <= 109`

## A solution in Java

```java
import java.util.*;

public List<String> subdomainVisits(String[] cpdomains) {
    Map<String, Integer> counts = new HashMap<>();
    List<String> result = new ArrayList<>();

    for (String cpdomain : cpdomains) {
        String[] info = cpdomain.split(" ");
        int count = Integer.valueOf(info[0]);
        String domain = info[1];

        for (int i = 0; i < domain.length(); ++i) {
            if (domain.charAt(i) == '.') {
                counts.put(domain.substring(i + 1), counts.getOrDefault(domain.substring(i + 1), 0) + count);
            }
        }
        counts.put(domain, counts.getOrDefault(domain, 0) + count);
    }

    for (String sub : counts.keySet()) {
        result.add("" + counts.get(sub) + " " + sub);
    }

    return result;
}
```
The algorithm iterates through the input array, splitting each string into count and domain. Then, for each domain, it looks for the period (.) character and for each period (.) found, it updates the count of the subdomain in a hash table/data structure (unordered_map/HashMap/defaultdict/object). Finally, the algorithm iterates through the counts of subdomains and formats an array in the required format to return.

## A solution in C++

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

vector<string> subdomainVisits(vector<string>& cpdomains) {
    unordered_map<string, int> counts;
    vector<string> result;

    for (const string& cpdomain : cpdomains) {
        int index = cpdomain.find(' ');
        int count = stoi(cpdomain.substr(0, index));
        string domain = cpdomain.substr(index + 1);

        for (int i = 0; i < domain.size(); ++i) {
            if (domain[i] == '.') {
                counts[domain.substr(i + 1)] += count;
            }
        }
        counts[domain] += count;
    }

    for (const auto& pair : counts) {
        result.push_back(to_string(pair.second) + ' ' + pair.first);
    }

    return result;
}
```
The algorithm iterates through the input array, splitting each string into count and domain. Then, for each domain, it looks for the period (.) character and for each period (.) found, it updates the count of the subdomain in a hash table/data structure (unordered_map/HashMap/defaultdict/object). Finally, the algorithm iterates through the counts of subdomains and formats an array in the required format to return.

## A solution in Python

```python
from collections import defaultdict

def subdomainVisits(cpdomains):
    counts = defaultdict(int)
    result = []

    for cpdomain in cpdomains:
        count, domain = cpdomain.split()
        count = int(count)

        for i in range(len(domain)):
            if domain[i] == '.':
                counts[domain[i + 1:]] += count
        counts[domain] += count

    for sub, cnt in counts.items():
        result.append(f"{cnt} {sub}")

    return result
```
The algorithm iterates through the input array, splitting each string into count and domain. Then, for each domain, it looks for the period (.) character and for each period (.) found, it updates the count of the subdomain in a hash table/data structure (unordered_map/HashMap/defaultdict/object). Finally, the algorithm iterates through the counts of subdomains and formats an array in the required format to return.

## A solution in Javascript

```javascript
function subdomainVisits(cpdomains) {
    const counts = {};
    const result = [];

    for (let cpdomain of cpdomains) {
        let [count, domain] = cpdomain.split(' ');
        count = parseInt(count);

        for (let i = 0; i < domain.length; ++i) {
            if (domain[i] === '.') {
                const sub = domain.slice(i + 1);
                counts[sub] = (counts[sub] || 0) + count;
            }
        }
        counts[domain] = (counts[domain] || 0) + count;
    }

    for (let sub in counts) {
        result.push(`${counts[sub]} ${sub}`);
    }

    return result;
}
```
The algorithm iterates through the input array, splitting each string into count and domain. Then, for each domain, it looks for the period (.) character and for each period (.) found, it updates the count of the subdomain in a hash table/data structure (unordered_map/HashMap/defaultdict/object). Finally, the algorithm iterates through the counts of subdomains and formats an array in the required format to return.


# Positions of Large Groups

- slug: positions-of-large-groups
- difficulty: Easy

In a string `s` of lowercase letters, these letters form consecutive groups of the same character.

For example, a string like `s = "abbxxxxzyy "` has the groups `"a "`, `"bb "`, `"xxxx "`, `"z "`, and `"yy "`.

A group is identified by an interval `[start, end]`, where `start` and `end` denote the start and end indices (inclusive) of the group. In the above example, `"xxxx "` has the interval `[3,6]`.

A group is considered **large** if it has 3 or more characters.

Return _the intervals of every **large** group sorted in **increasing order by start index**_.

**Example 1:**

**Input:** s =  "abbxxxxzzy "
**Output:** \[\[3,6\]\]
**Explanation:** `"xxxx " is the only` large group with start index 3 and end index 6.

**Example 2:**

**Input:** s =  "abc "
**Output:** \[\]
**Explanation:** We have groups  "a ",  "b ", and  "c ", none of which are large groups.

**Example 3:**

**Input:** s =  "abcdddeeeeaabbbcd "
**Output:** \[\[3,5\],\[6,9\],\[12,14\]\]
**Explanation:** The large groups are  "ddd ",  "eeee ", and  "bbb ".

**Constraints:**

*   `1 <= s.length <= 1000`
*   `s` contains lowercase English letters only.

## A solution in Java

```java
class Solution {
    public double largestTriangleArea(int[][] points) {
        double max_area = 0.0;
        for (int i = 0; i < points.length; ++i) {
            for (int j = i + 1; j < points.length; ++j) {
                for (int k = j + 1; k < points.length; ++k) {
                    max_area = Math.max(max_area, 0.5 * Math.abs(points[i][0] * (points[j][1] - points[k][1])
                                                              + points[j][0] * (points[k][1] - points[i][1])
                                                              + points[k][0] * (points[i][1] - points[j][1])));
                }
            }
        }
        return max_area;
    }
}
```
The algorithm computes the area of the triangle formed by any three different points in the input array. To do this, the algorithm performs the following steps:

1. Iterate through all possible unique combinations of three points (i, j, k) in the input array, with i < j < k.
2. Compute and store the area of the triangle formed by the three points using the shoelace formula: area = 0.5 * |x1(y2 - y3) + x2(y3 - y1) + x3(y1 - y2)|. The formula is derived from the determinant of a matrix.
3. Keep track of the maximum area found so far and return it after iterating through all combinations of points.

The algorithm has a time complexity of O(n^3), where n is the number of points in the input array.

## A solution in C++

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

double largestTriangleArea(vector<vector<int>>& points) {
    double max_area = 0.0;
    for (int i = 0; i < points.size(); ++i) {
        for (int j = i + 1; j < points.size(); ++j) {
            for (int k = j + 1; k < points.size(); ++k) {
                max_area = max(max_area, 0.5 * abs(points[i][0] * (points[j][1] - points[k][1])
                                                  + points[j][0] * (points[k][1] - points[i][1])
                                                  + points[k][0] * (points[i][1] - points[j][1])));
            }
        }
    }
    return max_area;
}
```
The algorithm computes the area of the triangle formed by any three different points in the input array. To do this, the algorithm performs the following steps:

1. Iterate through all possible unique combinations of three points (i, j, k) in the input array, with i < j < k.
2. Compute and store the area of the triangle formed by the three points using the shoelace formula: area = 0.5 * |x1(y2 - y3) + x2(y3 - y1) + x3(y1 - y2)|. The formula is derived from the determinant of a matrix.
3. Keep track of the maximum area found so far and return it after iterating through all combinations of points.

The algorithm has a time complexity of O(n^3), where n is the number of points in the input array.

## A solution in Python

```python
from itertools import combinations

def largestTriangleArea(points):
    return max(0.5 * abs(x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) for (x1, y1), (x2, y2), (x3, y3) in combinations(points, 3))
```
The algorithm computes the area of the triangle formed by any three different points in the input array. To do this, the algorithm performs the following steps:

1. Iterate through all possible unique combinations of three points (i, j, k) in the input array, with i < j < k.
2. Compute and store the area of the triangle formed by the three points using the shoelace formula: area = 0.5 * |x1(y2 - y3) + x2(y3 - y1) + x3(y1 - y2)|. The formula is derived from the determinant of a matrix.
3. Keep track of the maximum area found so far and return it after iterating through all combinations of points.

The algorithm has a time complexity of O(n^3), where n is the number of points in the input array.

## A solution in Javascript

```javascript
function largestTriangleArea(points) {
    let max_area = 0.0;
    for (let i = 0; i < points.length; ++i) {
        for (let j = i + 1; j < points.length; ++j) {
            for (let k = j + 1; k < points.length; ++k) {
                max_area = Math.max(max_area, 0.5 * Math.abs(points[i][0] * (points[j][1] - points[k][1])
                                                      + points[j][0] * (points[k][1] - points[i][1])
                                                      + points[k][0] * (points[i][1] - points[j][1])));
            }
        }
    }
    return max_area;
}
```
The algorithm computes the area of the triangle formed by any three different points in the input array. To do this, the algorithm performs the following steps:

1. Iterate through all possible unique combinations of three points (i, j, k) in the input array, with i < j < k.
2. Compute and store the area of the triangle formed by the three points using the shoelace formula: area = 0.5 * |x1(y2 - y3) + x2(y3 - y1) + x3(y1 - y2)|. The formula is derived from the determinant of a matrix.
3. Keep track of the maximum area found so far and return it after iterating through all combinations of points.

The algorithm has a time complexity of O(n^3), where n is the number of points in the input array.


# Masking Personal Information

- slug: masking-personal-information
- difficulty: Medium

You are given a personal information string `s`, representing either an **email address** or a **phone number**. Return _the **masked** personal information using the below rules_.

**Email address:**

An email address is:

*   A **name** consisting of uppercase and lowercase English letters, followed by
*   The `'@'` symbol, followed by
*   The **domain** consisting of uppercase and lowercase English letters with a dot `'.'` somewhere in the middle (not the first or last character).

To mask an email:

*   The uppercase letters in the **name** and **domain** must be converted to lowercase letters.
*   The middle letters of the **name** (i.e., all but the first and last letters) must be replaced by 5 asterisks `"***** "`.

**Phone number:**

A phone number is formatted as follows:

*   The phone number contains 10-13 digits.
*   The last 10 digits make up the **local number**.
*   The remaining 0-3 digits, in the beginning, make up the **country code**.
*   **Separation characters** from the set `{'+', '-', '(', ')', ' '}` separate the above digits in some way.

To mask a phone number:

*   Remove all **separation characters**.
*   The masked phone number should have the form:
    *   `"***-***-XXXX "` if the country code has 0 digits.
    *   `"+*-***-***-XXXX "` if the country code has 1 digit.
    *   `"+**-***-***-XXXX "` if the country code has 2 digits.
    *   `"+***-***-***-XXXX "` if the country code has 3 digits.
*   `"XXXX "` is the last 4 digits of the **local number**.

**Example 1:**

**Input:** s =  "LeetCode@LeetCode.com "
**Output:**  "l\*\*\*\*\*e@leetcode.com "
**Explanation:** s is an email address.
The name and domain are converted to lowercase, and the middle of the name is replaced by 5 asterisks.

**Example 2:**

**Input:** s =  "AB@qq.com "
**Output:**  "a\*\*\*\*\*b@qq.com "
**Explanation:** s is an email address.
The name and domain are converted to lowercase, and the middle of the name is replaced by 5 asterisks.
Note that even though  "ab " is 2 characters, it still must have 5 asterisks in the middle.

**Example 3:**

**Input:** s =  "1(234)567-890 "
**Output:**  "\*\*\*-\*\*\*-7890 "
**Explanation:** s is a phone number.
There are 10 digits, so the local number is 10 digits and the country code is 0 digits.
Thus, the resulting masked number is  "\*\*\*-\*\*\*-7890 ".

**Constraints:**

*   `s` is either a **valid** email or a phone number.
*   If `s` is an email:
    *   `8 <= s.length <= 40`
    *   `s` consists of uppercase and lowercase English letters and exactly one `'@'` symbol and `'.'` symbol.
*   If `s` is a phone number:
    *   `10 <= s.length <= 20`
    *   `s` consists of digits, spaces, and the symbols `'('`, `')'`, `'-'`, and `'+'`.

## A solution in Java

```java
public double largestSumOfAverages(int[] nums, int k) {
    int n = nums.length;
    double[][] memo = new double[n][k+1];
    for (double[] row : memo) {
        Arrays.fill(row, -1.0);
    }
    return maxPartitionSum(0, k, nums, memo);
}

private double maxPartitionSum(int start, int k, int[] nums, double[][] memo) {
    if (k == 1) {
        return IntStream.range(start, nums.length).mapToDouble(i -> nums[i]).sum() / (nums.length - start);
    }
    if (memo[start][k] != -1.0) {
        return memo[start][k];
    }
    double sum = 0, ans = 0;
    for (int i = start; i < nums.length - k + 1; ++i) {
        sum += nums[i];
        ans = Math.max(ans, sum / (i - start + 1) + maxPartitionSum(i + 1, k - 1, nums, memo));
    }
    memo[start][k] = ans;
    return ans;
}
```
The algorithm uses a depth-first search approach, utilizing memoization to store the previously calculated intermediate sums at every index `start` and remaining subarrays `k`. At each step, we recursively calculate the score for each partition of the subarrays and return the maximum partition sum.

1. If `k` is 1, return the average of the remaining elements in `nums`.
2. If the `memo` at the current index `start` and remaining subarrays `k` is already calculated, return the value from the memo table.
3. Iterate from the index `start` until remaining subarrays are less than or equal to the length of `nums`, and update the maximum score found so far.
4. After exiting the loop, store the maximum score in the memo table and return it.

## A solution in C++

```cpp
double maxPartitionSum(int start, int k, const vector<int>& nums, vector<vector<double>>& memo) {
    if (k == 1) {
        return (accumulate(nums.begin()+start, nums.end(), 0.0)) / (nums.size() - start);
    }
    if (memo[start][k] != -1.0) {
        return memo[start][k];
    }
    double sum = 0, ans = 0;
    for (int i = start; i < nums.size() - k + 1; ++i) {
        sum += nums[i];
        ans = max(ans, sum / (i - start + 1) + maxPartitionSum(i + 1, k - 1, nums, memo));
    }
    memo[start][k] = ans;
    return ans;
}

double largestSumOfAverages(vector<int>& nums, int k) {
    int n = nums.size();
    vector<vector<double>> memo(n, vector<double>(k+1, -1.0));
    return maxPartitionSum(0, k, nums, memo);
}
```
The algorithm uses a depth-first search approach, utilizing memoization to store the previously calculated intermediate sums at every index `start` and remaining subarrays `k`. At each step, we recursively calculate the score for each partition of the subarrays and return the maximum partition sum.

1. If `k` is 1, return the average of the remaining elements in `nums`.
2. If the `memo` at the current index `start` and remaining subarrays `k` is already calculated, return the value from the memo table.
3. Iterate from the index `start` until remaining subarrays are less than or equal to the length of `nums`, and update the maximum score found so far.
4. After exiting the loop, store the maximum score in the memo table and return it.

## A solution in Python

```python
class Solution:
    def largestSumOfAverages(self, nums: List[int], k: int) -> float:
        memo = {}

        def max_partition_sum(start: int, k: int) -> float:
            if k == 1:
                return sum(nums[start:]) / (len(nums) - start)
            if (start, k) in memo:
                return memo[start, k]

            ans, curr_sum = 0, 0
            for i in range(start, len(nums) - k + 1):
                curr_sum += nums[i]
                ans = max(ans, curr_sum / (i - start + 1) + max_partition_sum(i + 1, k - 1))

            memo[start, k] = ans
            return ans

        return max_partition_sum(0, k)
```
The algorithm uses a depth-first search approach, utilizing memoization to store the previously calculated intermediate sums at every index `start` and remaining subarrays `k`. At each step, we recursively calculate the score for each partition of the subarrays and return the maximum partition sum.

1. If `k` is 1, return the average of the remaining elements in `nums`.
2. If the `memo` at the current index `start` and remaining subarrays `k` is already calculated, return the value from the memo table.
3. Iterate from the index `start` until remaining subarrays are less than or equal to the length of `nums`, and update the maximum score found so far.
4. After exiting the loop, store the maximum score in the memo table and return it.

## A solution in Javascript

```javascript
function largestSumOfAverages(nums, k) {
    const memo = Array.from(Array(nums.length), () => Array(k + 1).fill(-1));
    return maxPartitionSum(0, k, nums, memo);
}

function maxPartitionSum(start, k, nums, memo) {
    if (k === 1) {
        return nums.slice(start).reduce((sum, n) => sum + n) / (nums.length - start);
    }
    if (memo[start][k] !== -1) {
        return memo[start][k];
    }
    let sum = 0, ans = 0;
    for (let i = start; i < nums.length - k + 1; ++i) {
        sum += nums[i];
        ans = Math.max(ans, sum / (i - start + 1) + maxPartitionSum(i + 1, k - 1, nums, memo));
    }
    memo[start][k] = ans;
    return ans;
}
```
The algorithm uses a depth-first search approach, utilizing memoization to store the previously calculated intermediate sums at every index `start` and remaining subarrays `k`. At each step, we recursively calculate the score for each partition of the subarrays and return the maximum partition sum.

1. If `k` is 1, return the average of the remaining elements in `nums`.
2. If the `memo` at the current index `start` and remaining subarrays `k` is already calculated, return the value from the memo table.
3. Iterate from the index `start` until remaining subarrays are less than or equal to the length of `nums`, and update the maximum score found so far.
4. After exiting the loop, store the maximum score in the memo table and return it.


# Flipping an Image

- slug: flipping-an-image
- difficulty: Easy

Given an `n x n` binary matrix `image`, flip the image **horizontally**, then invert it, and return _the resulting image_.

To flip an image horizontally means that each row of the image is reversed.

*   For example, flipping `[1,1,0]` horizontally results in `[0,1,1]`.

To invert an image means that each `0` is replaced by `1`, and each `1` is replaced by `0`.

*   For example, inverting `[0,1,1]` results in `[1,0,0]`.

**Example 1:**

**Input:** image = \[\[1,1,0\],\[1,0,1\],\[0,0,0\]\]
**Output:** \[\[1,0,0\],\[0,1,0\],\[1,1,1\]\]
**Explanation:** First reverse each row: \[\[0,1,1\],\[1,0,1\],\[0,0,0\]\].
Then, invert the image: \[\[1,0,0\],\[0,1,0\],\[1,1,1\]\]

**Example 2:**

**Input:** image = \[\[1,1,0,0\],\[1,0,0,1\],\[0,1,1,1\],\[1,0,1,0\]\]
**Output:** \[\[1,1,0,0\],\[0,1,1,0\],\[0,0,0,1\],\[1,0,1,0\]\]
**Explanation:** First reverse each row: \[\[0,0,1,1\],\[1,0,0,1\],\[1,1,1,0\],\[0,1,0,1\]\].
Then invert the image: \[\[1,1,0,0\],\[0,1,1,0\],\[0,0,0,1\],\[1,0,1,0\]\]

**Constraints:**

*   `n == image.length`
*   `n == image[i].length`
*   `1 <= n <= 20`
*   `images[i][j]` is either `0` or `1`.

## A solution in Java

```java
public TreeNode pruneTree(TreeNode root) {
    if (root == null) return null;
    root.left = pruneTree(root.left);
    root.right = pruneTree(root.right);
    if (root.val == 0 && root.left == null && root.right == null) return null;
    return root;
}
```
The algorithm uses a depth first search approach to traverse the given binary tree recursively. When traversing the tree, the function checks if a node has a value of 1 or has any child nodes with a value of 1.

In the base case, if the current node is null, return null.

For each node, the algorithm first checks its left and right subtrees using height-depth traversal through recursion. After checking its left and right subtrees, if the current node has a value of 0 and has no left or right child nodes, the function returns null, effectively pruning the subtree. If any part of the subtree has a value of 1, then the recursion returns the root of that subtree.

In the end, the algorithm returns the root of the pruned binary tree.

## A solution in C++

```cpp
TreeNode* pruneTree(TreeNode* root) {
    if (!root) return nullptr;
    root->left = pruneTree(root->left);
    root->right = pruneTree(root->right);
    if (root->val == 0 && !root->left && !root->right) return nullptr;
    return root;
}
```
The algorithm uses a depth first search approach to traverse the given binary tree recursively. When traversing the tree, the function checks if a node has a value of 1 or has any child nodes with a value of 1.

In the base case, if the current node is null, return null.

For each node, the algorithm first checks its left and right subtrees using height-depth traversal through recursion. After checking its left and right subtrees, if the current node has a value of 0 and has no left or right child nodes, the function returns null, effectively pruning the subtree. If any part of the subtree has a value of 1, then the recursion returns the root of that subtree.

In the end, the algorithm returns the root of the pruned binary tree.

## A solution in Python

```python
def pruneTree(root: TreeNode) -> TreeNode:
    if not root:
        return None
    root.left = pruneTree(root.left)
    root.right = pruneTree(root.right)
    if root.val == 0 and not root.left and not root.right:
        return None
    return root
```
The algorithm uses a depth first search approach to traverse the given binary tree recursively. When traversing the tree, the function checks if a node has a value of 1 or has any child nodes with a value of 1.

In the base case, if the current node is null, return null.

For each node, the algorithm first checks its left and right subtrees using height-depth traversal through recursion. After checking its left and right subtrees, if the current node has a value of 0 and has no left or right child nodes, the function returns null, effectively pruning the subtree. If any part of the subtree has a value of 1, then the recursion returns the root of that subtree.

In the end, the algorithm returns the root of the pruned binary tree.

## A solution in Javascript

```javascript
function pruneTree(root) {
    if (!root) return null;
    root.left = pruneTree(root.left);
    root.right = pruneTree(root.right);
    if (root.val === 0 && !root.left && !root.right) return null;
    return root;
}
```
The algorithm uses a depth first search approach to traverse the given binary tree recursively. When traversing the tree, the function checks if a node has a value of 1 or has any child nodes with a value of 1.

In the base case, if the current node is null, return null.

For each node, the algorithm first checks its left and right subtrees using height-depth traversal through recursion. After checking its left and right subtrees, if the current node has a value of 0 and has no left or right child nodes, the function returns null, effectively pruning the subtree. If any part of the subtree has a value of 1, then the recursion returns the root of that subtree.

In the end, the algorithm returns the root of the pruned binary tree.


# Find And Replace in String

- slug: find-and-replace-in-string
- difficulty: Medium

You are given a **0-indexed** string `s` that you must perform `k` replacement operations on. The replacement operations are given as three **0-indexed** parallel arrays, `indices`, `sources`, and `targets`, all of length `k`.

To complete the `ith` replacement operation:

1.  Check if the **substring** `sources[i]` occurs at index `indices[i]` in the **original string** `s`.
2.  If it does not occur, **do nothing**.
3.  Otherwise if it does occur, **replace** that substring with `targets[i]`.

For example, if `s = "abcd "`, `indices[i] = 0`, `sources[i] = "ab "`, and `targets[i] = "eee "`, then the result of this replacement will be `"eeecd "`.

All replacement operations must occur **simultaneously**, meaning the replacement operations should not affect the indexing of each other. The testcases will be generated such that the replacements will **not overlap**.

*   For example, a testcase with `s = "abc "`, `indices = [0, 1]`, and `sources = [ "ab ", "bc "]` will not be generated because the `"ab "` and `"bc "` replacements overlap.

Return _the **resulting string** after performing all replacement operations on_ `s`.

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

**Example 1:**

**Input:** s =  "abcd ", indices = \[0, 2\], sources = \[ "a ",  "cd "\], targets = \[ "eee ",  "ffff "\]
**Output:**  "eeebffff "
**Explanation:**
 "a " occurs at index 0 in s, so we replace it with  "eee ".
 "cd " occurs at index 2 in s, so we replace it with  "ffff ".

**Example 2:**

**Input:** s =  "abcd ", indices = \[0, 2\], sources = \[ "ab ", "ec "\], targets = \[ "eee ", "ffff "\]
**Output:**  "eeecd "
**Explanation:**
 "ab " occurs at index 0 in s, so we replace it with  "eee ".
 "ec " does not occur at index 2 in s, so we do nothing.

**Constraints:**

*   `1 <= s.length <= 1000`
*   `k == indices.length == sources.length == targets.length`
*   `1 <= k <= 100`
*   `0 <= indexes[i] < s.length`
*   `1 <= sources[i].length, targets[i].length <= 50`
*   `s` consists of only lowercase English letters.
*   `sources[i]` and `targets[i]` consist of only lowercase English letters.

## A solution in Java

```java
import java.util.*;

public int numBusesToDestination(int[][] routes, int source, int target) {
    if (source == target) return 0;

    Map<Integer, Set<Integer>> stopToBuses = new HashMap<>();
    for (int i = 0; i < routes.length; ++i) {
        for (int stop : routes[i]) {
            stopToBuses.computeIfAbsent(stop, k -> new HashSet<Integer>()).add(i);
        }
    }

    Queue<Integer> q = new LinkedList<>();
    Set<Integer> visitedBuses = new HashSet<>();
    int numBuses = 0;
    q.add(source);

    while (!q.isEmpty()) {
        int size = q.size();
        while (size-- > 0) {
            int stop = q.poll();
            for (int bus : stopToBuses.get(stop)) {
                if (visitedBuses.contains(bus)) continue;
                visitedBuses.add(bus);
                for (int nextStop : routes[bus]) {
                    if (nextStop == target) return numBuses + 1;
                    q.add(nextStop);
                }
            }
        }
        numBuses++;
    }

    return -1;
}
```
1. Create a hashmap to map each bus stop to its respective bus routes.
2. Initialize a queue and visitedBuses set to perform BFS, and add the source bus stop to the queue.
3. Perform BFS:
  a. Take the first element(bus stop) in the queue.
  b. Iterate through all buses passing through the current bus stop.
  c. If the bus route is visited, skip it. Else, mark it visited and go through all the bus stops belonging to it.
  d. If the next bus stop is the target, return the current number of buses taken + 1.
  e. Put the next bus stop into the queue.
4. If we haven't found the target, return -1.

## A solution in C++

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

int numBusesToDestination(std::vector<std::vector<int>>& routes, int source, int target) {
    if (source == target) return 0;

    std::unordered_map<int, std::unordered_set<int>> stopToBuses;
    for (int i = 0; i < routes.size(); ++i) {
        for (int stop : routes[i]) {
            stopToBuses[stop].insert(i);
        }
    }

    std::queue<int> q;
    std::unordered_set<int> visitedBuses;
    int numBuses = 0;
    q.push(source);

    while (!q.empty()) {
        int size = q.size();
        while (size--) {
            int stop = q.front();
            q.pop();
            for (int bus : stopToBuses[stop]) {
                if (visitedBuses.count(bus)) continue;
                visitedBuses.insert(bus);
                for (int nextStop : routes[bus]) {
                    if (nextStop == target) return numBuses + 1;
                    q.push(nextStop);
                }
            }
        }
        numBuses++;
    }

    return -1;
}
```
1. Create a hashmap to map each bus stop to its respective bus routes.
2. Initialize a queue and visitedBuses set to perform BFS, and add the source bus stop to the queue.
3. Perform BFS:
  a. Take the first element(bus stop) in the queue.
  b. Iterate through all buses passing through the current bus stop.
  c. If the bus route is visited, skip it. Else, mark it visited and go through all the bus stops belonging to it.
  d. If the next bus stop is the target, return the current number of buses taken + 1.
  e. Put the next bus stop into the queue.
4. If we haven't found the target, return -1.

## A solution in Python

```python
from collections import defaultdict
from queue import Queue

def numBusesToDestination(routes, source, target):
    if source == target:
        return 0

    stop_to_buses = defaultdict(set)
    for i, route in enumerate(routes):
        for stop in route:
            stop_to_buses[stop].add(i)

    q = Queue()
    visited_buses = set()
    num_buses = 0
    q.put(source)

    while not q.empty():
        size = q.qsize()
        for _ in range(size):
            stop = q.get()
            for bus in stop_to_buses[stop]:
                if bus in visited_buses:
                    continue
                visited_buses.add(bus)
                for next_stop in routes[bus]:
                    if next_stop == target:
                        return num_buses + 1
                    q.put(next_stop)
        num_buses += 1

    return -1
```
1. Create a hashmap to map each bus stop to its respective bus routes.
2. Initialize a queue and visitedBuses set to perform BFS, and add the source bus stop to the queue.
3. Perform BFS:
  a. Take the first element(bus stop) in the queue.
  b. Iterate through all buses passing through the current bus stop.
  c. If the bus route is visited, skip it. Else, mark it visited and go through all the bus stops belonging to it.
  d. If the next bus stop is the target, return the current number of buses taken + 1.
  e. Put the next bus stop into the queue.
4. If we haven't found the target, return -1.

## A solution in Javascript

```javascript
function numBusesToDestination(routes, source, target) {
    if (source === target) return 0;

    const stopToBuses = new Map();
    for (let i = 0; i < routes.length; ++i) {
        for (const stop of routes[i]) {
            if (!stopToBuses.has(stop)) {
                stopToBuses.set(stop, new Set());
            }
            stopToBuses.get(stop).add(i);
        }
    }

    const q = [];
    const visitedBuses = new Set();
    let numBuses = 0;
    q.push(source);

    while (q.length > 0) {
        const size = q.length;
        for (let i = 0; i < size; ++i) {
            const stop = q.shift();
            for (const bus of stopToBuses.get(stop)) {
                if (visitedBuses.has(bus)) continue;
                visitedBuses.add(bus);
                for (const nextStop of routes[bus]) {
                    if (nextStop === target) return numBuses + 1;
                    q.push(nextStop);
                }
            }
        }
        numBuses++;
    }

    return -1;
}
```
1. Create a hashmap to map each bus stop to its respective bus routes.
2. Initialize a queue and visitedBuses set to perform BFS, and add the source bus stop to the queue.
3. Perform BFS:
  a. Take the first element(bus stop) in the queue.
  b. Iterate through all buses passing through the current bus stop.
  c. If the bus route is visited, skip it. Else, mark it visited and go through all the bus stops belonging to it.
  d. If the next bus stop is the target, return the current number of buses taken + 1.
  e. Put the next bus stop into the queue.
4. If we haven't found the target, return -1.


# Sum of Distances in Tree

- slug: sum-of-distances-in-tree
- difficulty: Hard

There is an undirected connected tree with `n` nodes labeled from `0` to `n - 1` and `n - 1` edges.

You are given the integer `n` and the array `edges` where `edges[i] = [ai, bi]` indicates that there is an edge between nodes `ai` and `bi` in the tree.

Return an array `answer` of length `n` where `answer[i]` is the sum of the distances between the `ith` node in the tree and all other nodes.

**Example 1:**

**Input:** n = 6, edges = \[\[0,1\],\[0,2\],\[2,3\],\[2,4\],\[2,5\]\]
**Output:** \[8,12,6,10,10,10\]
**Explanation:** The tree is shown above.
We can see that dist(0,1) + dist(0,2) + dist(0,3) + dist(0,4) + dist(0,5)
equals 1 + 1 + 2 + 2 + 2 = 8.
Hence, answer\[0\] = 8, and so on.

**Example 2:**

**Input:** n = 1, edges = \[\]
**Output:** \[0\]

**Example 3:**

**Input:** n = 2, edges = \[\[1,0\]\]
**Output:** \[1,1\]

**Constraints:**

*   `1 <= n <= 3 * 104`
*   `edges.length == n - 1`
*   `edges[i].length == 2`
*   `0 <= ai, bi < n`
*   `ai != bi`
*   The given input represents a valid tree.

## A solution in Java

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

public List<String> ambiguousCoordinates(String s) {
    int n = s.length();
    List<String> res = new ArrayList<>();

    for (int i = 2; i < n - 1; i++) {
        List<String> first = generateNumber(s.substring(1, i));
        List<String> second = generateNumber(s.substring(i, n - 1));

        for (String f : first) {
            for (String sec : second) {
                res.add("(" + f + ", " + sec + ")");
            }
        }
    }
    return res;
}

private List<String> generateNumber(String s) {
    int n = s.length();
    List<String> res = new ArrayList<>();

    if (n == 0 || (n > 1 && s.charAt(0) == '0' && s.charAt(n - 1) == '0')) return res;
    if (n > 1 && s.charAt(0) == '0') {
        res.add("0." + s.substring(1));
        return res;
    }
    res.add(s);
    if (n == 1 || s.charAt(n - 1) == '0') return res;

    for (int i = 1; i < n; i++) {
        res.add(s.substring(0, i) + "." + s.substring(i));
    }
    return res;
}
```
1. Iterate over the string except the first and the last characters to create pairs of valid numbers.
2. In the `generateNumber()` function, handle four cases:
    a. If the length of the string is 0 or both the first and last characters are '0', then return an empty list.
    b. If the first character is '0', return a list with the number having a decimal point after the first character.
    c. If the last character is '0' or the string has only one digit, return a list with only the given string as the number.
    d. Otherwise, create numbers by placing a decimal point at every valid position between digits of the string.
3. Combine all valid pairs of numbers and return the final answer in the format of a list of strings.

## A solution in C++

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

std::vector<std::string> ambiguousCoordinates(std::string s) {
    int n = s.size();
    std::vector<std::string> res;

    for (int i = 2; i < n - 1; ++i) {
        auto first = generateNumber(s.substr(1, i - 1));
        auto second = generateNumber(s.substr(i, n - 1 - i));

        for (const auto& f : first) {
            for (const auto& sec : second) {
                res.push_back("(" + f + ", " + sec + ")");
            }
        }
    }
    return res;
}

std::vector<std::string> generateNumber(const std::string& s) {
    int n = s.size();
    std::vector<std::string> res;

    if (n == 0 || (n > 1 && s[0] == '0' && s[n - 1] == '0')) return res;
    if (n > 1 && s[0] == '0') {
        res.push_back("0." + s.substr(1));
        return res;
    }
    res.push_back(s);
    if (n == 1 || s[n - 1] == '0') return res;

    for (int i = 1; i < n; ++i) {
        res.push_back(s.substr(0, i) + "." + s.substr(i));
    }
    return res;
}
```
1. Iterate over the string except the first and the last characters to create pairs of valid numbers.
2. In the `generateNumber()` function, handle four cases:
    a. If the length of the string is 0 or both the first and last characters are '0', then return an empty list.
    b. If the first character is '0', return a list with the number having a decimal point after the first character.
    c. If the last character is '0' or the string has only one digit, return a list with only the given string as the number.
    d. Otherwise, create numbers by placing a decimal point at every valid position between digits of the string.
3. Combine all valid pairs of numbers and return the final answer in the format of a list of strings.

## A solution in Python

```python
def ambiguousCoordinates(s):
    def generateNumber(s):
        if not s or (len(s) > 1 and s[0] == '0' and s[-1] == '0'):
            return []
        if len(s) > 1 and s[0] == '0':
            return ["0." + s[1:]]
        res = [s]
        if len(s) == 1 or s[-1] == '0':
            return res
        for i in range(1, len(s)):
            res.append(s[:i] + "." + s[i:])
        return res

    n = len(s)
    res = []

    for i in range(2, n - 1):
        first = generateNumber(s[1:i])
        second = generateNumber(s[i:n - 1])

        for f in first:
            for sec in second:
                res.append("(" + f + ", " + sec + ")")

    return res
```
1. Iterate over the string except the first and the last characters to create pairs of valid numbers.
2. In the `generateNumber()` function, handle four cases:
    a. If the length of the string is 0 or both the first and last characters are '0', then return an empty list.
    b. If the first character is '0', return a list with the number having a decimal point after the first character.
    c. If the last character is '0' or the string has only one digit, return a list with only the given string as the number.
    d. Otherwise, create numbers by placing a decimal point at every valid position between digits of the string.
3. Combine all valid pairs of numbers and return the final answer in the format of a list of strings.

## A solution in Javascript

```javascript
function ambiguousCoordinates(s) {
    function generateNumber(s) {
        if (s.length === 0 || (s.length > 1 && s[0] === '0' && s[s.length - 1] === '0')) {
            return [];
        }
        if (s.length > 1 && s[0] === '0') {
            return ["0." + s.slice(1)];
        }
        let res = [s];
        if (s.length === 1 || s[s.length - 1] === '0') {
            return res;
        }
        for (let i = 1; i < s.length; i++) {
            res.push(s.slice(0, i) + "." + s.slice(i));
        }
        return res;
    }

    let n = s.length;
    let res = [];

    for (let i = 2; i < n - 1; i++) {
        let first = generateNumber(s.slice(1, i));
        let second = generateNumber(s.slice(i, n - 1));

        for (let f of first) {
            for (let sec of second) {
                res.push("(" + f + ", " + sec + ")");
            }
        }
    }
    return res;
}
```
1. Iterate over the string except the first and the last characters to create pairs of valid numbers.
2. In the `generateNumber()` function, handle four cases:
    a. If the length of the string is 0 or both the first and last characters are '0', then return an empty list.
    b. If the first character is '0', return a list with the number having a decimal point after the first character.
    c. If the last character is '0' or the string has only one digit, return a list with only the given string as the number.
    d. Otherwise, create numbers by placing a decimal point at every valid position between digits of the string.
3. Combine all valid pairs of numbers and return the final answer in the format of a list of strings.


# Image Overlap

- slug: image-overlap
- difficulty: Medium

You are given two images, `img1` and `img2`, represented as binary, square matrices of size `n x n`. A binary matrix has only `0`s and `1`s as values.

We **translate** one image however we choose by sliding all the `1` bits left, right, up, and/or down any number of units. We then place it on top of the other image. We can then calculate the **overlap** by counting the number of positions that have a `1` in **both** images.

Note also that a translation does **not** include any kind of rotation. Any `1` bits that are translated outside of the matrix borders are erased.

Return _the largest possible overlap_.

**Example 1:**

**Input:** img1 = \[\[1,1,0\],\[0,1,0\],\[0,1,0\]\], img2 = \[\[0,0,0\],\[0,1,1\],\[0,0,1\]\]
**Output:** 3
**Explanation:** We translate img1 to right by 1 unit and down by 1 unit.

The number of positions that have a 1 in both images is 3 (shown in red).

**Example 2:**

**Input:** img1 = \[\[1\]\], img2 = \[\[1\]\]
**Output:** 1

**Example 3:**

**Input:** img1 = \[\[0\]\], img2 = \[\[0\]\]
**Output:** 0

**Constraints:**

*   `n == img1.length == img1[i].length`
*   `n == img2.length == img2[i].length`
*   `1 <= n <= 30`
*   `img1[i][j]` is either `0` or `1`.
*   `img2[i][j]` is either `0` or `1`.

## A solution in Java

```java
public class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}

public int numComponents(ListNode head, int[] nums) {
    Set<Integer> numSet = new HashSet<>();
    for (int num : nums) {
        numSet.add(num);
    }

    int result = 0;
    boolean connected = false;

    while (head != null) {
        if (numSet.contains(head.val)) {
            if (!connected) {
                connected = true;
                result++;
            }
        } else {
            connected = false;
        }
        head = head.next;
    }

    return result;
}
```
Algorithm:
1. Create a set of nums.
2. Initialize result to 0 and a flag, connected, to false.
3. Traverse the linked list.
   - If the current node's value is in the set,
      - Check if connected is false,
         - Set connected to true and increment result.
   - Else, set connected to false.
4. Return the result.

## A solution in C++

```cpp
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(nullptr) {}
};

int numComponents(ListNode* head, vector<int>& nums) {
    unordered_set<int> num_set(nums.begin(), nums.end());
    int result = 0;
    bool connected = false;

    while (head) {
        if (num_set.find(head->val) != num_set.end()) {
            if (!connected) {
                connected = true;
                result++;
            }
        } else {
            connected = false;
        }
        head = head->next;
    }

    return result;
}
```
Algorithm:
1. Create a set of nums.
2. Initialize result to 0 and a flag, connected, to false.
3. Traverse the linked list.
   - If the current node's value is in the set,
      - Check if connected is false,
         - Set connected to true and increment result.
   - Else, set connected to false.
4. Return the result.

## A solution in Python

```python
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def numComponents(head: ListNode, nums: List[int]) -> int:
    num_set = set(nums)
    result = 0
    connected = False

    while head:
        if head.val in num_set:
            if not connected:
                connected = True
                result += 1
        else:
            connected = False
        head = head.next

    return result
```
Algorithm:
1. Create a set of nums.
2. Initialize result to 0 and a flag, connected, to false.
3. Traverse the linked list.
   - If the current node's value is in the set,
      - Check if connected is false,
         - Set connected to true and increment result.
   - Else, set connected to false.
4. Return the result.

## A solution in Javascript

```javascript
class ListNode {
    constructor(val, next = null) {
        this.val = val;
        this.next = next;
    }
}

function numComponents(head, nums) {
    const numSet = new Set(nums);
    let result = 0;
    let connected = false;

    while (head !== null) {
        if (numSet.has(head.val)) {
            if (!connected) {
                connected = true;
                result++;
            }
        } else {
            connected = false;
        }
        head = head.next;
    }

    return result;
}
```
Algorithm:
1. Create a set of nums.
2. Initialize result to 0 and a flag, connected, to false.
3. Traverse the linked list.
   - If the current node's value is in the set,
      - Check if connected is false,
         - Set connected to true and increment result.
   - Else, set connected to false.
4. Return the result.


# Rectangle Overlap

- slug: rectangle-overlap
- difficulty: Easy

An axis-aligned rectangle is represented as a list `[x1, y1, x2, y2]`, where `(x1, y1)` is the coordinate of its bottom-left corner, and `(x2, y2)` is the coordinate of its top-right corner. Its top and bottom edges are parallel to the X-axis, and its left and right edges are parallel to the Y-axis.

Two rectangles overlap if the area of their intersection is **positive**. To be clear, two rectangles that only touch at the corner or edges do not overlap.

Given two axis-aligned rectangles `rec1` and `rec2`, return `true` _if they overlap, otherwise return_ `false`.

**Example 1:**

**Input:** rec1 = \[0,0,2,2\], rec2 = \[1,1,3,3\]
**Output:** true

**Example 2:**

**Input:** rec1 = \[0,0,1,1\], rec2 = \[1,0,2,1\]
**Output:** false

**Example 3:**

**Input:** rec1 = \[0,0,1,1\], rec2 = \[2,2,3,3\]
**Output:** false

**Constraints:**

*   `rec1.length == 4`
*   `rec2.length == 4`
*   `-109 <= rec1[i], rec2[i] <= 109`
*   `rec1` and `rec2` represent a valid rectangle with a non-zero area.

## A solution in Java

```java
public int racecar(int target) {
    return racecar(target, new HashMap<>());
}

public int racecar(int target, Map<String, Integer> memo) {
    return dp(0, 1, target, memo);
}

public int dp(int pos, int speed, int target, Map<String, Integer> memo) {
    if (Math.abs(pos) > 2 * target)
        return Integer.MAX_VALUE - 1;

    if (pos == target)
        return 0;

    String key = pos + "," + speed;
    if (memo.containsKey(key))
        return memo.get(key);

    int op1 = dp(pos + speed, speed * 2, target, memo) + 1;
    int op2 = dp(pos, -speed, target, memo) + 2;

    int ans = Math.min(op1, op2);
    memo.put(key, ans);
    return ans;
}
```
The algorithm for solving this problem consists of a dynamic programming approach. We define a helper function called `dp` that receives the current position, speed, target and memoization Map.

1. Starting from position 0 and speed 1, we use the DP function that uses memoization to find the shortest sequence of instructions.
2. If the current position is equal to the target position, return 0 as no additional operations are needed.
3. If the absolute value of the current position exceeds twice the target position, we return a large number as the cost of the current path.
4. We check two operations at each recursive call: accelerating (moving with the current speed) and reversing (changing the sign of the speed). We calculate the cost for each operation, adding 1 for acceleration and 2 for reversing.
5. We return the minimum cost from these operations and memoize this minimum cost for the current position and speed.
6. Finally, the algorithm will return the shortest sequence of instructions to reach the target position by adding 1 outside of the DP function.

## A solution in C++

```cpp
int racecar(int target) {
    unordered_map<int, unordered_map<int, int>> memo;
    function<int(int, int)> dp = [&](int pos, int speed) {
        if (pos == target) return 0;
        if (abs(pos) > 2 * target) return INT_MAX;

        int &ans = memo[pos][speed];
        if (ans) return ans;

        if (speed == -1) {
            int op1 = dp(pos + speed, 2 * speed) + 1;
            int op2 = dp(pos, -speed) + 2;

            ans = min(op1, op2);
        } else {
            int op1 = dp(pos - speed, -2 * speed) + 1;
            int op2 = dp(pos, -speed) + 2;

            ans = min(op1, op2);
        }

        return ans;
    };

    return dp(0, target) + 1;
}
```
The algorithm for solving this problem consists of a dynamic programming approach. We define a helper function called `dp` that receives the current position, speed, target and memoization Map.

1. Starting from position 0 and speed 1, we use the DP function that uses memoization to find the shortest sequence of instructions.
2. If the current position is equal to the target position, return 0 as no additional operations are needed.
3. If the absolute value of the current position exceeds twice the target position, we return a large number as the cost of the current path.
4. We check two operations at each recursive call: accelerating (moving with the current speed) and reversing (changing the sign of the speed). We calculate the cost for each operation, adding 1 for acceleration and 2 for reversing.
5. We return the minimum cost from these operations and memoize this minimum cost for the current position and speed.
6. Finally, the algorithm will return the shortest sequence of instructions to reach the target position by adding 1 outside of the DP function.

## A solution in Python

```python
def racecar(target: int) -> int:
    memo = {}

    def dp(pos: int, speed: int) -> int:
        if pos == target:
            return 0
        if abs(pos) > 2 * target:
            return float('inf')

        key = (pos, speed)
        if key in memo:
            return memo[key]

        op1 = dp(pos + speed, speed * 2) + 1
        op2 = dp(pos, -speed) + 2

        ans = min(op1, op2)
        memo[key] = ans
        return ans

    return dp(0, 1)
```
The algorithm for solving this problem consists of a dynamic programming approach. We define a helper function called `dp` that receives the current position, speed, target and memoization Map.

1. Starting from position 0 and speed 1, we use the DP function that uses memoization to find the shortest sequence of instructions.
2. If the current position is equal to the target position, return 0 as no additional operations are needed.
3. If the absolute value of the current position exceeds twice the target position, we return a large number as the cost of the current path.
4. We check two operations at each recursive call: accelerating (moving with the current speed) and reversing (changing the sign of the speed). We calculate the cost for each operation, adding 1 for acceleration and 2 for reversing.
5. We return the minimum cost from these operations and memoize this minimum cost for the current position and speed.
6. Finally, the algorithm will return the shortest sequence of instructions to reach the target position by adding 1 outside of the DP function.

## A solution in Javascript

```javascript
function racecar(target) {
    return dp(0, 1, target, new Map());
}

function dp(position, speed, target, memo) {
    if (Math.abs(position) > 2 * target)
        return Infinity - 1;

    if (position === target)
        return 0;

    let key = position + "," + speed;
    if (memo.has(key))
        return memo.get(key);

    let op1 = dp(position + speed, speed * 2, target, memo) + 1;
    let op2 = dp(position, -speed, target, memo) + 2;

    let ans = Math.min(op1, op2);
    memo.set(key, ans);
    return ans;
}
```
The algorithm for solving this problem consists of a dynamic programming approach. We define a helper function called `dp` that receives the current position, speed, target and memoization Map.

1. Starting from position 0 and speed 1, we use the DP function that uses memoization to find the shortest sequence of instructions.
2. If the current position is equal to the target position, return 0 as no additional operations are needed.
3. If the absolute value of the current position exceeds twice the target position, we return a large number as the cost of the current path.
4. We check two operations at each recursive call: accelerating (moving with the current speed) and reversing (changing the sign of the speed). We calculate the cost for each operation, adding 1 for acceleration and 2 for reversing.
5. We return the minimum cost from these operations and memoize this minimum cost for the current position and speed.
6. Finally, the algorithm will return the shortest sequence of instructions to reach the target position by adding 1 outside of the DP function.


# New 21 Game

- slug: new-21-game
- difficulty: Medium

Alice plays the following game, loosely based on the card game **"21 "**.

Alice starts with `0` points and draws numbers while she has less than `k` points. During each draw, she gains an integer number of points randomly from the range `[1, maxPts]`, where `maxPts` is an integer. Each draw is independent and the outcomes have equal probabilities.

Alice stops drawing numbers when she gets `k` **or more points**.

Return the probability that Alice has `n` or fewer points.

Answers within `10-5` of the actual answer are considered accepted.

**Example 1:**

**Input:** n = 10, k = 1, maxPts = 10
**Output:** 1.00000
**Explanation:** Alice gets a single card, then stops.

**Example 2:**

**Input:** n = 6, k = 1, maxPts = 10
**Output:** 0.60000
**Explanation:** Alice gets a single card, then stops.
In 6 out of 10 possibilities, she is at or below 6 points.

**Example 3:**

**Input:** n = 21, k = 17, maxPts = 10
**Output:** 0.73278

**Constraints:**

*   `0 <= k <= n <= 104`
*   `1 <= maxPts <= 104`

## A solution in Java

```java
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public String mostCommonWord(String paragraph, String[] banned) {
    String lowerPara = paragraph.toLowerCase();
    String[] words = lowerPara.split("\\W+");
    Map<String, Integer> wordCount = new HashMap<>();
    Set<String> bannedSet = new HashSet<>();

    for (String ban : banned) {
        bannedSet.add(ban.toLowerCase());
    }

    for (String word : words) {
        if (!bannedSet.contains(word)) {
            wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);
        }
    }

    return wordCount.entrySet().stream()
            .max(Map.Entry.comparingByValue())
            .orElseThrow()
            .getKey();
}
```
First, convert the given `paragraph` to lowercase and split it into words. Then, create a `wordCount` map to store each word and their corresponding frequency count. Ignore punctuations by checking if the character is an alphabet or not.

Create a set of lowercase banned words (`bannedSet`) and iterate through the original list of words. For any word, not in the bannedSet, update or increment its frequency count in the wordCount map.

Finally, iterate through the `wordCount` map to find the word with the highest frequency count and return it as the result.

## A solution in C++

```cpp
#include <string>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <cctype>

std::string mostCommonWord(std::string paragraph, std::vector<std::string>& banned) {
    std::unordered_map<std::string, int> wordCount;
    std::string currentWord;
    for (char c : paragraph) {
        if (isalpha(c)) {
            currentWord.push_back(tolower(c));
        } else if (!currentWord.empty()) {
            wordCount[currentWord]++;
            currentWord.clear();
        }
    }

    if (!currentWord.empty()) {
        wordCount[currentWord]++;
    }

    for (std::string &ban : banned) {
        transform(ban.begin(), ban.end(), ban.begin(), ::tolower);
        wordCount[ban] = 0;
    }

    return std::max_element(wordCount.begin(), wordCount.end(), [](const auto &a, const auto &b) {
        return a.second < b.second;
    })->first;
}
```
First, convert the given `paragraph` to lowercase and split it into words. Then, create a `wordCount` map to store each word and their corresponding frequency count. Ignore punctuations by checking if the character is an alphabet or not.

Create a set of lowercase banned words (`bannedSet`) and iterate through the original list of words. For any word, not in the bannedSet, update or increment its frequency count in the wordCount map.

Finally, iterate through the `wordCount` map to find the word with the highest frequency count and return it as the result.

## A solution in Python

```python
def mostCommonWord(paragraph: str, banned: List[str]):
    word_count = {}
    banned_set = {ban.lower() for ban in banned}

    for word in paragraph.lower().split():
        cleaned_word = ''.join(c for c in word if c.isalpha())
        if cleaned_word not in banned_set:
            word_count[cleaned_word] = word_count.get(cleaned_word, 0) + 1

    return max(word_count, key=word_count.get)
```
First, convert the given `paragraph` to lowercase and split it into words. Then, create a `wordCount` map to store each word and their corresponding frequency count. Ignore punctuations by checking if the character is an alphabet or not.

Create a set of lowercase banned words (`bannedSet`) and iterate through the original list of words. For any word, not in the bannedSet, update or increment its frequency count in the wordCount map.

Finally, iterate through the `wordCount` map to find the word with the highest frequency count and return it as the result.

## A solution in Javascript

```javascript
function mostCommonWord(paragraph, banned) {
    const wordCount = new Map();
    const bannedSet = new Set(banned.map(x => x.toLowerCase()));
    const words = paragraph.toLowerCase().split(/\W+/);

    words.forEach(word => {
        if (!bannedSet.has(word)) {
            wordCount.set(word, (wordCount.get(word) || 0) + 1);
        }
    });

    let maxCount = -1;
    let result = '';
    wordCount.forEach((count, word) => {
        if (count > maxCount) {
            maxCount = count;
            result = word;
        }
    });

    return result;
}
```
First, convert the given `paragraph` to lowercase and split it into words. Then, create a `wordCount` map to store each word and their corresponding frequency count. Ignore punctuations by checking if the character is an alphabet or not.

Create a set of lowercase banned words (`bannedSet`) and iterate through the original list of words. For any word, not in the bannedSet, update or increment its frequency count in the wordCount map.

Finally, iterate through the `wordCount` map to find the word with the highest frequency count and return it as the result.