# Lexicographically Smallest Equivalent String

- slug: lexicographically-smallest-equivalent-string
- difficulty: Medium

You are given two strings of the same length `s1` and `s2` and a string `baseStr`.

We say `s1[i]` and `s2[i]` are equivalent characters.

*   For example, if `s1 = "abc "` and `s2 = "cde "`, then we have `'a' == 'c'`, `'b' == 'd'`, and `'c' == 'e'`.

Equivalent characters follow the usual rules of any equivalence relation:

*   **Reflexivity:** `'a' == 'a'`.
*   **Symmetry:** `'a' == 'b'` implies `'b' == 'a'`.
*   **Transitivity:** `'a' == 'b'` and `'b' == 'c'` implies `'a' == 'c'`.

For example, given the equivalency information from `s1 = "abc "` and `s2 = "cde "`, `"acd "` and `"aab "` are equivalent strings of `baseStr = "eed "`, and `"aab "` is the lexicographically smallest equivalent string of `baseStr`.

Return _the lexicographically smallest equivalent string of_ `baseStr` _by using the equivalency information from_ `s1` _and_ `s2`.

**Example 1:**

**Input:** s1 =  "parker ", s2 =  "morris ", baseStr =  "parser "
**Output:**  "makkek "
**Explanation:** Based on the equivalency information in s1 and s2, we can group their characters as \[m,p\], \[a,o\], \[k,r,s\], \[e,i\].
The characters in each group are equivalent and sorted in lexicographical order.
So the answer is  "makkek ".

**Example 2:**

**Input:** s1 =  "hello ", s2 =  "world ", baseStr =  "hold "
**Output:**  "hdld "
**Explanation:** Based on the equivalency information in s1 and s2, we can group their characters as \[h,w\], \[d,e,o\], \[l,r\].
So only the second letter 'o' in baseStr is changed to 'd', the answer is  "hdld ".

**Example 3:**

**Input:** s1 =  "leetcode ", s2 =  "programs ", baseStr =  "sourcecode "
**Output:**  "aauaaaaada "
**Explanation:** We group the equivalent characters in s1 and s2 as \[a,o,e,r,s,c\], \[l,p\], \[g,t\] and \[d,m\], thus all letters in baseStr except 'u' and 'd' are transformed to 'a', the answer is  "aauaaaaada ".

**Constraints:**

*   `1 <= s1.length, s2.length, baseStr <= 1000`
*   `s1.length == s2.length`
*   `s1`, `s2`, and `baseStr` consist of lowercase English letters.

## A solution in Java

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

public String lexSmallestEquivalent(String s1, String s2, String baseStr) {
    Map<Character, Character> parent = new HashMap<>();
    for (char ch = 'a'; ch <= 'z'; ch++) {
        parent.put(ch, ch);
    }

    for (int i = 0; i < s1.length(); i++) {
        char root1 = s1.charAt(i), root2 = s2.charAt(i);
        while (parent.get(root1) != root1) root1 = parent.get(root1);
        while (parent.get(root2) != root2) root2 = parent.get(root2);
        if (root1 != root2) {
            parent.put(root1, (char) Math.min(root1, root2));
            parent.put(root2, (char) Math.min(root1, root2));
        }
    }

    StringBuilder sb = new StringBuilder();
    for (char ch : baseStr.toCharArray()) {
        while (parent.get(ch) != ch) ch = parent.get(ch);
        sb.append(ch);
    }

    return sb.toString();
}
```
- Create a dictionary/ HashMap/ Map, called `parent`, where the key is the English letter and the value is the letter itself.
- Iterate through the `s1` and `s2`: for every character in `s1` and `s2`, find the roots of these characters in the `parent` dictionary/ HashMap/ Map.
- If the roots are not equal, set the value of each root in the dictionary as the minimum of the roots.
- Then, iterate through the `baseStr` characters: for each character, find its root in the parent dictionary and replace the character with its root.
- Join the baseStr characters back to a string and return it.

## A solution in C++

```cpp
#include <iostream>
#include <map>

std::string lexSmallestEquivalent(std::string s1, std::string s2, std::string baseStr) {
    std::map<char, char> parent;
    for (char ch = 'a'; ch <= 'z'; ch++) {
        parent[ch] = ch;
    }

    for (int i = 0; i < s1.size(); i++) {
        char root1 = s1[i], root2 = s2[i];
        while (parent[root1] != root1) root1 = parent[root1];
        while (parent[root2] != root2) root2 = parent[root2];
        if (root1 != root2) {
            parent[root1] = std::min(root1, root2);
            parent[root2] = std::min(root1, root2);
        }
    }

    for (int i = 0; i < baseStr.size(); i++) {
        char ch = baseStr[i];
        while (parent[ch] != ch) ch = parent[ch];
        baseStr[i] = ch;
    }

    return baseStr;
}
```
- Create a dictionary/ HashMap/ Map, called `parent`, where the key is the English letter and the value is the letter itself.
- Iterate through the `s1` and `s2`: for every character in `s1` and `s2`, find the roots of these characters in the `parent` dictionary/ HashMap/ Map.
- If the roots are not equal, set the value of each root in the dictionary as the minimum of the roots.
- Then, iterate through the `baseStr` characters: for each character, find its root in the parent dictionary and replace the character with its root.
- Join the baseStr characters back to a string and return it.

## A solution in Python

```python
def lex_smallest_equivalent(s1, s2, base_str):
    parent = {chr(ch): chr(ch) for ch in range(ord('a'), ord('z') + 1)}

    for c1, c2 in zip(s1, s2):
        root1, root2 = c1, c2
        while parent[root1] != root1:
            root1 = parent[root1]
        while parent[root2] != root2:
            root2 = parent[root2]
        if root1 != root2:
            min_root = min(root1, root2)
            parent[root1] = min_root
            parent[root2] = min_root

    return ''.join(parent[ch] for ch in base_str)
```
- Create a dictionary/ HashMap/ Map, called `parent`, where the key is the English letter and the value is the letter itself.
- Iterate through the `s1` and `s2`: for every character in `s1` and `s2`, find the roots of these characters in the `parent` dictionary/ HashMap/ Map.
- If the roots are not equal, set the value of each root in the dictionary as the minimum of the roots.
- Then, iterate through the `baseStr` characters: for each character, find its root in the parent dictionary and replace the character with its root.
- Join the baseStr characters back to a string and return it.

## A solution in Javascript

```javascript
function lexSmallestEquivalent(s1, s2, baseStr) {
    const parent = {};
    for (let ch = 'a'.charCodeAt(); ch <= 'z'.charCodeAt(); ch++) {
        parent[String.fromCharCode(ch)] = String.fromCharCode(ch);
    }

    for (let i = 0; i < s1.length; i++) {
        let root1 = s1[i], root2 = s2[i];
        while (parent[root1] !== root1) root1 = parent[root1];
        while (parent[root2] !== root2) root2 = parent[root2];
        if (root1 !== root2) {
            const minValue = Math.min(root1.charCodeAt(), root2.charCodeAt());
            parent[root1] = String.fromCharCode(minValue);
            parent[root2] = String.fromCharCode(minValue);
        }
    }

    return baseStr.split('').map(ch => {
        while (parent[ch] !== ch) ch = parent[ch];
        return ch;
    }).join('');
}
```
- Create a dictionary/ HashMap/ Map, called `parent`, where the key is the English letter and the value is the letter itself.
- Iterate through the `s1` and `s2`: for every character in `s1` and `s2`, find the roots of these characters in the `parent` dictionary/ HashMap/ Map.
- If the roots are not equal, set the value of each root in the dictionary as the minimum of the roots.
- Then, iterate through the `baseStr` characters: for each character, find its root in the parent dictionary and replace the character with its root.
- Join the baseStr characters back to a string and return it.


# Longest Repeating Substring

- slug: longest-repeating-substring
- difficulty: Medium

Given a string `s`, return _the length of the longest repeating substrings_. If no repeating substring exists, return `0`.

**Example 1:**

**Input:** s =  "abcd "
**Output:** 0
**Explanation:** There is no repeating substring.

**Example 2:**

**Input:** s =  "abbaba "
**Output:** 2
**Explanation:** The longest repeating substrings are  "ab " and  "ba ", each of which occurs twice.

**Example 3:**

**Input:** s =  "aabcaabdaab "
**Output:** 3
**Explanation:** The longest repeating substring is  "aab ", which occurs `3` times.

**Constraints:**

*   `1 <= s.length <= 2000`
*   `s` consists of lowercase English letters.

## A solution in Java

```java
public int findLongestRepeatingSubstring(String s) {
    int n = s.length();
    int maxSubstrLength = 0;
    for (int len = 1; len <= n / 2; ++len) {
        int maxRepeatCount = 0, repeatCount = 0;
        for (int i = 0; i < n - len; ++i) {
            if (s.substring(i, i + len).equals(s.substring(i + len, i + 2 * len))) {
                repeatCount++;
            } else {
                maxRepeatCount = Math.max(maxRepeatCount, repeatCount);
                repeatCount = 0;
            }
        }
        maxSubstrLength = Math.max(maxSubstrLength, maxRepeatCount * len);
    }
    return maxSubstrLength;
}
```
The algorithm iterates through each possible length of a substring (`len`). For each `len`, it checks if the current substring `s[i:i+len]` is equal to the next substring `s[i+len:i+2*len]`. If the substrings are equal, it increments `repeat_count` and updates `max_repeat_count` if needed. After iterating through all possible substring lengths, it returns the longest length of the repeated substrings as `max_substr_length`.

## A solution in C++

```cpp
int findLongestRepeatingSubstring(const std::string &s) {
    int n = s.length();
    int max_substr_length = 0;
    for (int len = 1; len <= n/2; ++len) {
        int max_repeat_count = 0, repeat_count = 0;
        for (int i = 0; i < n - len; ++i) {
            if (s.substr(i, len) == s.substr(i + len, len)) {
                repeat_count++;
            } else {
                max_repeat_count = std::max(max_repeat_count, repeat_count);
                repeat_count = 0;
            }
        }
        max_substr_length = std::max(max_substr_length, max_repeat_count * len);
    }
    return max_substr_length;
}
```
The algorithm iterates through each possible length of a substring (`len`). For each `len`, it checks if the current substring `s[i:i+len]` is equal to the next substring `s[i+len:i+2*len]`. If the substrings are equal, it increments `repeat_count` and updates `max_repeat_count` if needed. After iterating through all possible substring lengths, it returns the longest length of the repeated substrings as `max_substr_length`.

## A solution in Python

```python
def find_longest_repeating_substring(s: str) -> int:
    n = len(s)
    max_substr_length = 0
    for length in range(1, n // 2 + 1):
        max_repeat_count = repeat_count = 0
        for i in range(n - length):
            if s[i:i + length] == s[i + length:i + 2 * length]:
                repeat_count += 1
            else:
                max_repeat_count = max(max_repeat_count, repeat_count)
                repeat_count = 0
        max_substr_length = max(max_substr_length, max_repeat_count * length)
    return max_substr_length
```
The algorithm iterates through each possible length of a substring (`len`). For each `len`, it checks if the current substring `s[i:i+len]` is equal to the next substring `s[i+len:i+2*len]`. If the substrings are equal, it increments `repeat_count` and updates `max_repeat_count` if needed. After iterating through all possible substring lengths, it returns the longest length of the repeated substrings as `max_substr_length`.

## A solution in Javascript

```javascript
function findLongestRepeatingSubstring(s) {
    let n = s.length;
    let maxSubstrLength = 0;
    for (let len = 1; len <= n / 2; ++len) {
        let maxRepeatCount = 0, repeatCount = 0;
        for (let i = 0; i < n - len; ++i) {
            if (s.substring(i, i + len) === s.substring(i + len, i + 2 * len)) {
                repeatCount++;
            } else {
                maxRepeatCount = Math.max(maxRepeatCount, repeatCount);
                repeatCount = 0;
            }
        }
        maxSubstrLength = Math.max(maxSubstrLength, maxRepeatCount * len);
    }
    return maxSubstrLength;
}
```
The algorithm iterates through each possible length of a substring (`len`). For each `len`, it checks if the current substring `s[i:i+len]` is equal to the next substring `s[i+len:i+2*len]`. If the substrings are equal, it increments `repeat_count` and updates `max_repeat_count` if needed. After iterating through all possible substring lengths, it returns the longest length of the repeated substrings as `max_substr_length`.


# Number of Valid Subarrays

- slug: number-of-valid-subarrays
- difficulty: Hard

Given an integer array `nums`, return _the number of non-empty **subarrays** with the leftmost element of the subarray not larger than other elements in the subarray_.

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

**Example 1:**

**Input:** nums = \[1,4,2,5,3\]
**Output:** 11
**Explanation:** There are 11 valid subarrays: \[1\],\[4\],\[2\],\[5\],\[3\],\[1,4\],\[2,5\],\[1,4,2\],\[2,5,3\],\[1,4,2,5\],\[1,4,2,5,3\].

**Example 2:**

**Input:** nums = \[3,2,1\]
**Output:** 3
**Explanation:** The 3 valid subarrays are: \[3\],\[2\],\[1\].

**Example 3:**

**Input:** nums = \[2,2,2\]
**Output:** 6
**Explanation:** There are 6 valid subarrays: \[2\],\[2\],\[2\],\[2,2\],\[2,2\],\[2,2,2\].

**Constraints:**

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

## A solution in Java

```java
public int maxScoreSightseeingPair(int[] values) {
    int max_score = 0, max_score_left = values[0] + 0;
    for (int j = 1; j < values.length; ++j) {
        max_score = Math.max(max_score, max_score_left + values[j] - j);
        max_score_left = Math.max(max_score_left, values[j] + j);
    }
    return max_score;
}
```
We want to find the maximum score given by `values[i] + values[j] + i - j` for some `i < j`.
We can rewrite the formula as `values[i] + i + (values[j] - j)` for `i < j`.
Now we can loop through the `values` array with an index `j`.

For each `j` we calculate the "left" score which is `values[i] + i` where `i` is in a range `[0, j-1]`.

We keep track of the maximum score before `j` (i.e. for `[0, j-1]`) in `max_score_left`.
Also, we keep track of the maximum score so far in `max_score`.

For each `j`, we can calculate the score for the current pair `(i, j)` with the formula `max_score_left + (values[j] - j)`. If this score is greater than our current `max_score`, then we update `max_score`.

Finally, we return the `max_score` after iterating through the whole `values` array.

## A solution in C++

```cpp
int maxScoreSightseeingPair(vector<int>& values) {
    int max_score = 0, max_score_left = values[0] + 0;
    for (int j = 1; j < values.size(); ++j) {
        max_score = max(max_score, max_score_left + values[j] - j);
        max_score_left = max(max_score_left, values[j] + j);
    }
    return max_score;
}
```
We want to find the maximum score given by `values[i] + values[j] + i - j` for some `i < j`.
We can rewrite the formula as `values[i] + i + (values[j] - j)` for `i < j`.
Now we can loop through the `values` array with an index `j`.

For each `j` we calculate the "left" score which is `values[i] + i` where `i` is in a range `[0, j-1]`.

We keep track of the maximum score before `j` (i.e. for `[0, j-1]`) in `max_score_left`.
Also, we keep track of the maximum score so far in `max_score`.

For each `j`, we can calculate the score for the current pair `(i, j)` with the formula `max_score_left + (values[j] - j)`. If this score is greater than our current `max_score`, then we update `max_score`.

Finally, we return the `max_score` after iterating through the whole `values` array.

## A solution in Python

```python
def maxScoreSightseeingPair(values):
    max_score = 0
    max_score_left = values[0] + 0
    for j in range(1, len(values)):
        max_score = max(max_score, max_score_left + values[j] - j)
        max_score_left = max(max_score_left, values[j] + j)
    return max_score
```
We want to find the maximum score given by `values[i] + values[j] + i - j` for some `i < j`.
We can rewrite the formula as `values[i] + i + (values[j] - j)` for `i < j`.
Now we can loop through the `values` array with an index `j`.

For each `j` we calculate the "left" score which is `values[i] + i` where `i` is in a range `[0, j-1]`.

We keep track of the maximum score before `j` (i.e. for `[0, j-1]`) in `max_score_left`.
Also, we keep track of the maximum score so far in `max_score`.

For each `j`, we can calculate the score for the current pair `(i, j)` with the formula `max_score_left + (values[j] - j)`. If this score is greater than our current `max_score`, then we update `max_score`.

Finally, we return the `max_score` after iterating through the whole `values` array.

## A solution in Javascript

```javascript
function maxScoreSightseeingPair(values) {
    let max_score = 0, max_score_left = values[0] + 0;
    for (let j = 1; j < values.length; ++j) {
        max_score = Math.max(max_score, max_score_left + values[j] - j);
        max_score_left = Math.max(max_score_left, values[j] + j);
    }
    return max_score;
}
```
We want to find the maximum score given by `values[i] + values[j] + i - j` for some `i < j`.
We can rewrite the formula as `values[i] + i + (values[j] - j)` for `i < j`.
Now we can loop through the `values` array with an index `j`.

For each `j` we calculate the "left" score which is `values[i] + i` where `i` is in a range `[0, j-1]`.

We keep track of the maximum score before `j` (i.e. for `[0, j-1]`) in `max_score_left`.
Also, we keep track of the maximum score so far in `max_score`.

For each `j`, we can calculate the score for the current pair `(i, j)` with the formula `max_score_left + (values[j] - j)`. If this score is greater than our current `max_score`, then we update `max_score`.

Finally, we return the `max_score` after iterating through the whole `values` array.


# Fixed Point

- slug: fixed-point
- difficulty: Easy

Given an array of distinct integers `arr`, where `arr` is sorted in **ascending order**, return the smallest index `i` that satisfies `arr[i] == i`. If there is no such index, return `-1`.

**Example 1:**

**Input:** arr = \[-10,-5,0,3,7\]
**Output:** 3
**Explanation:** For the given array, `arr[0] = -10, arr[1] = -5, arr[2] = 0, arr[3] = 3`, thus the output is 3.

**Example 2:**

**Input:** arr = \[0,2,5,8,17\]
**Output:** 0
**Explanation:** `arr[0] = 0`, thus the output is 0.

**Example 3:**

**Input:** arr = \[-10,-5,3,4,7,9\]
**Output:** -1
**Explanation:** There is no such `i` that `arr[i] == i`, thus the output is -1.

**Constraints:**

*   `1 <= arr.length < 104`
*   `-109 <= arr[i] <= 109`

**Follow up:** The `O(n)` solution is very straightforward. Can we do better?

## A solution in Java

```java
public int fixedPoint(int[] arr) {
    int left = 0, right = arr.length - 1;
    while (left < right) {
        int middle = left + (right - left) / 2;
        if (arr[middle] < middle) {
            left = middle + 1;
        } else {
            right = middle;
        }
    }
    return arr[left] == left ? left : -1;
}
```
The algorithm uses binary search to efficiently find the fixed point in the sorted array of distinct integers. Since the array is sorted, when `arr[middle] < middle`, we can conclude that a fixed point (if exists) must be at `middle` or at the right side of `middle`, so we set `left` to `middle + 1`. In other cases, when `arr[middle] >= middle`, we set `right` to `middle`. This process continues until `left` < `right` is no longer true.

After exiting the loop, we check if `arr[left]` is equal to `left`. If yes, we return `left` as the fixed point index, otherwise we return `-1`, as no fixed point exists.

The time complexity of the algorithm is O(log n), as we divide the search interval by half at each step.

## A solution in C++

```cpp
int fixedPoint(vector<int>& arr) {
    int left = 0, right = arr.size() - 1;
    while (left < right) {
        int middle = left + (right - left) / 2;
        if (arr[middle] < middle) {
            left = middle + 1;
        } else {
            right = middle;
        }
    }
    return arr[left] == left ? left : -1;
}
```
The algorithm uses binary search to efficiently find the fixed point in the sorted array of distinct integers. Since the array is sorted, when `arr[middle] < middle`, we can conclude that a fixed point (if exists) must be at `middle` or at the right side of `middle`, so we set `left` to `middle + 1`. In other cases, when `arr[middle] >= middle`, we set `right` to `middle`. This process continues until `left` < `right` is no longer true.

After exiting the loop, we check if `arr[left]` is equal to `left`. If yes, we return `left` as the fixed point index, otherwise we return `-1`, as no fixed point exists.

The time complexity of the algorithm is O(log n), as we divide the search interval by half at each step.

## A solution in Python

```python
def fixedPoint(arr: List[int]) -> int:
    left, right = 0, len(arr) - 1
    while left < right:
        middle = left + (right - left) // 2
        if arr[middle] < middle:
            left = middle + 1
        else:
            right = middle
    return left if arr[left] == left else -1
```
The algorithm uses binary search to efficiently find the fixed point in the sorted array of distinct integers. Since the array is sorted, when `arr[middle] < middle`, we can conclude that a fixed point (if exists) must be at `middle` or at the right side of `middle`, so we set `left` to `middle + 1`. In other cases, when `arr[middle] >= middle`, we set `right` to `middle`. This process continues until `left` < `right` is no longer true.

After exiting the loop, we check if `arr[left]` is equal to `left`. If yes, we return `left` as the fixed point index, otherwise we return `-1`, as no fixed point exists.

The time complexity of the algorithm is O(log n), as we divide the search interval by half at each step.

## A solution in Javascript

```javascript
function fixedPoint(arr) {
    let left = 0, right = arr.length - 1;
    while (left < right) {
        let middle = left + Math.floor((right - left) / 2);
        if (arr[middle] < middle) {
            left = middle + 1;
        } else {
            right = middle;
        }
    }
    return arr[left] === left ? left : -1;
}
```
The algorithm uses binary search to efficiently find the fixed point in the sorted array of distinct integers. Since the array is sorted, when `arr[middle] < middle`, we can conclude that a fixed point (if exists) must be at `middle` or at the right side of `middle`, so we set `left` to `middle + 1`. In other cases, when `arr[middle] >= middle`, we set `right` to `middle`. This process continues until `left` < `right` is no longer true.

After exiting the loop, we check if `arr[left]` is equal to `left`. If yes, we return `left` as the fixed point index, otherwise we return `-1`, as no fixed point exists.

The time complexity of the algorithm is O(log n), as we divide the search interval by half at each step.


# Index Pairs of a String

- slug: index-pairs-of-a-string
- difficulty: Easy

Given a string `text` and an array of strings `words`, return _an array of all index pairs_ `[i, j]` _so that the substring_ `text[i...j]` _is in `words`_.

Return the pairs `[i, j]` in sorted order (i.e., sort them by their first coordinate, and in case of ties sort them by their second coordinate).

**Example 1:**

**Input:** text =  "thestoryofleetcodeandme ", words = \[ "story ", "fleet ", "leetcode "\]
**Output:** \[\[3,7\],\[9,13\],\[10,17\]\]

**Example 2:**

**Input:** text =  "ababa ", words = \[ "aba ", "ab "\]
**Output:** \[\[0,1\],\[0,2\],\[2,3\],\[2,4\]\]
**Explanation:** Notice that matches can overlap, see  "aba " is found in \[0,2\] and \[2,4\].

**Constraints:**

*   `1 <= text.length <= 100`
*   `1 <= words.length <= 20`
*   `1 <= words[i].length <= 50`
*   `text` and `words[i]` consist of lowercase English letters.
*   All the strings of `words` are **unique**.

## A solution in Java

```java
public boolean hasAllCodesInRange(String s, int n) {
    Set<String> substrings = new HashSet<>();
    int length = Integer.toBinaryString(n).length();
    for (int i = 0; i < s.length() - length + 1; ++i) {
        substrings.add(s.substring(i, i + length));
    }
    return substrings.size() == n;
}
```
1. Initialize an empty set called `substrings` to store unique binary substrings of length equal to the binary representation of `n`.
2. Compute the length of the binary representation of `n` and store it in `length`.
3. Loop through the binary string `s`, starting from index 0 to `len(s) - length`:
   a. Extract the substring of `s` with length `length` starting at index `i`.
   b. Add the extracted substring to the `substrings` set.
4. Check if the size of `substrings` is equal to `n`. If it is, then all integers in the range `[1, n]` had their binary representation in `s`.
5. Return the result (true if the size is equal to `n`, and false otherwise).

## A solution in C++

```cpp
bool hasAllCodesInRange(const std::string& s, int n) {
    std::unordered_set<std::string> substrings;
    int length = std::to_string(n).length();
    for (int i = 0; i < s.length() - length + 1; ++i) {
        substrings.insert(s.substr(i, length));
    }
    return substrings.size() == n;
}
```
1. Initialize an empty set called `substrings` to store unique binary substrings of length equal to the binary representation of `n`.
2. Compute the length of the binary representation of `n` and store it in `length`.
3. Loop through the binary string `s`, starting from index 0 to `len(s) - length`:
   a. Extract the substring of `s` with length `length` starting at index `i`.
   b. Add the extracted substring to the `substrings` set.
4. Check if the size of `substrings` is equal to `n`. If it is, then all integers in the range `[1, n]` had their binary representation in `s`.
5. Return the result (true if the size is equal to `n`, and false otherwise).

## A solution in Python

```python
def has_all_codes_in_range(s: str, n: int) -> bool:
    substrings = set()
    length = len(bin(n)) - 2
    for i in range(len(s) - length + 1):
        substrings.add(s[i:i + length])
    return len(substrings) == n
```
1. Initialize an empty set called `substrings` to store unique binary substrings of length equal to the binary representation of `n`.
2. Compute the length of the binary representation of `n` and store it in `length`.
3. Loop through the binary string `s`, starting from index 0 to `len(s) - length`:
   a. Extract the substring of `s` with length `length` starting at index `i`.
   b. Add the extracted substring to the `substrings` set.
4. Check if the size of `substrings` is equal to `n`. If it is, then all integers in the range `[1, n]` had their binary representation in `s`.
5. Return the result (true if the size is equal to `n`, and false otherwise).

## A solution in Javascript

```javascript
function hasAllCodesInRange(s, n) {
    let substrings = new Set();
    let length = n.toString(2).length;
    for (let i = 0; i < s.length - length + 1; ++i) {
        substrings.add(s.substr(i, length));
    }
    return substrings.size == n;
}
```
1. Initialize an empty set called `substrings` to store unique binary substrings of length equal to the binary representation of `n`.
2. Compute the length of the binary representation of `n` and store it in `length`.
3. Loop through the binary string `s`, starting from index 0 to `len(s) - length`:
   a. Extract the substring of `s` with length `length` starting at index `i`.
   b. Add the extracted substring to the `substrings` set.
4. Check if the size of `substrings` is equal to `n`. If it is, then all integers in the range `[1, n]` had their binary representation in `s`.
5. Return the result (true if the size is equal to `n`, and false otherwise).


# Campus Bikes II

- slug: campus-bikes-ii
- difficulty: Medium

On a campus represented as a 2D grid, there are `n` workers and `m` bikes, with `n <= m`. Each worker and bike is a 2D coordinate on this grid.

We assign one unique bike to each worker so that the sum of the **Manhattan distances** between each worker and their assigned bike is minimized.

Return `the minimum possible sum of Manhattan distances between each worker and their assigned bike`.

The **Manhattan distance** between two points `p1` and `p2` is `Manhattan(p1, p2) = |p1.x - p2.x| + |p1.y - p2.y|`.

**Example 1:**

**Input:** workers = \[\[0,0\],\[2,1\]\], bikes = \[\[1,2\],\[3,3\]\]
**Output:** 6
**Explanation:**
We assign bike 0 to worker 0, bike 1 to worker 1. The Manhattan distance of both assignments is 3, so the output is 6.

**Example 2:**

**Input:** workers = \[\[0,0\],\[1,1\],\[2,0\]\], bikes = \[\[1,0\],\[2,2\],\[2,1\]\]
**Output:** 4
**Explanation:**
We first assign bike 0 to worker 0, then assign bike 1 to worker 1 or worker 2, bike 2 to worker 2 or worker 1. Both assignments lead to sum of the Manhattan distances as 4.

**Example 3:**

**Input:** workers = \[\[0,0\],\[1,0\],\[2,0\],\[3,0\],\[4,0\]\], bikes = \[\[0,999\],\[1,999\],\[2,999\],\[3,999\],\[4,999\]\]
**Output:** 4995

**Constraints:**

*   `n == workers.length`
*   `m == bikes.length`
*   `1 <= n <= m <= 10`
*   `workers[i].length == 2`
*   `bikes[i].length == 2`
*   `0 <= workers[i][0], workers[i][1], bikes[i][0], bikes[i][1] < 1000`
*   All the workers and the bikes locations are **unique**.

## A solution in Java

```java
import java.util.*;

class Solution {
    public int manhattanDistance(int[] worker, int[] bike) {
        return Math.abs(worker[0] - bike[0]) + Math.abs(worker[1] - bike[1]);
    }

    private void dfs(int[][] workers, int[][] bikes, boolean[] used, int index, int dist, int[] minDist) {
        if (index == workers.length) {
            minDist[0] = Math.min(minDist[0], dist);
            return;
        }

        if (dist >= minDist[0]) {
            return;
        }

        for (int i = 0; i < bikes.length; i++) {
            if (used[i]) {
                continue;
            }
            used[i] = true;
            int curDist = manhattanDistance(workers[index], bikes[i]);
            dfs(workers, bikes, used, index+1, dist + curDist, minDist);
            used[i] = false;
        }
    }

    public int assignBikes(int[][] workers, int[][] bikes) {
        int[] minDist = new int[]{Integer.MAX_VALUE};
        boolean[] used = new boolean[bikes.length];
        dfs(workers, bikes, used, 0, 0, minDist);
        return minDist[0];
    }
}
```
In order to solve the problem, we use a Depth First Search (DFS) algorithm to find all possible assignments of bikes to workers. We take the following steps:

1. Create the helper function `manhattanDistance` to calculate the Manhattan distance between a worker and a bike.
2. Implement the DFS function that takes the current worker index, the distance accumulated so far, and the minimum distance by reference. The DFS function will do the following:
   a. Terminate if the current worker index is equal to the number of workers, indicating we have assigned bikes to all workers.
   b. Terminate if the accumulated distance is greater than or equal to the current minimum distance.
   c. Otherwise, iterate through all bikes and assign them to the current worker (if not already assigned to another worker).
3. Call the DFS function starting from the first worker with accumulated distance equal to 0 and a reference to the minimum distance.
4. Return the final minimum distance.

The time complexity of this solution is O(m^n), where m is the number of bikes, and n is the number of workers. Since the constraint is n <= 10, the solution will be efficient enough for our problem.

## A solution in C++

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

int manhattanDistance(vector<int>& worker, vector<int>& bike) {
    return abs(worker[0] - bike[0]) + abs(worker[1] - bike[1]);
}

void dfs(vector<vector<int>>& workers, vector<vector<int>>& bikes, vector<bool>& used, int index, int dist, int& minDist) {
    if (index == workers.size()) {
        minDist = min(minDist, dist);
        return;
    }

    if (dist >= minDist) {
        return;
    }

    for (int i = 0; i < bikes.size(); i++) {
        if (used[i]) {
            continue;
        }
        used[i] = true;
        int curDist = manhattanDistance(workers[index], bikes[i]);
        dfs(workers, bikes, used, index+1, dist + curDist, minDist);
        used[i] = false;
    }
}

int assignBikes(vector<vector<int>>& workers, vector<vector<int>>& bikes) {
    int minDist = INT_MAX;
    vector<bool> used(bikes.size(), false);
    dfs(workers, bikes, used, 0, 0, minDist);
    return minDist;
}
```
In order to solve the problem, we use a Depth First Search (DFS) algorithm to find all possible assignments of bikes to workers. We take the following steps:

1. Create the helper function `manhattanDistance` to calculate the Manhattan distance between a worker and a bike.
2. Implement the DFS function that takes the current worker index, the distance accumulated so far, and the minimum distance by reference. The DFS function will do the following:
   a. Terminate if the current worker index is equal to the number of workers, indicating we have assigned bikes to all workers.
   b. Terminate if the accumulated distance is greater than or equal to the current minimum distance.
   c. Otherwise, iterate through all bikes and assign them to the current worker (if not already assigned to another worker).
3. Call the DFS function starting from the first worker with accumulated distance equal to 0 and a reference to the minimum distance.
4. Return the final minimum distance.

The time complexity of this solution is O(m^n), where m is the number of bikes, and n is the number of workers. Since the constraint is n <= 10, the solution will be efficient enough for our problem.

## A solution in Python

```python
from typing import List

def manhattan_distance(worker: List[int], bike: List[int]) -> int:
    return abs(worker[0] - bike[0]) + abs(worker[1] - bike[1])

def dfs(workers: List[List[int]], bikes: List[List[int]], used: List[bool], index: int, dist: int, min_dist: List[int]) -> None:
    if index == len(workers):
        min_dist[0] = min(min_dist[0], dist)
        return

    if dist >= min_dist[0]:
        return

    for i in range(len(bikes)):
        if used[i]:
            continue
        used[i] = True
        cur_dist = manhattan_distance(workers[index], bikes[i])
        dfs(workers, bikes, used, index + 1, dist + cur_dist, min_dist)
        used[i] = False

def assign_bikes(workers: List[List[int]], bikes: List[List[int]]) -> int:
    min_dist = [float('inf')]
    used = [False] * len(bikes)
    dfs(workers, bikes, used, 0, 0, min_dist)
    return min_dist[0]
```
In order to solve the problem, we use a Depth First Search (DFS) algorithm to find all possible assignments of bikes to workers. We take the following steps:

1. Create the helper function `manhattanDistance` to calculate the Manhattan distance between a worker and a bike.
2. Implement the DFS function that takes the current worker index, the distance accumulated so far, and the minimum distance by reference. The DFS function will do the following:
   a. Terminate if the current worker index is equal to the number of workers, indicating we have assigned bikes to all workers.
   b. Terminate if the accumulated distance is greater than or equal to the current minimum distance.
   c. Otherwise, iterate through all bikes and assign them to the current worker (if not already assigned to another worker).
3. Call the DFS function starting from the first worker with accumulated distance equal to 0 and a reference to the minimum distance.
4. Return the final minimum distance.

The time complexity of this solution is O(m^n), where m is the number of bikes, and n is the number of workers. Since the constraint is n <= 10, the solution will be efficient enough for our problem.

## A solution in Javascript

```javascript
function manhattanDistance(worker, bike) {
    return Math.abs(worker[0] - bike[0]) + Math.abs(worker[1] - bike[1]);
}

function dfs(workers, bikes, used, index, dist, minDist) {
    if (index === workers.length) {
        minDist[0] = Math.min(minDist[0], dist);
        return;
    }

    if (dist >= minDist[0]) {
        return;
    }

    for (let i = 0; i < bikes.length; i++) {
        if (used[i]) {
            continue;
        }
        used[i] = true;
        let curDist = manhattanDistance(workers[index], bikes[i]);
        dfs(workers, bikes, used, index + 1, dist + curDist, minDist);
        used[i] = false;
    }
}

function assignBikes(workers, bikes) {
    let minDist = [Infinity];
    let used = new Array(bikes.length).fill(false);
    dfs(workers, bikes, used, 0, 0, minDist);
    return minDist[0];
}
```
In order to solve the problem, we use a Depth First Search (DFS) algorithm to find all possible assignments of bikes to workers. We take the following steps:

1. Create the helper function `manhattanDistance` to calculate the Manhattan distance between a worker and a bike.
2. Implement the DFS function that takes the current worker index, the distance accumulated so far, and the minimum distance by reference. The DFS function will do the following:
   a. Terminate if the current worker index is equal to the number of workers, indicating we have assigned bikes to all workers.
   b. Terminate if the accumulated distance is greater than or equal to the current minimum distance.
   c. Otherwise, iterate through all bikes and assign them to the current worker (if not already assigned to another worker).
3. Call the DFS function starting from the first worker with accumulated distance equal to 0 and a reference to the minimum distance.
4. Return the final minimum distance.

The time complexity of this solution is O(m^n), where m is the number of bikes, and n is the number of workers. Since the constraint is n <= 10, the solution will be efficient enough for our problem.


# Digit Count in Range

- slug: digit-count-in-range
- difficulty: Hard

Given a single-digit integer `d` and two integers `low` and `high`, return _the number of times that_ `d` _occurs as a digit in all integers in the inclusive range_ `[low, high]`.

**Example 1:**

**Input:** d = 1, low = 1, high = 13
**Output:** 6
**Explanation:** The digit d = 1 occurs 6 times in 1, 10, 11, 12, 13.
Note that the digit d = 1 occurs twice in the number 11.

**Example 2:**

**Input:** d = 3, low = 100, high = 250
**Output:** 35
**Explanation:** The digit d = 3 occurs 35 times in 103,113,123,130,131,...,238,239,243.

**Constraints:**

*   `0 <= d <= 9`
*   `1 <= low <= high <= 2 * 108`

## A solution in Java

```java
public int countDigit(int d, int low, int high) {
    int count = 0;
    for (int i = low; i <= high; i++) {
        int num = i;
        while (num > 0) {
            if (num % 10 == d) {
                count++;
            }
            num /= 10;
        }
    }
    return count;
}
```
The algorithm loops through all integers between `low` and `high` (inclusive). For each integer, it iterates through each digit by dividing it by 10 each time and taking the remainder (mod 10) to check if it matches the given digit `d`. If a match is found, it increments the `count` variable. Finally, it returns the total count.

## A solution in C++

```cpp
int countDigit(int d, int low, int high) {
    int count = 0;
    for (int i = low; i <= high; ++i) {
        int num = i;
        while (num) {
            if (num % 10 == d) {
                count++;
            }
            num /= 10;
        }
    }
    return count;
}
```
The algorithm loops through all integers between `low` and `high` (inclusive). For each integer, it iterates through each digit by dividing it by 10 each time and taking the remainder (mod 10) to check if it matches the given digit `d`. If a match is found, it increments the `count` variable. Finally, it returns the total count.

## A solution in Python

```python
def count_digit(d, low, high):
    count = 0
    for i in range(low, high + 1):
        num = i
        while num > 0:
            if num % 10 == d:
                count += 1
            num //= 10
    return count
```
The algorithm loops through all integers between `low` and `high` (inclusive). For each integer, it iterates through each digit by dividing it by 10 each time and taking the remainder (mod 10) to check if it matches the given digit `d`. If a match is found, it increments the `count` variable. Finally, it returns the total count.

## A solution in Javascript

```javascript
function countDigit(d, low, high) {
    let count = 0;
    for (let i = low; i <= high; i++) {
        let num = i;
        while (num > 0) {
            if (num % 10 === d) {
                count++;
            }
            num = Math.floor(num / 10);
        }
    }
    return count;
}
```
The algorithm loops through all integers between `low` and `high` (inclusive). For each integer, it iterates through each digit by dividing it by 10 each time and taking the remainder (mod 10) to check if it matches the given digit `d`. If a match is found, it increments the `count` variable. Finally, it returns the total count.


# Greatest Common Divisor of Strings

- slug: greatest-common-divisor-of-strings
- difficulty: Easy

For two strings `s` and `t`, we say "`t` divides `s` " if and only if `s = t + ... + t` (i.e., `t` is concatenated with itself one or more times).

Given two strings `str1` and `str2`, return _the largest string_ `x` _such that_ `x` _divides both_ `str1` _and_ `str2`.

**Example 1:**

**Input:** str1 =  "ABCABC ", str2 =  "ABC "
**Output:**  "ABC "

**Example 2:**

**Input:** str1 =  "ABABAB ", str2 =  "ABAB "
**Output:**  "AB "

**Example 3:**

**Input:** str1 =  "LEET ", str2 =  "CODE "
**Output:**  " "

**Constraints:**

*   `1 <= str1.length, str2.length <= 1000`
*   `str1` and `str2` consist of English uppercase letters.

## A solution in Java

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

public List<Boolean> prefixesDivBy5(int[] nums) {
    List<Boolean> result = new ArrayList<>();
    int current = 0;
    for (int num : nums) {
        current = ((current << 1) | num) % 5;
        result.add(current == 0);
    }
    return result;
}
```
The problem requires to find out if the binary representation of the subarray from 0 to i is divisible by 5. To solve this, we can maintain an integer `current` that keeps track of the value of this binary representation modulo 5.

Iterate through the `nums` array, and, for each number in the array, update the running total `current` as follows:
- Shift `current` one bit to the left (multiply by 2) using the bitwise left shift operator `<< 1`
- Perform bitwise OR operation with the current number `num` to add it as the least significant bit to the binary representation
- Compute this binary representation modulo 5

After computing the current binary representation (modulo 5), check if it is divisible by 5. If it's divisible, then the value of `current` would be 0. Append the result (true or false) to the answer list or vector.

Finally, return the resultant list of booleans.###

End ###

## A solution in C++

```cpp
#include <vector>

std::vector<bool> prefixesDivBy5(std::vector<int>& nums) {
    std::vector<bool> result;
    int current = 0;
    for (int num : nums) {
        current = ((current << 1) | num) % 5;
        result.push_back(current == 0);
    }
    return result;
}
```
The problem requires to find out if the binary representation of the subarray from 0 to i is divisible by 5. To solve this, we can maintain an integer `current` that keeps track of the value of this binary representation modulo 5.

Iterate through the `nums` array, and, for each number in the array, update the running total `current` as follows:
- Shift `current` one bit to the left (multiply by 2) using the bitwise left shift operator `<< 1`
- Perform bitwise OR operation with the current number `num` to add it as the least significant bit to the binary representation
- Compute this binary representation modulo 5

After computing the current binary representation (modulo 5), check if it is divisible by 5. If it's divisible, then the value of `current` would be 0. Append the result (true or false) to the answer list or vector.

Finally, return the resultant list of booleans.###

End ###

## A solution in Python

```python
def prefixesDivBy5(nums):
    result = []
    current = 0
    for num in nums:
        current = ((current << 1) | num) % 5
        result.append(current == 0)
    return result
```
The problem requires to find out if the binary representation of the subarray from 0 to i is divisible by 5. To solve this, we can maintain an integer `current` that keeps track of the value of this binary representation modulo 5.

Iterate through the `nums` array, and, for each number in the array, update the running total `current` as follows:
- Shift `current` one bit to the left (multiply by 2) using the bitwise left shift operator `<< 1`
- Perform bitwise OR operation with the current number `num` to add it as the least significant bit to the binary representation
- Compute this binary representation modulo 5

After computing the current binary representation (modulo 5), check if it is divisible by 5. If it's divisible, then the value of `current` would be 0. Append the result (true or false) to the answer list or vector.

Finally, return the resultant list of booleans.###

End ###

## A solution in Javascript

```javascript
function prefixesDivBy5(nums) {
    let result = [];
    let current = 0;
    for (let num of nums) {
        current = ((current << 1) | num) % 5;
        result.push(current === 0);
    }
    return result;
}
```
The problem requires to find out if the binary representation of the subarray from 0 to i is divisible by 5. To solve this, we can maintain an integer `current` that keeps track of the value of this binary representation modulo 5.

Iterate through the `nums` array, and, for each number in the array, update the running total `current` as follows:
- Shift `current` one bit to the left (multiply by 2) using the bitwise left shift operator `<< 1`
- Perform bitwise OR operation with the current number `num` to add it as the least significant bit to the binary representation
- Compute this binary representation modulo 5

After computing the current binary representation (modulo 5), check if it is divisible by 5. If it's divisible, then the value of `current` would be 0. Append the result (true or false) to the answer list or vector.

Finally, return the resultant list of booleans.###

End ###


# Flip Columns For Maximum Number of Equal Rows

- slug: flip-columns-for-maximum-number-of-equal-rows
- difficulty: Medium

You are given an `m x n` binary matrix `matrix`.

You can choose any number of columns in the matrix and flip every cell in that column (i.e., Change the value of the cell from `0` to `1` or vice versa).

Return _the maximum number of rows that have all values equal after some number of flips_.

**Example 1:**

**Input:** matrix = \[\[0,1\],\[1,1\]\]
**Output:** 1
**Explanation:** After flipping no values, 1 row has all values equal.

**Example 2:**

**Input:** matrix = \[\[0,1\],\[1,0\]\]
**Output:** 2
**Explanation:** After flipping values in the first column, both rows have equal values.

**Example 3:**

**Input:** matrix = \[\[0,0,0\],\[0,0,1\],\[1,1,0\]\]
**Output:** 2
**Explanation:** After flipping values in the first two columns, the last two rows have equal values.

**Constraints:**

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

## A solution in Java

```java
import java.util.Stack;

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

public int[] nextGreaterNodes(ListNode head) {
    Stack<Integer> greater = new Stack<>();
    ListNode current = head;
    int size = 0;

    while (current != null) {
        size++;
        current = current.next;
    }

    int[] answer = new int[size];
    int index = 0;

    current = head;

    while (current != null) {
        while (!greater.empty() && answer[greater.peek()] < current.val) {
            answer[greater.pop()] = current.val;
        }
        answer[index] = current.val;
        greater.push(index++);
        current = current.next;
    }

    while (!greater.empty()) {
        answer[greater.pop()] = 0;
    }
    return answer;
}
```
The algorithm starts by initializing an empty vector to store the results and an empty stack to keep track of the indices of the nodes. Then it iterates through the linked list using the given head. At each node, it compares the top of the stack to the current node's value. If the top of the stack is smaller than the current node's value, the top of the stack will be replaced with the current node's value and the stack will be popped. It will continue doing this until the condition is no longer satisfied or the stack is empty. The value of the current node is then added to the results vector and the index of the latest value that was added gets pushed to the stack. Finally, the algorithm checks if the stack is not empty; if it isn't, the top of the stack will be set to 0 and the stack will be popped. The results vector is then returned. This algorithm works the same way across all four languages, with the only differences being in the syntax and the specific data structures used.

## A solution in C++

```cpp
#include <stack>
#include <vector>

struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(NULL) {}
};

std::vector<int> nextGreaterNodes(ListNode* head) {
    std::vector<int> result;
    std::stack<int> greater;
    while (head) {
        while (!greater.empty() && greater.top() < head->val) {
            greater.top() = head->val;
            greater.pop();
        }
        result.push_back(head->val);
        greater.push(0);
        head = head->next;
    }
    return result;
}
```
The algorithm starts by initializing an empty vector to store the results and an empty stack to keep track of the indices of the nodes. Then it iterates through the linked list using the given head. At each node, it compares the top of the stack to the current node's value. If the top of the stack is smaller than the current node's value, the top of the stack will be replaced with the current node's value and the stack will be popped. It will continue doing this until the condition is no longer satisfied or the stack is empty. The value of the current node is then added to the results vector and the index of the latest value that was added gets pushed to the stack. Finally, the algorithm checks if the stack is not empty; if it isn't, the top of the stack will be set to 0 and the stack will be popped. The results vector is then returned. This algorithm works the same way across all four languages, with the only differences being in the syntax and the specific data structures used.

## A solution in Python

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

def nextGreaterNodes(head):
    result = []
    stack = []
    while head:
        while stack and stack[-1] < head.val:
            stack[-1] = head.val
            stack.pop()
        result.append(head.val)
        stack.append(len(result) - 1)
        head = head.next

    while stack:
        result[stack.pop()] = 0

    return result
```
The algorithm starts by initializing an empty vector to store the results and an empty stack to keep track of the indices of the nodes. Then it iterates through the linked list using the given head. At each node, it compares the top of the stack to the current node's value. If the top of the stack is smaller than the current node's value, the top of the stack will be replaced with the current node's value and the stack will be popped. It will continue doing this until the condition is no longer satisfied or the stack is empty. The value of the current node is then added to the results vector and the index of the latest value that was added gets pushed to the stack. Finally, the algorithm checks if the stack is not empty; if it isn't, the top of the stack will be set to 0 and the stack will be popped. The results vector is then returned. This algorithm works the same way across all four languages, with the only differences being in the syntax and the specific data structures used.

## A solution in Javascript

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

function nextGreaterNodes(head) {
    const result = [];
    const stack = [];

    let current = head;
    while (current) {
        while (stack.length > 0 && result[stack[stack.length - 1]] < current.val) {
            result[stack.pop()] = current.val;
        }
        result.push(current.val);
        stack.push(result.length - 1);
        current = current.next;
    }

    while (stack.length > 0) {
        result[stack.pop()] = 0;
    }

    return result;
}
```
The algorithm starts by initializing an empty vector to store the results and an empty stack to keep track of the indices of the nodes. Then it iterates through the linked list using the given head. At each node, it compares the top of the stack to the current node's value. If the top of the stack is smaller than the current node's value, the top of the stack will be replaced with the current node's value and the stack will be popped. It will continue doing this until the condition is no longer satisfied or the stack is empty. The value of the current node is then added to the results vector and the index of the latest value that was added gets pushed to the stack. Finally, the algorithm checks if the stack is not empty; if it isn't, the top of the stack will be set to 0 and the stack will be popped. The results vector is then returned. This algorithm works the same way across all four languages, with the only differences being in the syntax and the specific data structures used.


# Adding Two Negabinary Numbers

- slug: adding-two-negabinary-numbers
- difficulty: Medium

Given two numbers `arr1` and `arr2` in base **\-2**, return the result of adding them together.

Each number is given in _array format_: as an array of 0s and 1s, from most significant bit to least significant bit. For example, `arr = [1,1,0,1]` represents the number `(-2)^3 + (-2)^2 + (-2)^0 = -3`. A number `arr` in _array, format_ is also guaranteed to have no leading zeros: either `arr == [0]` or `arr[0] == 1`.

Return the result of adding `arr1` and `arr2` in the same format: as an array of 0s and 1s with no leading zeros.

**Example 1:**

**Input:** arr1 = \[1,1,1,1,1\], arr2 = \[1,0,1\]
**Output:** \[1,0,0,0,0\]
**Explanation:** arr1 represents 11, arr2 represents 5, the output represents 16.

**Example 2:**

**Input:** arr1 = \[0\], arr2 = \[0\]
**Output:** \[0\]

**Example 3:**

**Input:** arr1 = \[0\], arr2 = \[1\]
**Output:** \[1\]

**Constraints:**

*   `1 <= arr1.length, arr2.length <= 1000`
*   `arr1[i]` and `arr2[i]` are `0` or `1`
*   `arr1` and `arr2` have no leading zeros

## A solution in Java

```java
import java.util.*;

public class Solution {
    public int[] addNegabinary(int[] arr1, int[] arr2) {
        LinkedList<Integer> res = new LinkedList<>();
        int i = arr1.length - 1, j = arr2.length - 1, carry = 0;
        while (i >= 0 || j >= 0 || carry < 0 || carry > 0) {
            if (i >= 0) carry += arr1[i--];
            if (j >= 0) carry += arr2[j--];
            res.addFirst(carry & 1);
            carry = -(carry >> 1);
        }
        while (res.size() > 1 && res.peekFirst() == 0) res.pollFirst();
        return res.stream().mapToInt(Integer::intValue).toArray();
    }
}
```
The algorithm follows the idea of binary addition. We iterate through the input arrays from right to left, summing the corresponding bits and keeping track of the carry value. Since we are working with base -2, we divide the carry value by -2 after each step of calculation (equivalent to -right shift by 1). We keep updating the carry value until we reach the end of both arrays and the carry value is 0. Finally, we remove any leading zeros in the result array.

## A solution in C++

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

vector<int> addNegabinary(vector<int>& arr1, vector<int>& arr2) {
    vector<int> res;
    int carry = 0, i = arr1.size() - 1, j = arr2.size() - 1;
    while (i >= 0 || j >= 0 || carry) {
        if (i >= 0) carry += arr1[i--];
        if (j >= 0) carry += arr2[j--];
        res.push_back(carry & 1);
        carry = -(carry >> 1);
    }
    while (res.size() > 1 && res.back() == 0) res.pop_back();
    reverse(res.begin(), res.end());
    return res;
}
```
The algorithm follows the idea of binary addition. We iterate through the input arrays from right to left, summing the corresponding bits and keeping track of the carry value. Since we are working with base -2, we divide the carry value by -2 after each step of calculation (equivalent to -right shift by 1). We keep updating the carry value until we reach the end of both arrays and the carry value is 0. Finally, we remove any leading zeros in the result array.

## A solution in Python

```python
from collections import deque

def addNegabinary(arr1, arr2):
    res = deque()
    carry, i, j = 0, len(arr1) - 1, len(arr2) - 1
    while i >= 0 or j >= 0 or carry:
        if i >= 0: carry += arr1[i]; i -= 1
        if j >= 0: carry += arr2[j]; j -= 1
        res.appendleft(carry & 1)
        carry = -(carry >> 1)
    while len(res) > 1 and res[0] == 0: res.popleft()
    return list(res)
```
The algorithm follows the idea of binary addition. We iterate through the input arrays from right to left, summing the corresponding bits and keeping track of the carry value. Since we are working with base -2, we divide the carry value by -2 after each step of calculation (equivalent to -right shift by 1). We keep updating the carry value until we reach the end of both arrays and the carry value is 0. Finally, we remove any leading zeros in the result array.

## A solution in Javascript

```javascript
function addNegabinary(arr1, arr2) {
    const res = [];
    let carry = 0, i = arr1.length - 1, j = arr2.length - 1;
    while (i >= 0 || j >= 0 || carry) {
        if (i >= 0) carry += arr1[i--];
        if (j >= 0) carry += arr2[j--];
        res.unshift(carry & 1);
        carry = -(carry >> 1);
    }
    while (res.length > 1 && res[0] == 0) res.shift();
    return res;
}
```
The algorithm follows the idea of binary addition. We iterate through the input arrays from right to left, summing the corresponding bits and keeping track of the carry value. Since we are working with base -2, we divide the carry value by -2 after each step of calculation (equivalent to -right shift by 1). We keep updating the carry value until we reach the end of both arrays and the carry value is 0. Finally, we remove any leading zeros in the result array.


# Number of Submatrices That Sum to Target

- slug: number-of-submatrices-that-sum-to-target
- difficulty: Hard

Given a `matrix` and a `target`, return the number of non-empty submatrices that sum to target.

A submatrix `x1, y1, x2, y2` is the set of all cells `matrix[x][y]` with `x1 <= x <= x2` and `y1 <= y <= y2`.

Two submatrices `(x1, y1, x2, y2)` and `(x1', y1', x2', y2')` are different if they have some coordinate that is different: for example, if `x1 != x1'`.

**Example 1:**

**Input:** matrix = \[\[0,1,0\],\[1,1,1\],\[0,1,0\]\], target = 0
**Output:** 4
**Explanation:** The four 1x1 submatrices that only contain 0.

**Example 2:**

**Input:** matrix = \[\[1,-1\],\[-1,1\]\], target = 0
**Output:** 5
**Explanation:** The two 1x2 submatrices, plus the two 2x1 submatrices, plus the 2x2 submatrix.

**Example 3:**

**Input:** matrix = \[\[904\]\], target = 0
**Output:** 0

**Constraints:**

*   `1 <= matrix.length <= 100`
*   `1 <= matrix[0].length <= 100`
*   `-1000 <= matrix[i] <= 1000`
*   `-10^8 <= target <= 10^8`

## A solution in Java

```java
public int numSubmatrixSumTarget(int[][] matrix, int target) {
    int rows = matrix.length, cols = matrix[0].length;
    for (int row = 0; row < rows; ++row)
        for (int col = 1; col < cols; ++col)
            matrix[row][col] += matrix[row][col-1];

    int count = 0;
    Map<Integer, Integer> counter = new HashMap<>();
    for (int col1 = 0; col1 < cols; ++col1) {
        for (int col2 = col1; col2 < cols; ++col2) {
            counter.clear();
            counter.put(0, 1);
            int cur_sum = 0;
            for (int row = 0; row < rows; ++row) {
                cur_sum += matrix[row][col2] - (col1 > 0 ? matrix[row][col1-1] : 0);
                count += counter.getOrDefault(cur_sum - target, 0);
                counter.put(cur_sum, counter.getOrDefault(cur_sum, 0) + 1);
            }
        }
    }
    return count;
}
```
1. First, we need to find the prefix sum of each row in the matrix. This means that the value at the cell (i, j) will store the sum of all elements from (i, 0) to (i, j) in the same row.
2. Then, we iterate through all possible column pairs (col1, col2), and calculate the sum between those columns for each row using the prefix sum.
3. We use a hashmap to store the sum we have encountered so far and their counts.
4. For each row, update the sum and check how many times we have encountered the sum - target from the hashmap.
5. Add the count and update the hashmap for the current sum.
6. Return the total count after iterating all possible column pairs.

## A solution in C++

```cpp
int numSubmatrixSumTarget(vector<vector<int>>& matrix, int target) {
    int rows = matrix.size(), cols = matrix[0].size();
    for (int row = 0; row < rows; ++row)
        for (int col = 1; col < cols; ++col)
            matrix[row][col] += matrix[row][col-1];

    int count = 0;
    unordered_map<int, int> counter;
    for (int col1 = 0; col1 < cols; ++col1) {
        for (int col2 = col1; col2 < cols; ++col2) {
            counter.clear();
            counter[0] = 1;
            int cur_sum = 0;
            for (int row = 0; row < rows; ++row) {
                cur_sum += matrix[row][col2] - (col1 > 0 ? matrix[row][col1-1] : 0);
                count += counter[cur_sum - target];
                ++counter[cur_sum];
            }
        }
    }
    return count;
}
```
1. First, we need to find the prefix sum of each row in the matrix. This means that the value at the cell (i, j) will store the sum of all elements from (i, 0) to (i, j) in the same row.
2. Then, we iterate through all possible column pairs (col1, col2), and calculate the sum between those columns for each row using the prefix sum.
3. We use a hashmap to store the sum we have encountered so far and their counts.
4. For each row, update the sum and check how many times we have encountered the sum - target from the hashmap.
5. Add the count and update the hashmap for the current sum.
6. Return the total count after iterating all possible column pairs.

## A solution in Python

```python
def numSubmatrixSumTarget(matrix: List[List[int]], target: int) -> int:
    rows, cols = len(matrix), len(matrix[0])
    for row in range(rows):
        for col in range(1, cols):
            matrix[row][col] += matrix[row][col-1]

    count = 0
    for col1 in range(cols):
        for col2 in range(col1, cols):
            counter = collections.defaultdict(int)
            counter[0] = 1
            cur_sum = 0
            for row in range(rows):
                cur_sum += matrix[row][col2] - (matrix[row][col1-1] if col1 > 0 else 0)
                count += counter[cur_sum - target]
                counter[cur_sum] += 1

    return count
```
1. First, we need to find the prefix sum of each row in the matrix. This means that the value at the cell (i, j) will store the sum of all elements from (i, 0) to (i, j) in the same row.
2. Then, we iterate through all possible column pairs (col1, col2), and calculate the sum between those columns for each row using the prefix sum.
3. We use a hashmap to store the sum we have encountered so far and their counts.
4. For each row, update the sum and check how many times we have encountered the sum - target from the hashmap.
5. Add the count and update the hashmap for the current sum.
6. Return the total count after iterating all possible column pairs.

## A solution in Javascript

```javascript
var numSubmatrixSumTarget = function(matrix, target) {
    const rows = matrix.length, cols = matrix[0].length;
    for (let row = 0; row < rows; ++row)
        for (let col = 1; col < cols; ++col)
            matrix[row][col] += matrix[row][col-1];

    let count = 0;
    for (let col1 = 0; col1 < cols; ++col1) {
        for (let col2 = col1; col2 < cols; ++col2) {
            const counter = new Map();
            counter.set(0, 1);
            let cur_sum = 0;
            for (let row = 0; row < rows; ++row) {
                cur_sum += matrix[row][col2] - (col1 > 0 ? matrix[row][col1-1] : 0);
                count += (counter.get(cur_sum - target) || 0);
                counter.set(cur_sum, (counter.get(cur_sum) || 0) + 1);
            }
        }
    }
    return count;
};
```
1. First, we need to find the prefix sum of each row in the matrix. This means that the value at the cell (i, j) will store the sum of all elements from (i, 0) to (i, j) in the same row.
2. Then, we iterate through all possible column pairs (col1, col2), and calculate the sum between those columns for each row using the prefix sum.
3. We use a hashmap to store the sum we have encountered so far and their counts.
4. For each row, update the sum and check how many times we have encountered the sum - target from the hashmap.
5. Add the count and update the hashmap for the current sum.
6. Return the total count after iterating all possible column pairs.


# Occurrences After Bigram

- slug: occurrences-after-bigram
- difficulty: Easy

Given two strings `first` and `second`, consider occurrences in some text of the form `"first second third "`, where `second` comes immediately after `first`, and `third` comes immediately after `second`.

Return _an array of all the words_ `third` _for each occurrence of_ `"first second third "`.

**Example 1:**

**Input:** text = "alice is a good girl she is a good student", first = "a", second = "good"
**Output:** \["girl","student"\]

**Example 2:**

**Input:** text = "we will we will rock you", first = "we", second = "will"
**Output:** \["we","rock"\]

**Constraints:**

*   `1 <= text.length <= 1000`
*   `text` consists of lowercase English letters and spaces.
*   All the words in `text` a separated by **a single space**.
*   `1 <= first.length, second.length <= 10`
*   `first` and `second` consist of lowercase English letters.

## A solution in Java

```java
public String removeOuterParentheses(String s) {
    StringBuilder result = new StringBuilder();
    int opened = 0;

    for (char c : s.toCharArray()) {
        if (c == '(' && opened++ > 0) {
            result.append(c);
        }
        if (c == ')' && opened-- > 1) {
            result.append(c);
        }
    }
    return result.toString();
}
```
The algorithm is fairly simple. We will iterate through the given string `s`. For each character in the string, we will keep track of the count of open-parentheses encountered so far using the variable `opened`.

- If we find an open-parenthesis `(`, and the value of `opened` is more than 0, we append it to the resulting string. Then, we increment the value of `opened`.
- If we find a close-parenthesis `)`, and the value of `opened` is more than 1, we append it to the resulting string. Then, we decrement the value of `opened`.

By doing this, we effectively skip the outermost parentheses of each primitive valid parentheses string, as required by the problem while constructing the result string.

## A solution in C++

```cpp
#include <string>
#include <stack>

std::string removeOuterParentheses(std::string s) {
    std::string result;
    int opened = 0;

    for (char c : s) {
        if (c == '(' && opened++ > 0) {
            result += c;
        }
        if (c == ')' && opened-- > 1) {
            result += c;
        }
    }
    return result;
}
```
The algorithm is fairly simple. We will iterate through the given string `s`. For each character in the string, we will keep track of the count of open-parentheses encountered so far using the variable `opened`.

- If we find an open-parenthesis `(`, and the value of `opened` is more than 0, we append it to the resulting string. Then, we increment the value of `opened`.
- If we find a close-parenthesis `)`, and the value of `opened` is more than 1, we append it to the resulting string. Then, we decrement the value of `opened`.

By doing this, we effectively skip the outermost parentheses of each primitive valid parentheses string, as required by the problem while constructing the result string.

## A solution in Python

```python
def remove_outer_parentheses(s: str) -> str:
    result = []
    opened = 0

    for c in s:
        if c == '(':
            if opened > 0:
                result.append(c)
            opened += 1
        elif c == ')':
            if opened > 1:
                result.append(c)
            opened -= 1

    return ''.join(result)
```
The algorithm is fairly simple. We will iterate through the given string `s`. For each character in the string, we will keep track of the count of open-parentheses encountered so far using the variable `opened`.

- If we find an open-parenthesis `(`, and the value of `opened` is more than 0, we append it to the resulting string. Then, we increment the value of `opened`.
- If we find a close-parenthesis `)`, and the value of `opened` is more than 1, we append it to the resulting string. Then, we decrement the value of `opened`.

By doing this, we effectively skip the outermost parentheses of each primitive valid parentheses string, as required by the problem while constructing the result string.

## A solution in Javascript

```javascript
function removeOuterParentheses(s) {
    let result = "";
    let opened = 0;

    for (let c of s) {
        if (c === '(' && opened++ > 0) {
            result += c;
        }
        if (c === ')' && opened-- > 1) {
            result += c;
        }
    }

    return result;
}
```
The algorithm is fairly simple. We will iterate through the given string `s`. For each character in the string, we will keep track of the count of open-parentheses encountered so far using the variable `opened`.

- If we find an open-parenthesis `(`, and the value of `opened` is more than 0, we append it to the resulting string. Then, we increment the value of `opened`.
- If we find a close-parenthesis `)`, and the value of `opened` is more than 1, we append it to the resulting string. Then, we decrement the value of `opened`.

By doing this, we effectively skip the outermost parentheses of each primitive valid parentheses string, as required by the problem while constructing the result string.


# Letter Tile Possibilities

- slug: letter-tile-possibilities
- difficulty: Medium

You have `n` `tiles`, where each tile has one letter `tiles[i]` printed on it.

Return _the number of possible non-empty sequences of letters_ you can make using the letters printed on those `tiles`.

**Example 1:**

**Input:** tiles =  "AAB "
**Output:** 8
**Explanation:** The possible sequences are  "A ",  "B ",  "AA ",  "AB ",  "BA ",  "AAB ",  "ABA ",  "BAA ".

**Example 2:**

**Input:** tiles =  "AAABBC "
**Output:** 188

**Example 3:**

**Input:** tiles =  "V "
**Output:** 1

**Constraints:**

*   `1 <= tiles.length <= 7`
*   `tiles` consists of uppercase English letters.

## A solution in Java

```java
public int sumRootToLeaf(TreeNode root) {
    return sumHelper(root, 0);
}

private int sumHelper(TreeNode node, int value) {
    if (node == null) return 0;
    value = value * 2 + node.val;
    if (node.left == null && node.right == null) return value;
    return sumHelper(node.left, value) + sumHelper(node.right, value);
}
```
The algorithm uses a Depth-First-Search approach. Starting from the root node, it recursively traverses the tree in a depth-first manner. The running path value is computed by shifting the current path value left (multiply by 2) and adding the value of the current node. If the current node is a leaf node (both left and right children are null), return the current path value. Otherwise, return the sum of the subtrees rooted at the left and right children. The recursion function has an optional argument, `path_value`, which helps to carry the running path value during the traversal.

## A solution in C++

```cpp
int sumRootToLeaf(TreeNode* root, int path_val = 0) {
    if (!root) return 0;
    path_val = path_val * 2 + root->val;
    if (!root->left && !root->right) return path_val;
    return sumRootToLeaf(root->left, path_val) + sumRootToLeaf(root->right, path_val);
}
```
The algorithm uses a Depth-First-Search approach. Starting from the root node, it recursively traverses the tree in a depth-first manner. The running path value is computed by shifting the current path value left (multiply by 2) and adding the value of the current node. If the current node is a leaf node (both left and right children are null), return the current path value. Otherwise, return the sum of the subtrees rooted at the left and right children. The recursion function has an optional argument, `path_value`, which helps to carry the running path value during the traversal.

## A solution in Python

```python
def sumRootToLeaf(root, path_value=0):
    if not root:
        return 0
    path_value = path_value * 2 + root.val
    if not root.left and not root.right:
        return path_value
    return sumRootToLeaf(root.left, path_value) + sumRootToLeaf(root.right, path_value)
```
The algorithm uses a Depth-First-Search approach. Starting from the root node, it recursively traverses the tree in a depth-first manner. The running path value is computed by shifting the current path value left (multiply by 2) and adding the value of the current node. If the current node is a leaf node (both left and right children are null), return the current path value. Otherwise, return the sum of the subtrees rooted at the left and right children. The recursion function has an optional argument, `path_value`, which helps to carry the running path value during the traversal.

## A solution in Javascript

```javascript
function sumRootToLeaf(root, pathValue = 0) {
    if (!root) return 0;
    pathValue = pathValue * 2 + root.val;
    if (!root.left && !root.right) return pathValue;
    return sumRootToLeaf(root.left, pathValue) + sumRootToLeaf(root.right, pathValue);
}
```
The algorithm uses a Depth-First-Search approach. Starting from the root node, it recursively traverses the tree in a depth-first manner. The running path value is computed by shifting the current path value left (multiply by 2) and adding the value of the current node. If the current node is a leaf node (both left and right children are null), return the current path value. Otherwise, return the sum of the subtrees rooted at the left and right children. The recursion function has an optional argument, `path_value`, which helps to carry the running path value during the traversal.


# Insufficient Nodes in Root to Leaf Paths

- slug: insufficient-nodes-in-root-to-leaf-paths
- difficulty: Medium

Given the `root` of a binary tree and an integer `limit`, delete all **insufficient nodes** in the tree simultaneously, and return _the root of the resulting binary tree_.

A node is **insufficient** if every root to **leaf** path intersecting this node has a sum strictly less than `limit`.

A **leaf** is a node with no children.

**Example 1:**

**Input:** root = \[1,2,3,4,-99,-99,7,8,9,-99,-99,12,13,-99,14\], limit = 1
**Output:** \[1,2,3,4,null,null,7,8,9,null,14\]

**Example 2:**

**Input:** root = \[5,4,8,11,null,17,4,7,1,null,null,5,3\], limit = 22
**Output:** \[5,4,8,11,null,17,4,7,null,null,null,5\]

**Example 3:**

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

**Constraints:**

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

## A solution in Java

```java
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode sufficientSubset(TreeNode root, int limit) {
        if(root == null) return null;
        if(root.left == null && root.right == null) {
            if(root.val < limit) return null;
            return root;
        }
        root.left = sufficientSubset(root.left, limit - root.val);
        root.right = sufficientSubset(root.right, limit - root.val);
        if(root.left == null && root.right == null) return null;

        return root;
    }
}
```
The algorithm solves this problem by recursively checking each node in the binary tree for any insufficient children. If a node is insufficient, we want to remove it from the tree. We start by checking whether a node has any children - if not, it's a leaf node and should be checked for insufficiency. Then, we return either the node if it's sufficient, or `null` if it's not.

Next, we recursively check both the left and right children of a node, pruning the tree by updating their references with their sufficient children. If a node's left and right children are both `null`, it means they were insufficient and the node itself should also be checked for insufficiency. If it's insufficient, we return `null`, otherwise, we return the node.

By going through the binary tree recursively we effectively remove any insufficient nodes and return the root of the modified tree.

## A solution in C++

```cpp
// Definition for a binary tree node.
// struct TreeNode {
//     int val;
//     TreeNode *left;
//     TreeNode *right;
//     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
// };

class Solution {
public:
    TreeNode* sufficientSubset(TreeNode* root, int limit) {
        if(!root) return nullptr;
        if(!root->left && !root->right) {
            if(root->val < limit) return nullptr;
            return root;
        }
        root->left = sufficientSubset(root->left, limit - root->val);
        root->right = sufficientSubset(root->right, limit - root->val);
        if(!root->left && !root->right) return nullptr;

        return root;
    }
};
```
The algorithm solves this problem by recursively checking each node in the binary tree for any insufficient children. If a node is insufficient, we want to remove it from the tree. We start by checking whether a node has any children - if not, it's a leaf node and should be checked for insufficiency. Then, we return either the node if it's sufficient, or `null` if it's not.

Next, we recursively check both the left and right children of a node, pruning the tree by updating their references with their sufficient children. If a node's left and right children are both `null`, it means they were insufficient and the node itself should also be checked for insufficiency. If it's insufficient, we return `null`, otherwise, we return the node.

By going through the binary tree recursively we effectively remove any insufficient nodes and return the root of the modified tree.

## A solution in Python

```python
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sufficientSubset(self, root: TreeNode, limit: int) -> TreeNode:
        if not root:
            return None
        if not root.left and not root.right:
            if root.val < limit:
                return None
            return root
        root.left = self.sufficientSubset(root.left, limit - root.val)
        root.right = self.sufficientSubset(root.right, limit - root.val)
        if not root.left and not root.right:
            return None

        return root
```
The algorithm solves this problem by recursively checking each node in the binary tree for any insufficient children. If a node is insufficient, we want to remove it from the tree. We start by checking whether a node has any children - if not, it's a leaf node and should be checked for insufficiency. Then, we return either the node if it's sufficient, or `null` if it's not.

Next, we recursively check both the left and right children of a node, pruning the tree by updating their references with their sufficient children. If a node's left and right children are both `null`, it means they were insufficient and the node itself should also be checked for insufficiency. If it's insufficient, we return `null`, otherwise, we return the node.

By going through the binary tree recursively we effectively remove any insufficient nodes and return the root of the modified tree.

## A solution in Javascript

```javascript
// Definition for a binary tree node.
// function TreeNode(val, left, right) {
//     this.val = (val===undefined ? 0 : val)
//     this.left = (left===undefined ? null : left)
//     this.right = (right===undefined ? null : right)
// }

/**
 * @param {TreeNode} root
 * @param {number} limit
 * @return {TreeNode}
 */
var sufficientSubset = function(root, limit) {
    if(!root) return null;
    if(!root.left && !root.right) {
        if(root.val < limit) return null;
        return root;
    }
    root.left = sufficientSubset(root.left, limit - root.val);
    root.right = sufficientSubset(root.right, limit - root.val);
    if(!root.left && !root.right) return null;

    return root;
};
```
The algorithm solves this problem by recursively checking each node in the binary tree for any insufficient children. If a node is insufficient, we want to remove it from the tree. We start by checking whether a node has any children - if not, it's a leaf node and should be checked for insufficiency. Then, we return either the node if it's sufficient, or `null` if it's not.

Next, we recursively check both the left and right children of a node, pruning the tree by updating their references with their sufficient children. If a node's left and right children are both `null`, it means they were insufficient and the node itself should also be checked for insufficiency. If it's insufficient, we return `null`, otherwise, we return the node.

By going through the binary tree recursively we effectively remove any insufficient nodes and return the root of the modified tree.


# Smallest Subsequence of Distinct Characters

- slug: smallest-subsequence-of-distinct-characters
- difficulty: Medium

Given a string `s`, return _the_ _lexicographically smallest_ _subsequence_ _of_ `s` _that contains all the distinct characters of_ `s` _exactly once_.

**Example 1:**

**Input:** s =  "bcabc "
**Output:**  "abc "

**Example 2:**

**Input:** s =  "cbacdcbc "
**Output:**  "acdb "

**Constraints:**

*   `1 <= s.length <= 1000`
*   `s` consists of lowercase English letters.

**Note:** This question is the same as 316: [https://leetcode.com/problems/remove-duplicate-letters/](https://leetcode.com/problems/remove-duplicate-letters/)

## A solution in Java

```java
import java.util.Arrays;

public int videoStitching(int[][] clips, int time) {
    int[] dp = new int[time + 1];
    Arrays.fill(dp, Integer.MAX_VALUE);
    dp[0] = 0;
    for (int i = 1; i <= time; ++i) {
        for (int[] clip : clips) {
            if (clip[0] < i && i <= clip[1]) {
                dp[i] = Math.min(dp[i], dp[clip[0]] + 1);
            }
        }
    }
    return dp[time] == Integer.MAX_VALUE ? -1 : dp[time];
}
```
We use dynamic programming to solve this problem. We create an array `dp` of length `time + 1` and initialize it with infinity, except for `dp[0]`, which we set to 0. To find the minimum number of clips needed to cover the entire sporting event, we iterate through the range from 1 to `time` (inclusive). For each value `i`, we loop through all the clips, and if we found a clip that can contribute to the current value of 'i', we update the `dp[i]` value with the minimum of itself and the value of `dp[clip[0]] + 1`. This ensures that we take the minimum possible number of clips to reach the current segment. Finally, we return the value of `dp[time]`, or `-1` if it is still infinity, which indicates that the task is impossible.

## A solution in C++

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

int videoStitching(vector<vector<int>>& clips, int time) {
    vector<int> dp(time + 1, INT_MAX);
    dp[0] = 0;
    for (int i = 1; i <= time; ++i) {
        for (const auto& clip : clips) {
            if (clip[0] < i && i <= clip[1]) {
                dp[i] = min(dp[i], dp[clip[0]] + 1);
            }
        }
    }
    return dp[time] == INT_MAX ? -1 : dp[time];
}
```
We use dynamic programming to solve this problem. We create an array `dp` of length `time + 1` and initialize it with infinity, except for `dp[0]`, which we set to 0. To find the minimum number of clips needed to cover the entire sporting event, we iterate through the range from 1 to `time` (inclusive). For each value `i`, we loop through all the clips, and if we found a clip that can contribute to the current value of 'i', we update the `dp[i]` value with the minimum of itself and the value of `dp[clip[0]] + 1`. This ensures that we take the minimum possible number of clips to reach the current segment. Finally, we return the value of `dp[time]`, or `-1` if it is still infinity, which indicates that the task is impossible.

## A solution in Python

```python
def videoStitching(clips, time):
    dp = [float('inf')] * (time + 1)
    dp[0] = 0
    for i in range(1, time + 1):
        for clip in clips:
            if clip[0] < i and i <= clip[1]:
                dp[i] = min(dp[i], dp[clip[0]] + 1)
    return -1 if dp[time] == float('inf') else dp[time]
```
We use dynamic programming to solve this problem. We create an array `dp` of length `time + 1` and initialize it with infinity, except for `dp[0]`, which we set to 0. To find the minimum number of clips needed to cover the entire sporting event, we iterate through the range from 1 to `time` (inclusive). For each value `i`, we loop through all the clips, and if we found a clip that can contribute to the current value of 'i', we update the `dp[i]` value with the minimum of itself and the value of `dp[clip[0]] + 1`. This ensures that we take the minimum possible number of clips to reach the current segment. Finally, we return the value of `dp[time]`, or `-1` if it is still infinity, which indicates that the task is impossible.

## A solution in Javascript

```javascript
function videoStitching(clips, time) {
    let dp = new Array(time + 1).fill(Number.MAX_SAFE_INTEGER);
    dp[0] = 0;
    for (let i = 1; i <= time; ++i) {
        for (const clip of clips) {
            if (clip[0] < i && i <= clip[1]) {
                dp[i] = Math.min(dp[i], dp[clip[0]] + 1);
            }
        }
    }
    return dp[time] === Number.MAX_SAFE_INTEGER ? -1 : dp[time];
}
```
We use dynamic programming to solve this problem. We create an array `dp` of length `time + 1` and initialize it with infinity, except for `dp[0]`, which we set to 0. To find the minimum number of clips needed to cover the entire sporting event, we iterate through the range from 1 to `time` (inclusive). For each value `i`, we loop through all the clips, and if we found a clip that can contribute to the current value of 'i', we update the `dp[i]` value with the minimum of itself and the value of `dp[clip[0]] + 1`. This ensures that we take the minimum possible number of clips to reach the current segment. Finally, we return the value of `dp[time]`, or `-1` if it is still infinity, which indicates that the task is impossible.


# Sum of Digits in the Minimum Number

- slug: sum-of-digits-in-the-minimum-number
- difficulty: Easy

Given an integer array `nums`, return `0` _if the sum of the digits of the minimum integer in_ `nums` _is odd, or_ `1` _otherwise_.

**Example 1:**

**Input:** nums = \[34,23,1,24,75,33,54,8\]
**Output:** 0
**Explanation:** The minimal element is 1, and the sum of those digits is 1 which is odd, so the answer is 0.

**Example 2:**

**Input:** nums = \[99,77,33,66,55\]
**Output:** 1
**Explanation:** The minimal element is 33, and the sum of those digits is 3 + 3 = 6 which is even, so the answer is 1.

**Constraints:**

*   `1 <= nums.length <= 100`
*   `1 <= nums[i] <= 100`

## A solution in Java

```java
public int sumOfDigits(int[] nums) {
    int minVal = Arrays.stream(nums).min().getAsInt();
    int digitSum = 0;
    while (minVal > 0) {
        digitSum += minVal % 10;
        minVal /= 10;
    }
    return digitSum % 2 == 0 ? 1 : 0;
}
```
1. Find the minimal element (`minVal`) of given array `nums`.
2. Calculate the sum of the digits of the minimal element (`digitSum`).
3. Check if the sum of the digits is odd or even.
   - If it's even, return 1.
   - If it's odd, return 0.

## A solution in C++

```cpp
int sumOfDigits(vector<int>& nums) {
    int minVal = *min_element(nums.begin(), nums.end());
    int digitSum = 0;
    while (minVal > 0) {
        digitSum += minVal % 10;
        minVal /= 10;
    }
    return digitSum % 2 == 0 ? 1 : 0;
}
```
1. Find the minimal element (`minVal`) of given array `nums`.
2. Calculate the sum of the digits of the minimal element (`digitSum`).
3. Check if the sum of the digits is odd or even.
   - If it's even, return 1.
   - If it's odd, return 0.

## A solution in Python

```python
def sum_of_digits(nums):
    min_val = min(nums)
    digit_sum = sum(int(digit) for digit in str(min_val))
    return 1 if digit_sum % 2 == 0 else 0
```
1. Find the minimal element (`minVal`) of given array `nums`.
2. Calculate the sum of the digits of the minimal element (`digitSum`).
3. Check if the sum of the digits is odd or even.
   - If it's even, return 1.
   - If it's odd, return 0.

## A solution in Javascript

```javascript
function sumOfDigits(nums) {
    const minVal = Math.min(...nums);
    let digitSum = 0;
    let temp = minVal;
    while (temp > 0) {
        digitSum += temp % 10;
        temp = Math.floor(temp / 10);
    }
    return digitSum % 2 === 0 ? 1 : 0;
}
```
1. Find the minimal element (`minVal`) of given array `nums`.
2. Calculate the sum of the digits of the minimal element (`digitSum`).
3. Check if the sum of the digits is odd or even.
   - If it's even, return 1.
   - If it's odd, return 0.


# High Five

- slug: high-five
- difficulty: Easy

Given a list of the scores of different students, `items`, where `items[i] = [IDi, scorei]` represents one score from a student with `IDi`, calculate each student's **top five average**.

Return _the answer as an array of pairs_ `result`_, where_ `result[j] = [IDj, topFiveAveragej]` _represents the student with_ `IDj` _and their **top five average**. Sort_ `result` _by_ `IDj` _in **increasing order**._

A student's **top five average** is calculated by taking the sum of their top five scores and dividing it by `5` using **integer division**.

**Example 1:**

**Input:** items = \[\[1,91\],\[1,92\],\[2,93\],\[2,97\],\[1,60\],\[2,77\],\[1,65\],\[1,87\],\[1,100\],\[2,100\],\[2,76\]\]
**Output:** \[\[1,87\],\[2,88\]\]
**Explanation:**
The student with ID = 1 got scores 91, 92, 60, 65, 87, and 100. Their top five average is (100 + 92 + 91 + 87 + 65) / 5 = 87.
The student with ID = 2 got scores 93, 97, 77, 100, and 76. Their top five average is (100 + 97 + 93 + 77 + 76) / 5 = 88.6, but with integer division their average converts to 88.

**Example 2:**

**Input:** items = \[\[1,100\],\[7,100\],\[1,100\],\[7,100\],\[1,100\],\[7,100\],\[1,100\],\[7,100\],\[1,100\],\[7,100\]\]
**Output:** \[\[1,100\],\[7,100\]\]

**Constraints:**

*   `1 <= items.length <= 1000`
*   `items[i].length == 2`
*   `1 <= IDi <= 1000`
*   `0 <= scorei <= 100`
*   For each `IDi`, there will be **at least** five scores.

## A solution in Java

```java
boolean aliceWin(int n) {
    return n % 2 == 0;
}
```
The game is a simple parity-based game, where Alice and Bob alternately change the number on the board. Since Alice goes first, if the number on the board is even initially, Alice has the opportunity to make a move and maintain the even number status of the board. If Alice and Bob are playing optimally, they will always choose a number that is a divisor of the current number by 2, to guarantee they leave an even number on the board. In this way, the parity of the number on the board never changes.

So, when the number becomes 1, the player whose turn it is will lose, as they cannot choose a divisor of the current number that is less than the current number. Since the number remains even throughout the game, if it starts as an even number, Alice will always win; if it starts as an odd number, Bob will always win. The algorithm simply checks if the given number is even and returns true if Alice wins, and false otherwise. The code implementations for each language perform the modulo operation `%` to check if the given number is even.

## A solution in C++

```cpp
bool aliceWin(int n) {
    return n % 2 == 0;
}
```
The game is a simple parity-based game, where Alice and Bob alternately change the number on the board. Since Alice goes first, if the number on the board is even initially, Alice has the opportunity to make a move and maintain the even number status of the board. If Alice and Bob are playing optimally, they will always choose a number that is a divisor of the current number by 2, to guarantee they leave an even number on the board. In this way, the parity of the number on the board never changes.

So, when the number becomes 1, the player whose turn it is will lose, as they cannot choose a divisor of the current number that is less than the current number. Since the number remains even throughout the game, if it starts as an even number, Alice will always win; if it starts as an odd number, Bob will always win. The algorithm simply checks if the given number is even and returns true if Alice wins, and false otherwise. The code implementations for each language perform the modulo operation `%` to check if the given number is even.

## A solution in Python

```python
def alice_win(n):
    return n % 2 == 0
```
The game is a simple parity-based game, where Alice and Bob alternately change the number on the board. Since Alice goes first, if the number on the board is even initially, Alice has the opportunity to make a move and maintain the even number status of the board. If Alice and Bob are playing optimally, they will always choose a number that is a divisor of the current number by 2, to guarantee they leave an even number on the board. In this way, the parity of the number on the board never changes.

So, when the number becomes 1, the player whose turn it is will lose, as they cannot choose a divisor of the current number that is less than the current number. Since the number remains even throughout the game, if it starts as an even number, Alice will always win; if it starts as an odd number, Bob will always win. The algorithm simply checks if the given number is even and returns true if Alice wins, and false otherwise. The code implementations for each language perform the modulo operation `%` to check if the given number is even.

## A solution in Javascript

```javascript
function aliceWin(n) {
    return n % 2 === 0;
}
```
The game is a simple parity-based game, where Alice and Bob alternately change the number on the board. Since Alice goes first, if the number on the board is even initially, Alice has the opportunity to make a move and maintain the even number status of the board. If Alice and Bob are playing optimally, they will always choose a number that is a divisor of the current number by 2, to guarantee they leave an even number on the board. In this way, the parity of the number on the board never changes.

So, when the number becomes 1, the player whose turn it is will lose, as they cannot choose a divisor of the current number that is less than the current number. Since the number remains even throughout the game, if it starts as an even number, Alice will always win; if it starts as an odd number, Bob will always win. The algorithm simply checks if the given number is even and returns true if Alice wins, and false otherwise. The code implementations for each language perform the modulo operation `%` to check if the given number is even.