# Meeting Rooms III

- slug: meeting-rooms-iii
- difficulty: Hard

You are given an integer `n`. There are `n` rooms numbered from `0` to `n - 1`.

You are given a 2D integer array `meetings` where `meetings[i] = [starti, endi]` means that a meeting will be held during the **half-closed** time interval `[starti, endi)`. All the values of `starti` are **unique**.

Meetings are allocated to rooms in the following manner:

1.  Each meeting will take place in the unused room with the **lowest** number.
2.  If there are no available rooms, the meeting will be delayed until a room becomes free. The delayed meeting should have the **same** duration as the original meeting.
3.  When a room becomes unused, meetings that have an earlier original **start** time should be given the room.

Return _the **number** of the room that held the most meetings._ If there are multiple rooms, return _the room with the **lowest** number._

A **half-closed interval** `[a, b)` is the interval between `a` and `b` **including** `a` and **not including** `b`.

**Example 1:**

**Input:** n = 2, meetings = \[\[0,10\],\[1,5\],\[2,7\],\[3,4\]\]
**Output:** 0
**Explanation:**
- At time 0, both rooms are not being used. The first meeting starts in room 0.
- At time 1, only room 1 is not being used. The second meeting starts in room 1.
- At time 2, both rooms are being used. The third meeting is delayed.
- At time 3, both rooms are being used. The fourth meeting is delayed.
- At time 5, the meeting in room 1 finishes. The third meeting starts in room 1 for the time period \[5,10).
- At time 10, the meetings in both rooms finish. The fourth meeting starts in room 0 for the time period \[10,11).
Both rooms 0 and 1 held 2 meetings, so we return 0.

**Example 2:**

**Input:** n = 3, meetings = \[\[1,20\],\[2,10\],\[3,5\],\[4,9\],\[6,8\]\]
**Output:** 1
**Explanation:**
- At time 1, all three rooms are not being used. The first meeting starts in room 0.
- At time 2, rooms 1 and 2 are not being used. The second meeting starts in room 1.
- At time 3, only room 2 is not being used. The third meeting starts in room 2.
- At time 4, all three rooms are being used. The fourth meeting is delayed.
- At time 5, the meeting in room 2 finishes. The fourth meeting starts in room 2 for the time period \[5,10).
- At time 6, all three rooms are being used. The fifth meeting is delayed.
- At time 10, the meetings in rooms 1 and 2 finish. The fifth meeting starts in room 1 for the time period \[10,12).
Room 0 held 1 meeting while rooms 1 and 2 each held 2 meetings, so we return 1.

**Constraints:**

*   `1 <= n <= 100`
*   `1 <= meetings.length <= 105`
*   `meetings[i].length == 2`
*   `0 <= starti < endi <= 5 * 105`
*   All the values of `starti` are **unique**.

## A solution in Java

```java
import java.util.Arrays;
import java.util.PriorityQueue;

public int mostVisitedRoom(int n, int[][] meetings) {
    Arrays.sort(meetings, (a, b) -> Integer.compare(a[0], b[0]));
    PriorityQueue<int[]> pq = new PriorityQueue<>(((a, b) -> Integer.compare(a[0], b[0])));
    int[] rooms = new int[n];

    for (int[] meeting : meetings) {
        while (!pq.isEmpty() && pq.peek()[0] <= meeting[0]) {
            rooms[pq.poll()[1]]++;
        }
        pq.offer(new int[] {meeting[1], pq.size() % n});
    }
    int result = 0;
    for (int i = 1; i < n; i++) {
        if (rooms[i] > rooms[result]) {
            result = i;
        }
    }
    return result;
}
```
The solution uses a priority queue to manage the state of the rooms. First, we sort the meetings by the start time. For each meeting, we check if there are any rooms that will be available by the meeting's start time. If so, we increment the counter for that room in the `rooms` array, which tracks the number of meetings held in each room.

After looping through all the rooms, we check the `rooms` array to find the room with the highest count of meetings. If there are multiple rooms with the same maximum count, we return the room with the lowest index (room number).

The time complexity of this solution is O(M * log(M)), where M is the number of meetings, mainly due to sorting the meetings and managing the priority queue. The space complexity is O(N+M), where N is the number of rooms, and M is the number of meetings.

## A solution in C++

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

int mostVisitedRoom(int n, std::vector<std::vector<int>>& meetings) {
    std::sort(meetings.begin(), meetings.end());
    std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, std::greater<>> pq;
    std::vector<int> rooms(n);

    for (const auto& meeting : meetings) {
        while (!pq.empty() && pq.top().first <= meeting[0]) {
            ++rooms[pq.top().second];
            pq.pop();
        }
        pq.push({meeting[1], pq.size() % n});
    }
    int result = 0;
    for (int i = 1; i < n; ++i) {
        if (rooms[i] > rooms[result]) {
            result = i;
        }
    }
    return result;
}
```
The solution uses a priority queue to manage the state of the rooms. First, we sort the meetings by the start time. For each meeting, we check if there are any rooms that will be available by the meeting's start time. If so, we increment the counter for that room in the `rooms` array, which tracks the number of meetings held in each room.

After looping through all the rooms, we check the `rooms` array to find the room with the highest count of meetings. If there are multiple rooms with the same maximum count, we return the room with the lowest index (room number).

The time complexity of this solution is O(M * log(M)), where M is the number of meetings, mainly due to sorting the meetings and managing the priority queue. The space complexity is O(N+M), where N is the number of rooms, and M is the number of meetings.

## A solution in Python

```python
import heapq

def most_visited_room(n, meetings):
    meetings.sort()
    pq = []
    rooms = [0] * n

    for start, end in meetings:
        while pq and pq[0][0] <= start:
            _, room = heapq.heappop(pq)
            rooms[room] += 1
        heapq.heappush(pq, (end, len(pq) % n))

    return rooms.index(max(rooms))
```
The solution uses a priority queue to manage the state of the rooms. First, we sort the meetings by the start time. For each meeting, we check if there are any rooms that will be available by the meeting's start time. If so, we increment the counter for that room in the `rooms` array, which tracks the number of meetings held in each room.

After looping through all the rooms, we check the `rooms` array to find the room with the highest count of meetings. If there are multiple rooms with the same maximum count, we return the room with the lowest index (room number).

The time complexity of this solution is O(M * log(M)), where M is the number of meetings, mainly due to sorting the meetings and managing the priority queue. The space complexity is O(N+M), where N is the number of rooms, and M is the number of meetings.

## A solution in Javascript

```javascript
function mostVisitedRoom(n, meetings) {
    meetings.sort((a, b) => a[0] - b[0]);
    const pq = [];
    const rooms = Array(n).fill(0);

    for (const [start, end] of meetings) {
        while (pq.length && pq[0][0] <= start) {
            const [_, room] = pq.shift();
            rooms[room]++;
        }
        pq.push([end, pq.length % n]);
        pq.sort((a, b) => a[0] - b[0]);
    }

    return rooms.indexOf(Math.max(...rooms));
}
```
The solution uses a priority queue to manage the state of the rooms. First, we sort the meetings by the start time. For each meeting, we check if there are any rooms that will be available by the meeting's start time. If so, we increment the counter for that room in the `rooms` array, which tracks the number of meetings held in each room.

After looping through all the rooms, we check the `rooms` array to find the room with the highest count of meetings. If there are multiple rooms with the same maximum count, we return the room with the lowest index (room number).

The time complexity of this solution is O(M * log(M)), where M is the number of meetings, mainly due to sorting the meetings and managing the priority queue. The space complexity is O(N+M), where N is the number of rooms, and M is the number of meetings.


# Minimum Time to Kill All Monsters

- slug: minimum-time-to-kill-all-monsters
- difficulty: Hard

You are given an integer array `power` where `power[i]` is the power of the `ith` monster.

You start with `0` mana points, and each day you increase your mana points by `gain` where `gain` initially is equal to `1`.

Each day, after gaining `gain` mana, you can defeat a monster if your mana points are greater than or equal to the power of that monster. When you defeat a monster:

*   your mana points will be reset to `0`, and
*   the value of `gain` increases by `1`.

Return _the **minimum** number of days needed to defeat all the monsters._

**Example 1:**

**Input:** power = \[3,1,4\]
**Output:** 4
**Explanation:** The optimal way to beat all the monsters is to:
- Day 1: Gain 1 mana point to get a total of 1 mana point. Spend all mana points to kill the 2nd monster.
- Day 2: Gain 2 mana points to get a total of 2 mana points.
- Day 3: Gain 2 mana points to get a total of 4 mana points. Spend all mana points to kill the 3rd monster.
- Day 4: Gain 3 mana points to get a total of 3 mana points. Spend all mana points to kill the 1st monster.
It can be proven that 4 is the minimum number of days needed.

**Example 2:**

**Input:** power = \[1,1,4\]
**Output:** 4
**Explanation:** The optimal way to beat all the monsters is to:
- Day 1: Gain 1 mana point to get a total of 1 mana point. Spend all mana points to kill the 1st monster.
- Day 2: Gain 2 mana points to get a total of 2 mana points. Spend all mana points to kill the 2nd monster.
- Day 3: Gain 3 mana points to get a total of 3 mana points.
- Day 4: Gain 3 mana points to get a total of 6 mana points. Spend all mana points to kill the 3rd monster.
It can be proven that 4 is the minimum number of days needed.

**Example 3:**

**Input:** power = \[1,2,4,9\]
**Output:** 6
**Explanation:** The optimal way to beat all the monsters is to:
- Day 1: Gain 1 mana point to get a total of 1 mana point. Spend all mana points to kill the 1st monster.
- Day 2: Gain 2 mana points to get a total of 2 mana points. Spend all mana points to kill the 2nd monster.
- Day 3: Gain 3 mana points to get a total of 3 mana points.
- Day 4: Gain 3 mana points to get a total of 6 mana points.
- Day 5: Gain 3 mana points to get a total of 9 mana points. Spend all mana points to kill the 4th monster.
- Day 6: Gain 4 mana points to get a total of 4 mana points. Spend all mana points to kill the 3rd monster.
It can be proven that 6 is the minimum number of days needed.

**Constraints:**

*   `1 <= power.length <= 17`
*   `1 <= power[i] <= 109`

## A solution in Java

```java
public int minDays(int[] power) {
    int n = power.length;
    int ans = (int)1e9;
    int[] dp = new int[1 << n];
    Arrays.fill(dp, (int)1e9);

    dp[0] = 0;
    int[] sortedPower = Arrays.copyOf(power, n);
    Arrays.sort(sortedPower);

    for (int i = 0; i < (1 << n); ++i) {
        int powerSum = 0;
        for (int j = 0; j < n; ++j) {
            if ((i & (1 << j)) != 0) {
                powerSum += sortedPower[j];
            }
        }
        int gain = 1 + Integer.bitCount(i);
        for (int j = 0; j < n; ++j) {
            if ((i & (1 << j)) == 0 && gain > sortedPower[j]) {
                dp[i | (1 << j)] = Math.min(dp[i | (1 << j)], dp[i] + 1);
            }
        }
    }
    return dp[(1 << n) - 1];
}
```
1. Sort the given `power` array in ascending order.
2. We will use dynamic programming. Create a `dp` array sized `2^n` and initialized with a large number (eg., `1e9`), where `n` is the length of the `power` array. `dp[i]` represents the minimum number of days needed to defeat the monsters represented by the bitmask `i`.
3. Set `dp[0] = 0`, because no days are needed if there are no monsters.
4. Loop through all possible subsets of the sorted `power` array by iterating through `1 << n`.
5. Calculate the mana points gain as `1 + number of bits set in i`.
6. Iterate through each of the monsters (0 to n-1), if the monster is not already defeated as indicated by the bitmask (`!(i & (1 << j))`), and if the mana is greater than the power of the monster (`gain > sorted_power[j]`), we find the minimum of the current `dp` value at `i | (1 << j)` and `dp[i] + 1`, and store the result back in `dp[i | (1 << j)]`.
7. After iterating through all possible subsets, return the value of `dp[(1 << n) - 1]`, which is the minimum number of days needed to defeat all the monsters.

## A solution in C++

```cpp
int min_days(const std::vector<int>& power) {
    int n = power.size();
    int ans = 1e9;
    std::vector<int> dp(1 << n, 1e9);

    dp[0] = 0;
    std::vector<int> sorted_power(power.begin(), power.end());
    sort(sorted_power.begin(), sorted_power.end());

    for (int i = 0; i < (1 << n); ++i) {
        int power_sum = 0;
        for (int j = 0; j < n; ++j) {
            if (i & (1 << j)) {
                power_sum += sorted_power[j];
            }
        }
        int gain = 1 + __builtin_popcount(i);
        for (int j = 0; j < n; ++j) {
            if (!(i & (1 << j)) && gain > sorted_power[j]) {
                dp[i | (1 << j)] = std::min(dp[i | (1 << j)], dp[i] + 1);
            }
        }
    }
    return dp[(1 << n) - 1];
}
```
1. Sort the given `power` array in ascending order.
2. We will use dynamic programming. Create a `dp` array sized `2^n` and initialized with a large number (eg., `1e9`), where `n` is the length of the `power` array. `dp[i]` represents the minimum number of days needed to defeat the monsters represented by the bitmask `i`.
3. Set `dp[0] = 0`, because no days are needed if there are no monsters.
4. Loop through all possible subsets of the sorted `power` array by iterating through `1 << n`.
5. Calculate the mana points gain as `1 + number of bits set in i`.
6. Iterate through each of the monsters (0 to n-1), if the monster is not already defeated as indicated by the bitmask (`!(i & (1 << j))`), and if the mana is greater than the power of the monster (`gain > sorted_power[j]`), we find the minimum of the current `dp` value at `i | (1 << j)` and `dp[i] + 1`, and store the result back in `dp[i | (1 << j)]`.
7. After iterating through all possible subsets, return the value of `dp[(1 << n) - 1]`, which is the minimum number of days needed to defeat all the monsters.

## A solution in Python

```python
def min_days(power):
    n = len(power)
    ans = int(1e9)
    dp = [int(1e9)] * (1 << n)
    dp[0] = 0

    sorted_power = sorted(power)

    for i in range(1 << n):
        power_sum = sum(sorted_power[j] for j in range(n) if i & (1 << j))
        gain = 1 + bin(i).count('1')

        for j in range(n):
            if not i & (1 << j) and gain > sorted_power[j]:
                dp[i | (1 << j)] = min(dp[i | (1 << j)], dp[i] + 1)

    return dp[(1 << n) - 1]
```
1. Sort the given `power` array in ascending order.
2. We will use dynamic programming. Create a `dp` array sized `2^n` and initialized with a large number (eg., `1e9`), where `n` is the length of the `power` array. `dp[i]` represents the minimum number of days needed to defeat the monsters represented by the bitmask `i`.
3. Set `dp[0] = 0`, because no days are needed if there are no monsters.
4. Loop through all possible subsets of the sorted `power` array by iterating through `1 << n`.
5. Calculate the mana points gain as `1 + number of bits set in i`.
6. Iterate through each of the monsters (0 to n-1), if the monster is not already defeated as indicated by the bitmask (`!(i & (1 << j))`), and if the mana is greater than the power of the monster (`gain > sorted_power[j]`), we find the minimum of the current `dp` value at `i | (1 << j)` and `dp[i] + 1`, and store the result back in `dp[i | (1 << j)]`.
7. After iterating through all possible subsets, return the value of `dp[(1 << n) - 1]`, which is the minimum number of days needed to defeat all the monsters.

## A solution in Javascript

```javascript
function minDays(power) {
    const n = power.length;
    const ans = 1e9;
    const dp = new Array(1 << n).fill(1e9);

    dp[0] = 0;
    const sortedPower = [...power].sort((a, b) => a - b);

    for (let i = 0; i < (1 << n); ++i) {
        let powerSum = 0;
        for (let j = 0; j < n; ++j) {
            if (i & (1 << j)) {
                powerSum += sortedPower[j];
            }
        }
        const gain = 1 + countBits(i);
        for (let j = 0; j < n; ++j) {
            if (!(i & (1 << j)) && gain > sortedPower[j]) {
                dp[i | (1 << j)] = Math.min(dp[i | (1 << j)], dp[i] + 1);
            }
        }
    }
    return dp[(1 << n) - 1];

    function countBits(num) {
        let count = 0;
        while (num) {
            num &= (num - 1);
            ++count;
        }
        return count;
    }
}
```
1. Sort the given `power` array in ascending order.
2. We will use dynamic programming. Create a `dp` array sized `2^n` and initialized with a large number (eg., `1e9`), where `n` is the length of the `power` array. `dp[i]` represents the minimum number of days needed to defeat the monsters represented by the bitmask `i`.
3. Set `dp[0] = 0`, because no days are needed if there are no monsters.
4. Loop through all possible subsets of the sorted `power` array by iterating through `1 << n`.
5. Calculate the mana points gain as `1 + number of bits set in i`.
6. Iterate through each of the monsters (0 to n-1), if the monster is not already defeated as indicated by the bitmask (`!(i & (1 << j))`), and if the mana is greater than the power of the monster (`gain > sorted_power[j]`), we find the minimum of the current `dp` value at `i | (1 << j)` and `dp[i] + 1`, and store the result back in `dp[i | (1 << j)]`.
7. After iterating through all possible subsets, return the value of `dp[(1 << n) - 1]`, which is the minimum number of days needed to defeat all the monsters.


# Most Frequent Even Element

- slug: most-frequent-even-element
- difficulty: Easy

Given an integer array `nums`, return _the most frequent even element_.

If there is a tie, return the **smallest** one. If there is no such element, return `-1`.

**Example 1:**

**Input:** nums = \[0,1,2,2,4,4,1\]
**Output:** 2
**Explanation:**
The even elements are 0, 2, and 4. Of these, 2 and 4 appear the most.
We return the smallest one, which is 2.

**Example 2:**

**Input:** nums = \[4,4,4,9,2,4\]
**Output:** 4
**Explanation:** 4 is the even element appears the most.

**Example 3:**

**Input:** nums = \[29,47,21,41,13,37,25,7\]
**Output:** -1
**Explanation:** There is no even element.

**Constraints:**

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

## A solution in Java

```java
public int mostFrequentEven(int[] nums) {
    Map<Integer, Integer> count = new HashMap<>();
    for (int num : nums) {
        if (num % 2 == 0) {
            count.put(num, count.getOrDefault(num, 0) + 1);
        }
    }
    int maxCount = Integer.MIN_VALUE;
    int mostFrequent = -1;
    for (Map.Entry<Integer, Integer> entry : count.entrySet()) {
        int num = entry.getKey();
        int freq = entry.getValue();
        if (freq > maxCount || (freq == maxCount && num < mostFrequent)) {
            maxCount = freq;
            mostFrequent = num;
        }
    }
    return mostFrequent;
}
```
The algorithm uses a hash map to count the frequency of even numbers in the given array. The hash map is iterated and the even number with the highest frequency is stored as the most frequent. If there is a tie, the smaller number is chosen as the most frequent. If no even number is found, the algorithm returns -1.

## A solution in C++

```cpp
int mostFrequentEven(vector<int>& nums) {
    unordered_map<int, int> count;
    for (int num : nums) {
        if (num % 2 == 0) {
            count[num]++;
        }
    }
    int max_count = INT_MIN;
    int most_frequent = -1;
    for (auto& [num, freq] : count) {
        if (freq > max_count || (freq == max_count && num < most_frequent)) {
            max_count = freq;
            most_frequent = num;
        }
    }
    return most_frequent;
}
```
The algorithm uses a hash map to count the frequency of even numbers in the given array. The hash map is iterated and the even number with the highest frequency is stored as the most frequent. If there is a tie, the smaller number is chosen as the most frequent. If no even number is found, the algorithm returns -1.

## A solution in Python

```python
def most_frequent_even(nums):
    count = {}
    for num in nums:
        if num % 2 == 0:
            count[num] = count.get(num, 0) + 1
    max_count = float('-inf')
    most_frequent = -1
    for num, freq in count.items():
        if freq > max_count or (freq == max_count and num < most_frequent):
            max_count = freq
            most_frequent = num
    return most_frequent
```
The algorithm uses a hash map to count the frequency of even numbers in the given array. The hash map is iterated and the even number with the highest frequency is stored as the most frequent. If there is a tie, the smaller number is chosen as the most frequent. If no even number is found, the algorithm returns -1.

## A solution in Javascript

```javascript
function mostFrequentEven(nums) {
    let count = {};
    for (let num of nums) {
        if (num % 2 === 0) {
            count[num] = (count[num] || 0) + 1;
        }
    }
    let maxCount = Number.MIN_SAFE_INTEGER;
    let mostFrequent = -1;
    for (let num in count) {
        let freq = count[num];
        if (freq > maxCount || (freq === maxCount && parseInt(num) < mostFrequent)) {
            maxCount = freq;
            mostFrequent = parseInt(num);
        }
    }
    return mostFrequent;
}
```
The algorithm uses a hash map to count the frequency of even numbers in the given array. The hash map is iterated and the even number with the highest frequency is stored as the most frequent. If there is a tie, the smaller number is chosen as the most frequent. If no even number is found, the algorithm returns -1.


# Optimal Partition of String

- slug: optimal-partition-of-string
- difficulty: Medium

Given a string `s`, partition the string into one or more **substrings** such that the characters in each substring are **unique**. That is, no letter appears in a single substring more than **once**.

Return _the **minimum** number of substrings in such a partition._

Note that each character should belong to exactly one substring in a partition.

**Example 1:**

**Input:** s =  "abacaba "
**Output:** 4
**Explanation:**
Two possible partitions are ( "a ", "ba ", "cab ", "a ") and ( "ab ", "a ", "ca ", "ba ").
It can be shown that 4 is the minimum number of substrings needed.

**Example 2:**

**Input:** s =  "ssssss "
**Output:** 6
**Explanation:**
The only valid partition is ( "s ", "s ", "s ", "s ", "s ", "s ").

**Constraints:**

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

## A solution in Java

```java
import java.util.HashSet;

public int min_substrs(String s) {
    HashSet<Character> seen = new HashSet<>();
    int count = 0;
    for (char c : s.toCharArray()) {
        if (seen.contains(c)) {
            count++;
            seen.clear();
        }
        seen.add(c);
    }
    return count + (seen.isEmpty() ? 0 : 1);
}
```
The algorithm iterates through the characters of the input string `s`. It uses a set `seen` to store the unique characters encountered so far in the current substring. When a character is found that already exists in the set, we increment the `count` and clear the set. This indicates that a new unique substring should start.

At the end, if there are still characters left in the `seen` set, it means there is one last unique substring, so we add 1 to the count.

The time complexity of this algorithm is O(N) where N is the length of the input string, since we iterate through the input string once, and set operations (add, clear, etc.) take constant time on average.

## A solution in C++

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

int min_substrs(string s) {
    unordered_set<char> seen;
    int count = 0;
    for (char c : s) {
        if (seen.find(c) != seen.end()) {
            count++;
            seen.clear();
        }
        seen.insert(c);
    }
    return count + !seen.empty();
}
```
The algorithm iterates through the characters of the input string `s`. It uses a set `seen` to store the unique characters encountered so far in the current substring. When a character is found that already exists in the set, we increment the `count` and clear the set. This indicates that a new unique substring should start.

At the end, if there are still characters left in the `seen` set, it means there is one last unique substring, so we add 1 to the count.

The time complexity of this algorithm is O(N) where N is the length of the input string, since we iterate through the input string once, and set operations (add, clear, etc.) take constant time on average.

## A solution in Python

```python
def min_substrs(s: str) -> int:
    seen = set()
    count = 0
    for c in s:
        if c in seen:
            count += 1
            seen.clear()
        seen.add(c)
    return count + int(bool(seen))
```
The algorithm iterates through the characters of the input string `s`. It uses a set `seen` to store the unique characters encountered so far in the current substring. When a character is found that already exists in the set, we increment the `count` and clear the set. This indicates that a new unique substring should start.

At the end, if there are still characters left in the `seen` set, it means there is one last unique substring, so we add 1 to the count.

The time complexity of this algorithm is O(N) where N is the length of the input string, since we iterate through the input string once, and set operations (add, clear, etc.) take constant time on average.

## A solution in Javascript

```javascript
function min_substrs(s) {
    const seen = new Set();
    let count = 0;
    for (const c of s) {
        if (seen.has(c)) {
            count++;
            seen.clear();
        }
        seen.add(c);
    }
    return count + (seen.size > 0 ? 1 : 0);
}
```
The algorithm iterates through the characters of the input string `s`. It uses a set `seen` to store the unique characters encountered so far in the current substring. When a character is found that already exists in the set, we increment the `count` and clear the set. This indicates that a new unique substring should start.

At the end, if there are still characters left in the `seen` set, it means there is one last unique substring, so we add 1 to the count.

The time complexity of this algorithm is O(N) where N is the length of the input string, since we iterate through the input string once, and set operations (add, clear, etc.) take constant time on average.


# Divide Intervals Into Minimum Number of Groups

- slug: divide-intervals-into-minimum-number-of-groups
- difficulty: Medium

You are given a 2D integer array `intervals` where `intervals[i] = [lefti, righti]` represents the **inclusive** interval `[lefti, righti]`.

You have to divide the intervals into one or more **groups** such that each interval is in **exactly** one group, and no two intervals that are in the same group **intersect** each other.

Return _the **minimum** number of groups you need to make_.

Two intervals **intersect** if there is at least one common number between them. For example, the intervals `[1, 5]` and `[5, 8]` intersect.

**Example 1:**

**Input:** intervals = \[\[5,10\],\[6,8\],\[1,5\],\[2,3\],\[1,10\]\]
**Output:** 3
**Explanation:** We can divide the intervals into the following groups:
- Group 1: \[1, 5\], \[6, 8\].
- Group 2: \[2, 3\], \[5, 10\].
- Group 3: \[1, 10\].
It can be proven that it is not possible to divide the intervals into fewer than 3 groups.

**Example 2:**

**Input:** intervals = \[\[1,3\],\[5,6\],\[8,10\],\[11,13\]\]
**Output:** 1
**Explanation:** None of the intervals overlap, so we can put all of them in one group.

**Constraints:**

*   `1 <= intervals.length <= 105`
*   `intervals[i].length == 2`
*   `1 <= lefti <= righti <= 106`

## A solution in Java

```java
import java.util.Arrays;
import java.util.PriorityQueue;

public int minGroups(int[][] intervals) {
    Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
    PriorityQueue<Integer> pq = new PriorityQueue<>();
    for (int[] interval : intervals) {
        if (!pq.isEmpty() && pq.peek() < interval[0]) {
            pq.poll();
        }
        pq.offer(interval[1]);
    }
    return pq.size();
}
```
1. Sort the input intervals based on start time (`left`) in ascending order.
2. Create a priority queue (or similar data structure suitable for the language) sorted by end time (`right`).
3. Iterate over the intervals, if the start time of the new interval is greater than or equal to the smallest end time in the priority queue, it means the intervals do not intersect, so remove the smallest end time from the queue.
4. Add the end time of the new interval to the priority queue.
5. When all intervals have been processed, the size of the priority queue represents the minimum number of groups required.

## A solution in C++

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

int minGroups(vector<vector<int>>& intervals) {
    sort(intervals.begin(), intervals.end());
    priority_queue<int, vector<int>, greater<int>> pq;
    for (auto& interval : intervals) {
        if (!pq.empty() && pq.top() < interval[0]) {
            pq.pop();
        }
        pq.push(interval[1]);
    }
    return pq.size();
}
```
1. Sort the input intervals based on start time (`left`) in ascending order.
2. Create a priority queue (or similar data structure suitable for the language) sorted by end time (`right`).
3. Iterate over the intervals, if the start time of the new interval is greater than or equal to the smallest end time in the priority queue, it means the intervals do not intersect, so remove the smallest end time from the queue.
4. Add the end time of the new interval to the priority queue.
5. When all intervals have been processed, the size of the priority queue represents the minimum number of groups required.

## A solution in Python

```python
import heapq

def min_groups(intervals):
    intervals.sort()
    pq = []
    for interval in intervals:
        if pq and pq[0] < interval[0]:
            heapq.heappop(pq)
        heapq.heappush(pq, interval[1])
    return len(pq)
```
1. Sort the input intervals based on start time (`left`) in ascending order.
2. Create a priority queue (or similar data structure suitable for the language) sorted by end time (`right`).
3. Iterate over the intervals, if the start time of the new interval is greater than or equal to the smallest end time in the priority queue, it means the intervals do not intersect, so remove the smallest end time from the queue.
4. Add the end time of the new interval to the priority queue.
5. When all intervals have been processed, the size of the priority queue represents the minimum number of groups required.

## A solution in Javascript

```javascript
function minGroups(intervals) {
    intervals.sort((a, b) => a[0] - b[0]);
    const pq = [];
    for (let interval of intervals) {
        if (pq.length > 0 && pq[0] < interval[0]) {
            pq.shift();
        }
        pq.push(interval[1]);
        pq.sort((a, b) => a - b);
    }
    return pq.length;
}
```
1. Sort the input intervals based on start time (`left`) in ascending order.
2. Create a priority queue (or similar data structure suitable for the language) sorted by end time (`right`).
3. Iterate over the intervals, if the start time of the new interval is greater than or equal to the smallest end time in the priority queue, it means the intervals do not intersect, so remove the smallest end time from the queue.
4. Add the end time of the new interval to the priority queue.
5. When all intervals have been processed, the size of the priority queue represents the minimum number of groups required.


# Longest Increasing Subsequence II

- slug: longest-increasing-subsequence-ii
- difficulty: Hard

You are given an integer array `nums` and an integer `k`.

Find the longest subsequence of `nums` that meets the following requirements:

*   The subsequence is **strictly increasing** and
*   The difference between adjacent elements in the subsequence is **at most** `k`.

Return _the length of the **longest** **subsequence** that meets the requirements._

A **subsequence** is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.

**Example 1:**

**Input:** nums = \[4,2,1,4,3,4,5,8,15\], k = 3
**Output:** 5
**Explanation:**
The longest subsequence that meets the requirements is \[1,3,4,5,8\].
The subsequence has a length of 5, so we return 5.
Note that the subsequence \[1,3,4,5,8,15\] does not meet the requirements because 15 - 8 = 7 is larger than 3.

**Example 2:**

**Input:** nums = \[7,4,5,1,8,12,4,7\], k = 5
**Output:** 4
**Explanation:**
The longest subsequence that meets the requirements is \[4,5,8,12\].
The subsequence has a length of 4, so we return 4.

**Example 3:**

**Input:** nums = \[1,5\], k = 1
**Output:** 1
**Explanation:**
The longest subsequence that meets the requirements is \[1\].
The subsequence has a length of 1, so we return 1.

**Constraints:**

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

## A solution in Java

```java
public int longestSubsequence(int[] nums, int k) {
    int n = nums.length;
    TreeMap<Integer, Integer> dp = new TreeMap<>();
    int ans = 0;

    for (int num : nums) {
        int temp = 0;
        Integer key = dp.lowerKey(num - k);
        if (key != null) {
            temp = dp.get(key);
        }
        dp.put(num, Math.max(dp.getOrDefault(num, 0), temp + 1));
        ans = Math.max(ans, dp.get(num));
    }

    return ans;
}
```
The main idea for finding the longest strictly increasing subsequence is using dynamic programming (DP). In each iteration, we iterate over the elements of the `nums` array with the given constraint that the difference between adjacent elements in the subsequence should be no more than `k`.

We use a dictionary or map to store the maximum length of subsequence that can be formed ending with each element. While iterating, we search for the largest element in the DP smaller than `num - k`. This is done using the `upper_bound` or `lowerKey` methods depending on the language.

If a valid larger element in the DP can be found, we take the length of the subsequence ending with that larger element and increment it by one (`temp = it->second` or `temp = dp.get(key)`). Then, we update the length of the subsequence ending with `num` with the maximum between the current length and `temp + 1`.

In the end, we simply return the maximum length of subsequence found.

Time complexity: O(n * log n) due to the usage of a balanced search tree (map or TreeMap)
Space complexity: O(n) for the DP map/dictionary.

## A solution in C++

```cpp
int longestSubsequence(vector<int>& nums, int k) {
    int n = nums.size();
    map<int, int> dp;
    int ans = 0;

    for (int num : nums) {
        int temp = 0;
        auto it = dp.upper_bound(num - k - 1);
        if (it != dp.begin()) {
            --it;
            temp = it->second;
        }
        dp[num] = max(dp[num], temp + 1);
        ans = max(ans, dp[num]);
    }

    return ans;
}
```
The main idea for finding the longest strictly increasing subsequence is using dynamic programming (DP). In each iteration, we iterate over the elements of the `nums` array with the given constraint that the difference between adjacent elements in the subsequence should be no more than `k`.

We use a dictionary or map to store the maximum length of subsequence that can be formed ending with each element. While iterating, we search for the largest element in the DP smaller than `num - k`. This is done using the `upper_bound` or `lowerKey` methods depending on the language.

If a valid larger element in the DP can be found, we take the length of the subsequence ending with that larger element and increment it by one (`temp = it->second` or `temp = dp.get(key)`). Then, we update the length of the subsequence ending with `num` with the maximum between the current length and `temp + 1`.

In the end, we simply return the maximum length of subsequence found.

Time complexity: O(n * log n) due to the usage of a balanced search tree (map or TreeMap)
Space complexity: O(n) for the DP map/dictionary.

## A solution in Python

```python
def longestSubsequence(nums, k):
    n = len(nums)
    dp = {}
    ans = 0

    for num in nums:
        temp = 0
        keys = [key for key in dp if num - k <= key]
        if keys:
            temp = dp[max(keys)]

        dp[num] = max(dp.get(num, 0), temp + 1)
        ans = max(ans, dp[num])

    return ans
```
The main idea for finding the longest strictly increasing subsequence is using dynamic programming (DP). In each iteration, we iterate over the elements of the `nums` array with the given constraint that the difference between adjacent elements in the subsequence should be no more than `k`.

We use a dictionary or map to store the maximum length of subsequence that can be formed ending with each element. While iterating, we search for the largest element in the DP smaller than `num - k`. This is done using the `upper_bound` or `lowerKey` methods depending on the language.

If a valid larger element in the DP can be found, we take the length of the subsequence ending with that larger element and increment it by one (`temp = it->second` or `temp = dp.get(key)`). Then, we update the length of the subsequence ending with `num` with the maximum between the current length and `temp + 1`.

In the end, we simply return the maximum length of subsequence found.

Time complexity: O(n * log n) due to the usage of a balanced search tree (map or TreeMap)
Space complexity: O(n) for the DP map/dictionary.

## A solution in Javascript

```javascript
function longestSubsequence(nums, k) {
    const n = nums.length;
    const dp = new Map();
    let ans = 0;

    for (const num of nums) {
        let temp = 0;
        const key = [...dp.keys()].reverse().find(key => key <= num - k);
        if (key !== undefined) {
            temp = dp.get(key);
        }
        dp.set(num, Math.max(dp.get(num) || 0, temp + 1));
        ans = Math.max(ans, dp.get(num));
    }

    return ans;
}
```
The main idea for finding the longest strictly increasing subsequence is using dynamic programming (DP). In each iteration, we iterate over the elements of the `nums` array with the given constraint that the difference between adjacent elements in the subsequence should be no more than `k`.

We use a dictionary or map to store the maximum length of subsequence that can be formed ending with each element. While iterating, we search for the largest element in the DP smaller than `num - k`. This is done using the `upper_bound` or `lowerKey` methods depending on the language.

If a valid larger element in the DP can be found, we take the length of the subsequence ending with that larger element and increment it by one (`temp = it->second` or `temp = dp.get(key)`). Then, we update the length of the subsequence ending with `num` with the maximum between the current length and `temp + 1`.

In the end, we simply return the maximum length of subsequence found.

Time complexity: O(n * log n) due to the usage of a balanced search tree (map or TreeMap)
Space complexity: O(n) for the DP map/dictionary.


# Design SQL

- slug: design-sql
- difficulty: Medium

You are given `n` tables represented with two arrays `names` and `columns`, where `names[i]` is the name of the `ith` table and `columns[i]` is the number of columns of the `ith` table.

You should be able to perform the following **operations**:

*   **Insert** a row in a specific table. Each row you insert has an id. The id is assigned using an auto-increment method where the id of the first inserted row is 1, and the id of each other row inserted into the same table is the id of the last inserted row (even if it was deleted) plus one.
*   **Delete** a row from a specific table. **Note** that deleting a row does not affect the id of the next inserted row.
*   **Select** a specific cell from any table and return its value.

Implement the `SQL` class:

*   `SQL(String[] names, int[] columns)` Creates the `n` tables.
*   `void insertRow(String name, String[] row)` Adds a row to the table `name`. It is **guaranteed** that the table will exist, and the size of the array `row` is equal to the number of columns in the table.
*   `void deleteRow(String name, int rowId)` Removes the row `rowId` from the table `name`. It is **guaranteed** that the table and row will **exist**.
*   `String selectCell(String name, int rowId, int columnId)` Returns the value of the cell in the row `rowId` and the column `columnId` from the table `name`.

**Example 1:**

**Input**
\[ "SQL ",  "insertRow ",  "selectCell ",  "insertRow ",  "deleteRow ",  "selectCell "\]
\[\[\[ "one ",  "two ",  "three "\], \[2, 3, 1\]\], \[ "two ", \[ "first ",  "second ",  "third "\]\], \[ "two ", 1, 3\], \[ "two ", \[ "fourth ",  "fifth ",  "sixth "\]\], \[ "two ", 1\], \[ "two ", 2, 2\]\]
**Output**
\[null, null,  "third ", null, null,  "fifth "\]

**Explanation**
SQL sql = new SQL(\[ "one ",  "two ",  "three "\], \[2, 3, 1\]); // creates three tables.
sql.insertRow( "two ", \[ "first ",  "second ",  "third "\]); // adds a row to the table  "two ". Its id is 1.
sql.selectCell( "two ", 1, 3); // return  "third ", finds the value of the third column in the row with id 1 of the table  "two ".
sql.insertRow( "two ", \[ "fourth ",  "fifth ",  "sixth "\]); // adds another row to the table  "two ". Its id is 2.
sql.deleteRow( "two ", 1); // deletes the first row of the table  "two ". Note that the second row will still have the id 2.
sql.selectCell( "two ", 2, 2); // return  "fifth ", finds the value of the second column in the row with id 2 of the table  "two ".

**Constraints:**

*   `n == names.length == columns.length`
*   `1 <= n <= 104`
*   `1 <= names[i].length, row[i].length, name.length <= 20`
*   `names[i]`, `row[i]`, and `name` consist of lowercase English letters.
*   `1 <= columns[i] <= 100`
*   All the strings of `names` are **distinct**.
*   `name` exists in the array `names`.
*   `row.length` equals the number of columns in the chosen table.
*   `rowId` and `columnId` will be valid.
*   At most `250` calls will be made to `insertRow` and `deleteRow`.
*   At most `104` calls will be made to `selectCell`.

## A solution in Java

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

public class SQL {
    private Map<String, Table> tables;

    public SQL(String[] names, int[] columns) {
        tables = new HashMap<>();
        for (int i = 0; i < names.length; i++) {
            tables.put(names[i], new Table(columns[i]));
        }
    }

    public void insertRow(String name, String[] row) {
        tables.get(name).insertRow(row);
    }

    public void deleteRow(String name, int rowId) {
        tables.get(name).deleteRow(rowId);
    }

    public String selectCell(String name, int rowId, int columnId) {
        return tables.get(name).selectCell(rowId, columnId);
    }

    private static class Table {
        private int nextId;
        private List<Row> rows;
        private int numColumns;

        public Table(int numColumns) {
            this.numColumns = numColumns;
            this.nextId = 1;
            this.rows = new ArrayList<>();
        }

        public void insertRow(String[] row) {
            rows.add(new Row(nextId++, row));
        }

        public void deleteRow(int rowId) {
            rows.removeIf(r -> r.id == rowId);
        }

        public String selectCell(int rowId, int columnId) {
            return rows.stream().filter(r -> r.id == rowId).findFirst().get().values[columnId - 1];
        }
    }

    private static class Row {
        private int id;
        private String[] values;

        public Row(int id, String[] values) {
            this.id = id;
            this.values = values;
        }
    }
}
```
The SQL class is designed to hold tables' information, and the main logic comes from Table class internally. To perform insertRow and deleteRow operations, we maintain a unique id for each row based on the nextId variable. For insertRow, we append a new row with its unique id and its cell contents. For deleteRow, we remove the rows based on their unique id.

selectCell function iterates through rows and selects the needed cell based on rowId and columnId.

## A solution in C++

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

class SQL {
public:
    SQL(vector<string>& names, vector<int>& columns) {
        for (size_t i = 0; i < names.size(); ++i) {
            tables[names[i]] = {columns[i], {}};
        }
    }

    void insertRow(string name, vector<string>& row) {
        tables[name].second.push_back({++tables[name].first, row});
    }

    void deleteRow(string name, int rowId) {
        auto& rows = tables[name].second;
        rows.erase(remove_if(rows.begin(), rows.end(),
                             [rowId](auto&& p) { return p.first == rowId; }),
                   rows.end());
    }

    string selectCell(string name, int rowId, int columnId) {
        auto& rows = tables[name].second;
        auto it = find_if(rows.begin(), rows.end(), [rowId](auto&& p) { return p.first == rowId; });
        return it->second[columnId - 1];
    }

private:
    unordered_map<string, pair<int, vector<pair<int, vector<string>>>> tables;
};
```
The SQL class is designed to hold tables' information, and the main logic comes from Table class internally. To perform insertRow and deleteRow operations, we maintain a unique id for each row based on the nextId variable. For insertRow, we append a new row with its unique id and its cell contents. For deleteRow, we remove the rows based on their unique id.

selectCell function iterates through rows and selects the needed cell based on rowId and columnId.

## A solution in Python

```python
class SQL:
    def __init__(self, names: List[str], columns: List[int]):
        self.tables = {name: Table(columns[i]) for i, name in enumerate(names)}

    def insertRow(self, name: str, row: List[str]) -> None:
        self.tables[name].insertRow(row)

    def deleteRow(self, name: str, rowId: int) -> None:
        self.tables[name].deleteRow(rowId)

    def selectCell(self, name: str, rowId: int, columnId: int) -> str:
        return self.tables[name].selectCell(rowId, columnId)

class Table:
    def __init__(self, columns: int):
        self.next_id = 1
        self.rows = []
        self.num_columns = columns

    def insertRow(self, row: List[str]) -> None:
        self.rows.append([self.next_id, row])
        self.next_id += 1

    def deleteRow(self, rowId: int) -> None:
        self.rows = [row for row in self.rows if row[0] != rowId]

    def selectCell(self, rowId: int, columnId: int) -> str:
        for row in self.rows:
            if row[0] == rowId:
                return row[1][columnId - 1]
```
The SQL class is designed to hold tables' information, and the main logic comes from Table class internally. To perform insertRow and deleteRow operations, we maintain a unique id for each row based on the nextId variable. For insertRow, we append a new row with its unique id and its cell contents. For deleteRow, we remove the rows based on their unique id.

selectCell function iterates through rows and selects the needed cell based on rowId and columnId.

## A solution in Javascript

```javascript
class SQL {
    constructor(names, columns) {
        this.tables = {};
        for (let i = 0; i < names.length; i++) {
            this.tables[names[i]] = new Table(columns[i]);
        }
    }

    insertRow(name, row) {
        this.tables[name].insertRow(row);
    }

    deleteRow(name, rowId) {
        this.tables[name].deleteRow(rowId);
    }

    selectCell(name, rowId, columnId) {
        return this.tables[name].selectCell(rowId, columnId);
    }
}

class Table {
    constructor(columns) {
        this.columns = columns;
        this.rows = [];
        this.nextId = 1;
    }

    insertRow(row) {
        this.rows.push({ id: this.nextId++, values: row });
    }

    deleteRow(rowId) {
        this.rows = this.rows.filter(row => row.id !== rowId);
    }

    selectCell(rowId, columnId) {
        const row = this.rows.find(row => row.id === rowId);
        return row.values[columnId - 1];
    }
}
```
The SQL class is designed to hold tables' information, and the main logic comes from Table class internally. To perform insertRow and deleteRow operations, we maintain a unique id for each row based on the nextId variable. For insertRow, we append a new row with its unique id and its cell contents. For deleteRow, we remove the rows based on their unique id.

selectCell function iterates through rows and selects the needed cell based on rowId and columnId.


# Count Days Spent Together

- slug: count-days-spent-together
- difficulty: Easy

Alice and Bob are traveling to Rome for separate business meetings.

You are given 4 strings `arriveAlice`, `leaveAlice`, `arriveBob`, and `leaveBob`. Alice will be in the city from the dates `arriveAlice` to `leaveAlice` (**inclusive**), while Bob will be in the city from the dates `arriveBob` to `leaveBob` (**inclusive**). Each will be a 5-character string in the format `"MM-DD "`, corresponding to the month and day of the date.

Return _the total number of days that Alice and Bob are in Rome together._

You can assume that all dates occur in the **same** calendar year, which is **not** a leap year. Note that the number of days per month can be represented as: `[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]`.

**Example 1:**

**Input:** arriveAlice =  "08-15 ", leaveAlice =  "08-18 ", arriveBob =  "08-16 ", leaveBob =  "08-19 "
**Output:** 3
**Explanation:** Alice will be in Rome from August 15 to August 18. Bob will be in Rome from August 16 to August 19. They are both in Rome together on August 16th, 17th, and 18th, so the answer is 3.

**Example 2:**

**Input:** arriveAlice =  "10-01 ", leaveAlice =  "10-31 ", arriveBob =  "11-01 ", leaveBob =  "12-31 "
**Output:** 0
**Explanation:** There is no day when Alice and Bob are in Rome together, so we return 0.

**Constraints:**

*   All dates are provided in the format `"MM-DD "`.
*   Alice and Bob's arrival dates are **earlier than or equal to** their leaving dates.
*   The given dates are valid dates of a **non-leap** year.

## A solution in Java

```java
public int daysTogether(String arriveAlice, String leaveAlice, String arriveBob, String leaveBob) {
    int[] daysInMonth = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int arriveDaysAlice = dateToDays(arriveAlice, daysInMonth);
    int leaveDaysAlice = dateToDays(leaveAlice, daysInMonth);
    int arriveDaysBob = dateToDays(arriveBob, daysInMonth);
    int leaveDaysBob = dateToDays(leaveBob, daysInMonth);

    int commonStartDate = Math.max(arriveDaysAlice, arriveDaysBob);
    int commonEndDate = Math.min(leaveDaysAlice, leaveDaysBob);

    return Math.max(0, commonEndDate - commonStartDate + 1);
}

private int dateToDays(String date, int[] daysInMonth) {
    int month = Integer.parseInt(date.substring(0, 2));
    int day = Integer.parseInt(date.substring(3, 5));
    int days = day;

    for (int i = 1; i < month; i++) {
        days += daysInMonth[i];
    }

    return days;
}
```
1. Store the days in each month of a non-leap year in an array `daysInMonth`.
2. Define a function `dateToDays` that takes a date string and the `daysInMonth` array, then converts the date string to the total number of days from the beginning of the year. Calculate this by summing up days from prior months plus the day of the month.
3. Compute the total number of days for `arriveAlice`, `leaveAlice`, `arriveBob`, and `leaveBob` by calling `dateToDays`.
4. Calculate the common starting date by taking the max of `arriveDaysAlice` and `arriveDaysBob`.
5. Calculate the common end date by taking the min of `leaveDaysAlice` and `leaveDaysBob`.
6. Calculate and return the total number of days Alice and Bob are in Rome together by finding the difference between the common end and start dates, adding 1, and taking the max between that result and 0.

## A solution in C++

```cpp
#include <string>
#include <algorithm>

int daysTogether(const std::string& arriveAlice, const std::string& leaveAlice, const std::string& arriveBob, const std::string& leaveBob) {
    int daysInMonth[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    auto dateToDays = [&](const std::string& date) {
        int month = stoi(date.substr(0, 2));
        int day = stoi(date.substr(3, 2));
        int days = day;
        for (int i = 1; i < month; ++i) {
            days += daysInMonth[i];
        }
        return days;
    };

    int arriveDaysAlice = dateToDays(arriveAlice);
    int leaveDaysAlice = dateToDays(leaveAlice);
    int arriveDaysBob = dateToDays(arriveBob);
    int leaveDaysBob = dateToDays(leaveBob);

    int commonStartDate = std::max(arriveDaysAlice, arriveDaysBob);
    int commonEndDate = std::min(leaveDaysAlice, leaveDaysBob);

    return std::max(0, commonEndDate - commonStartDate + 1);
}
```
1. Store the days in each month of a non-leap year in an array `daysInMonth`.
2. Define a function `dateToDays` that takes a date string and the `daysInMonth` array, then converts the date string to the total number of days from the beginning of the year. Calculate this by summing up days from prior months plus the day of the month.
3. Compute the total number of days for `arriveAlice`, `leaveAlice`, `arriveBob`, and `leaveBob` by calling `dateToDays`.
4. Calculate the common starting date by taking the max of `arriveDaysAlice` and `arriveDaysBob`.
5. Calculate the common end date by taking the min of `leaveDaysAlice` and `leaveDaysBob`.
6. Calculate and return the total number of days Alice and Bob are in Rome together by finding the difference between the common end and start dates, adding 1, and taking the max between that result and 0.

## A solution in Python

```python
def days_together(arrive_alice, leave_alice, arrive_bob, leave_bob):
    days_in_month = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

    def date_to_days(date):
        month, day = map(int, date.split('-'))
        return sum(days_in_month[:month]) + day

    arrive_days_alice = date_to_days(arrive_alice)
    leave_days_alice = date_to_days(leave_alice)
    arrive_days_bob = date_to_days(arrive_bob)
    leave_days_bob = date_to_days(leave_bob)

    common_start_date = max(arrive_days_alice, arrive_days_bob)
    common_end_date = min(leave_days_alice, leave_days_bob)

    return max(0, common_end_date - common_start_date + 1)
```
1. Store the days in each month of a non-leap year in an array `daysInMonth`.
2. Define a function `dateToDays` that takes a date string and the `daysInMonth` array, then converts the date string to the total number of days from the beginning of the year. Calculate this by summing up days from prior months plus the day of the month.
3. Compute the total number of days for `arriveAlice`, `leaveAlice`, `arriveBob`, and `leaveBob` by calling `dateToDays`.
4. Calculate the common starting date by taking the max of `arriveDaysAlice` and `arriveDaysBob`.
5. Calculate the common end date by taking the min of `leaveDaysAlice` and `leaveDaysBob`.
6. Calculate and return the total number of days Alice and Bob are in Rome together by finding the difference between the common end and start dates, adding 1, and taking the max between that result and 0.

## A solution in Javascript

```javascript
function daysTogether(arriveAlice, leaveAlice, arriveBob, leaveBob) {
    const daysInMonth = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

    function dateToDays(date) {
        const [month, day] = date.split('-').map(str => parseInt(str, 10));
        return daysInMonth.slice(0, month).reduce((a, b) => a + b, day);
    }

    const arriveDaysAlice = dateToDays(arriveAlice);
    const leaveDaysAlice = dateToDays(leaveAlice);
    const arriveDaysBob = dateToDays(arriveBob);
    const leaveDaysBob = dateToDays(leaveBob);

    const commonStartDate = Math.max(arriveDaysAlice, arriveDaysBob);
    const commonEndDate = Math.min(leaveDaysAlice, leaveDaysBob);

    return Math.max(0, commonEndDate - commonStartDate + 1);
}
```
1. Store the days in each month of a non-leap year in an array `daysInMonth`.
2. Define a function `dateToDays` that takes a date string and the `daysInMonth` array, then converts the date string to the total number of days from the beginning of the year. Calculate this by summing up days from prior months plus the day of the month.
3. Compute the total number of days for `arriveAlice`, `leaveAlice`, `arriveBob`, and `leaveBob` by calling `dateToDays`.
4. Calculate the common starting date by taking the max of `arriveDaysAlice` and `arriveDaysBob`.
5. Calculate the common end date by taking the min of `leaveDaysAlice` and `leaveDaysBob`.
6. Calculate and return the total number of days Alice and Bob are in Rome together by finding the difference between the common end and start dates, adding 1, and taking the max between that result and 0.


# Maximum Matching of Players With Trainers

- slug: maximum-matching-of-players-with-trainers
- difficulty: Medium

You are given a **0-indexed** integer array `players`, where `players[i]` represents the **ability** of the `ith` player. You are also given a **0-indexed** integer array `trainers`, where `trainers[j]` represents the **training capacity** of the `jth` trainer.

The `ith` player can **match** with the `jth` trainer if the player's ability is **less than or equal to** the trainer's training capacity. Additionally, the `ith` player can be matched with at most one trainer, and the `jth` trainer can be matched with at most one player.

Return _the **maximum** number of matchings between_ `players` _and_ `trainers` _that satisfy these conditions._

**Example 1:**

**Input:** players = \[4,7,9\], trainers = \[8,2,5,8\]
**Output:** 2
**Explanation:**
One of the ways we can form two matchings is as follows:
- players\[0\] can be matched with trainers\[0\] since 4 <= 8.
- players\[1\] can be matched with trainers\[3\] since 7 <= 8.
It can be proven that 2 is the maximum number of matchings that can be formed.

**Example 2:**

**Input:** players = \[1,1,1\], trainers = \[10\]
**Output:** 1
**Explanation:**
The trainer can be matched with any of the 3 players.
Each player can only be matched with one trainer, so the maximum answer is 1.

**Constraints:**

*   `1 <= players.length, trainers.length <= 105`
*   `1 <= players[i], trainers[j] <= 109`

## A solution in Java

```java
import java.util.Arrays;

public int maxMatchings(int[] players, int[] trainers) {
    Arrays.sort(players);
    Arrays.sort(trainers);

    int playerIndex = 0, trainerIndex = 0, matchCount = 0;
    while (playerIndex < players.length && trainerIndex < trainers.length) {
        if (players[playerIndex] <= trainers[trainerIndex]) {
            matchCount++;
            playerIndex++;
            trainerIndex++;
        } else {
            trainerIndex++;
        }
    }

    return matchCount;
}
```
1. Sort the `players` and `trainers` arrays in ascending order.
2. Initialize variables `playerIndex`, `trainerIndex`, and `matchCount` to 0.
3. Loop through the `players` and `trainers` arrays while `playerIndex` is less than the `players` length and `trainerIndex` is less than the `trainers` length.
   a. If the current `player`'s ability is less than or equal to the current `trainer`'s training capacity, increase the `matchCount`, increment both `playerIndex` and `trainerIndex`.
   b. If not, increment `trainerIndex` only.
4. After the loop, the final `matchCount` value is the maximum number of matchings that satisfy the conditions.

## A solution in C++

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

int maxMatchings(std::vector<int>& players, std::vector<int>& trainers) {
    std::sort(players.begin(), players.end());
    std::sort(trainers.begin(), trainers.end());

    int playerIndex = 0, trainerIndex = 0, matchCount = 0;
    while (playerIndex < players.size() && trainerIndex < trainers.size()) {
        if (players[playerIndex] <= trainers[trainerIndex]) {
            matchCount++;
            playerIndex++;
            trainerIndex++;
        } else {
            trainerIndex++;
        }
    }

    return matchCount;
}
```
1. Sort the `players` and `trainers` arrays in ascending order.
2. Initialize variables `playerIndex`, `trainerIndex`, and `matchCount` to 0.
3. Loop through the `players` and `trainers` arrays while `playerIndex` is less than the `players` length and `trainerIndex` is less than the `trainers` length.
   a. If the current `player`'s ability is less than or equal to the current `trainer`'s training capacity, increase the `matchCount`, increment both `playerIndex` and `trainerIndex`.
   b. If not, increment `trainerIndex` only.
4. After the loop, the final `matchCount` value is the maximum number of matchings that satisfy the conditions.

## A solution in Python

```python
def max_matchings(players, trainers):
    players.sort()
    trainers.sort()

    player_index, trainer_index, match_count = 0, 0, 0
    while (player_index < len(players)) and (trainer_index < len(trainers)):
        if players[player_index] <= trainers[trainer_index]:
            match_count += 1
            player_index += 1
            trainer_index += 1
        else:
            trainer_index += 1

    return match_count
```
1. Sort the `players` and `trainers` arrays in ascending order.
2. Initialize variables `playerIndex`, `trainerIndex`, and `matchCount` to 0.
3. Loop through the `players` and `trainers` arrays while `playerIndex` is less than the `players` length and `trainerIndex` is less than the `trainers` length.
   a. If the current `player`'s ability is less than or equal to the current `trainer`'s training capacity, increase the `matchCount`, increment both `playerIndex` and `trainerIndex`.
   b. If not, increment `trainerIndex` only.
4. After the loop, the final `matchCount` value is the maximum number of matchings that satisfy the conditions.

## A solution in Javascript

```javascript
function maxMatchings(players, trainers) {
    players.sort((a, b) => a - b);
    trainers.sort((a, b) => a - b);

    let playerIndex = 0, trainerIndex = 0, matchCount = 0;
    while (playerIndex < players.length && trainerIndex < trainers.length) {
        if (players[playerIndex] <= trainers[trainerIndex]) {
            matchCount++;
            playerIndex++;
            trainerIndex++;
        } else {
            trainerIndex++;
        }
    }

    return matchCount;
}
```
1. Sort the `players` and `trainers` arrays in ascending order.
2. Initialize variables `playerIndex`, `trainerIndex`, and `matchCount` to 0.
3. Loop through the `players` and `trainers` arrays while `playerIndex` is less than the `players` length and `trainerIndex` is less than the `trainers` length.
   a. If the current `player`'s ability is less than or equal to the current `trainer`'s training capacity, increase the `matchCount`, increment both `playerIndex` and `trainerIndex`.
   b. If not, increment `trainerIndex` only.
4. After the loop, the final `matchCount` value is the maximum number of matchings that satisfy the conditions.


# Smallest Subarrays With Maximum Bitwise OR

- slug: smallest-subarrays-with-maximum-bitwise-or
- difficulty: Medium

You are given a **0-indexed** array `nums` of length `n`, consisting of non-negative integers. For each index `i` from `0` to `n - 1`, you must determine the size of the **minimum sized** non-empty subarray of `nums` starting at `i` (**inclusive**) that has the **maximum** possible **bitwise OR**.

*   In other words, let `Bij` be the bitwise OR of the subarray `nums[i...j]`. You need to find the smallest subarray starting at `i`, such that bitwise OR of this subarray is equal to `max(Bik)` where `i <= k <= n - 1`.

The bitwise OR of an array is the bitwise OR of all the numbers in it.

Return _an integer array_ `answer` _of size_ `n` _where_ `answer[i]` _is the length of the **minimum** sized subarray starting at_ `i` _with **maximum** bitwise OR._

A **subarray** is a contiguous non-empty sequence of elements within an array.

**Example 1:**

**Input:** nums = \[1,0,2,1,3\]
**Output:** \[3,3,2,2,1\]
**Explanation:**
The maximum possible bitwise OR starting at any index is 3.
- Starting at index 0, the shortest subarray that yields it is \[1,0,2\].
- Starting at index 1, the shortest subarray that yields the maximum bitwise OR is \[0,2,1\].
- Starting at index 2, the shortest subarray that yields the maximum bitwise OR is \[2,1\].
- Starting at index 3, the shortest subarray that yields the maximum bitwise OR is \[1,3\].
- Starting at index 4, the shortest subarray that yields the maximum bitwise OR is \[3\].
Therefore, we return \[3,3,2,2,1\].

**Example 2:**

**Input:** nums = \[1,2\]
**Output:** \[2,1\]
**Explanation:**
Starting at index 0, the shortest subarray that yields the maximum bitwise OR is of length 2.
Starting at index 1, the shortest subarray that yields the maximum bitwise OR is of length 1.
Therefore, we return \[2,1\].

**Constraints:**

*   `n == nums.length`
*   `1 <= n <= 105`
*   `0 <= nums[i] <= 109`

## A solution in Java

```java
public int[] minSizeMaxBitwiseOR(int[] nums) {
    int n = nums.length;
    int[] answer = new int[n];
    int orSum = 0;

    for (int i = 0, j = 0; i < n; ++i) {
        orSum |= nums[i];
        while ((orSum | nums[j]) == orSum) {
            orSum ^= nums[j++];
        }

        answer[i] = i - j + 2;
    }

    return answer;
}
```
The algorithm uses two pointers `i` and `j` to process the array `nums`. For each index `i`, it will compute the bitwise OR `orSum` using the current value `nums[i]`. Then, in the inner loop, we check if the bitwise OR including `nums[j]` is the same as the current `orSum`. If so, we remove `nums[j]` from `orSum` by XOR and increment the pointer `j`.

We calculate the minimum size of the subarray that has the maximum bitwise OR at index `i` by subtracting `j` from `i` and adding 2. This will give us the current minimum size starting at the current position `i`.

The outer loop moves `i` from `0` to `n - 1`, ensuring that every index is accounted for.

At the end of each iteration, the corresponding bitwise OR value will be stored in the `answer` array. Finally, we return the `answer` array, containing the length of the minimum-sized subarray starting at `i` with the maximum bitwise OR.

## A solution in C++

```cpp
#include <vector>

std::vector<int> minSizeMaxBitwiseOR(const std::vector<int>& nums) {
    int n = nums.size();
    std::vector<int> answer(n);
    int orSum = 0;

    for (int i = 0, j = 0; i < n; ++i) {
        orSum |= nums[i];
        while ((orSum | nums[j]) == orSum) {
            orSum ^= nums[j++];
        }

        answer[i] = i - j + 2;
    }

    return answer;
}
```
The algorithm uses two pointers `i` and `j` to process the array `nums`. For each index `i`, it will compute the bitwise OR `orSum` using the current value `nums[i]`. Then, in the inner loop, we check if the bitwise OR including `nums[j]` is the same as the current `orSum`. If so, we remove `nums[j]` from `orSum` by XOR and increment the pointer `j`.

We calculate the minimum size of the subarray that has the maximum bitwise OR at index `i` by subtracting `j` from `i` and adding 2. This will give us the current minimum size starting at the current position `i`.

The outer loop moves `i` from `0` to `n - 1`, ensuring that every index is accounted for.

At the end of each iteration, the corresponding bitwise OR value will be stored in the `answer` array. Finally, we return the `answer` array, containing the length of the minimum-sized subarray starting at `i` with the maximum bitwise OR.

## A solution in Python

```python
def minSizeMaxBitwiseOR(nums):
    n = len(nums)
    answer = [0] * n
    orSum = 0

    i, j = 0, 0
    while i < n:
        orSum |= nums[i]
        while (orSum | nums[j]) == orSum:
            orSum ^= nums[j]
            j += 1

        answer[i] = i - j + 2
        i += 1

    return answer
```
The algorithm uses two pointers `i` and `j` to process the array `nums`. For each index `i`, it will compute the bitwise OR `orSum` using the current value `nums[i]`. Then, in the inner loop, we check if the bitwise OR including `nums[j]` is the same as the current `orSum`. If so, we remove `nums[j]` from `orSum` by XOR and increment the pointer `j`.

We calculate the minimum size of the subarray that has the maximum bitwise OR at index `i` by subtracting `j` from `i` and adding 2. This will give us the current minimum size starting at the current position `i`.

The outer loop moves `i` from `0` to `n - 1`, ensuring that every index is accounted for.

At the end of each iteration, the corresponding bitwise OR value will be stored in the `answer` array. Finally, we return the `answer` array, containing the length of the minimum-sized subarray starting at `i` with the maximum bitwise OR.

## A solution in Javascript

```javascript
function minSizeMaxBitwiseOR(nums) {
    const n = nums.length;
    const answer = new Array(n);
    let orSum = 0;

    for (let i = 0, j = 0; i < n; ++i) {
        orSum |= nums[i];
        while ((orSum | nums[j]) === orSum) {
            orSum ^= nums[j++];
        }

        answer[i] = i - j + 2;
    }

    return answer;
}
```
The algorithm uses two pointers `i` and `j` to process the array `nums`. For each index `i`, it will compute the bitwise OR `orSum` using the current value `nums[i]`. Then, in the inner loop, we check if the bitwise OR including `nums[j]` is the same as the current `orSum`. If so, we remove `nums[j]` from `orSum` by XOR and increment the pointer `j`.

We calculate the minimum size of the subarray that has the maximum bitwise OR at index `i` by subtracting `j` from `i` and adding 2. This will give us the current minimum size starting at the current position `i`.

The outer loop moves `i` from `0` to `n - 1`, ensuring that every index is accounted for.

At the end of each iteration, the corresponding bitwise OR value will be stored in the `answer` array. Finally, we return the `answer` array, containing the length of the minimum-sized subarray starting at `i` with the maximum bitwise OR.


# Minimum Money Required Before Transactions

- slug: minimum-money-required-before-transactions
- difficulty: Hard

You are given a **0-indexed** 2D integer array `transactions`, where `transactions[i] = [costi, cashbacki]`.

The array describes transactions, where each transaction must be completed exactly once in **some order**. At any given moment, you have a certain amount of `money`. In order to complete transaction `i`, `money >= costi` must hold true. After performing a transaction, `money` becomes `money - costi + cashbacki`.

Return _the minimum amount of_ `money` _required before any transaction so that all of the transactions can be completed **regardless of the order** of the transactions._

**Example 1:**

**Input:** transactions = \[\[2,1\],\[5,0\],\[4,2\]\]
**Output:** 10
**Explanation:**
Starting with money = 10, the transactions can be performed in any order.
It can be shown that starting with money < 10 will fail to complete all transactions in some order.

**Example 2:**

**Input:** transactions = \[\[3,0\],\[0,3\]\]
**Output:** 3
**Explanation:**
- If transactions are in the order \[\[3,0\],\[0,3\]\], the minimum money required to complete the transactions is 3.
- If transactions are in the order \[\[0,3\],\[3,0\]\], the minimum money required to complete the transactions is 0.
Thus, starting with money = 3, the transactions can be performed in any order.

**Constraints:**

*   `1 <= transactions.length <= 105`
*   `transactions[i].length == 2`
*   `0 <= costi, cashbacki <= 109`

## A solution in Java

```java
public int min_money(int[][] transactions) {
    int min_money_needed = 0;
    for (int[] transaction : transactions) {
        min_money_needed = Math.max(min_money_needed, transaction[0] - transaction[1]);
    }
    return min_money_needed;
}
```
The algorithm is quite straightforward. It finds the minimum amount of money required by iterating through the transactions and calculating the difference between the cost and cashback for each transaction. To find the minimum amount of money needed, we track the maximum difference between the cost and cashback. At the end of the loop, the maximum difference is returned as the minimum amount of money required to perform all transactions in any order.

## A solution in C++

```cpp
int min_money(vector<vector<int>>& transactions) {
    int min_money_needed = 0;
    for (const auto& transaction : transactions) {
        min_money_needed = max(min_money_needed, transaction[0] - transaction[1]);
    }
    return min_money_needed;
}
```
The algorithm is quite straightforward. It finds the minimum amount of money required by iterating through the transactions and calculating the difference between the cost and cashback for each transaction. To find the minimum amount of money needed, we track the maximum difference between the cost and cashback. At the end of the loop, the maximum difference is returned as the minimum amount of money required to perform all transactions in any order.

## A solution in Python

```python
def min_money(transactions):
    min_money_needed = 0
    for transaction in transactions:
        min_money_needed = max(min_money_needed, transaction[0] - transaction[1])
    return min_money_needed
```
The algorithm is quite straightforward. It finds the minimum amount of money required by iterating through the transactions and calculating the difference between the cost and cashback for each transaction. To find the minimum amount of money needed, we track the maximum difference between the cost and cashback. At the end of the loop, the maximum difference is returned as the minimum amount of money required to perform all transactions in any order.

## A solution in Javascript

```javascript
function min_money(transactions) {
    let min_money_needed = 0;
    for (const transaction of transactions) {
        min_money_needed = Math.max(min_money_needed, transaction[0] - transaction[1]);
    }
    return min_money_needed;
}
```
The algorithm is quite straightforward. It finds the minimum amount of money required by iterating through the transactions and calculating the difference between the cost and cashback for each transaction. To find the minimum amount of money needed, we track the maximum difference between the cost and cashback. At the end of the loop, the maximum difference is returned as the minimum amount of money required to perform all transactions in any order.


# Smallest Even Multiple

- slug: smallest-even-multiple
- difficulty: Easy

Given a **positive** integer `n`, return _the smallest positive integer that is a multiple of **both**_ `2` _and_ `n`.

**Example 1:**

**Input:** n = 5
**Output:** 10
**Explanation:** The smallest multiple of both 5 and 2 is 10.

**Example 2:**

**Input:** n = 6
**Output:** 6
**Explanation:** The smallest multiple of both 6 and 2 is 6. Note that a number is a multiple of itself.

**Constraints:**

*   `1 <= n <= 150`

## A solution in Java

```java
public int smallestMultiple(int n) {
    return n % 2 == 0 ? n : n * 2;
}
```
The algorithm to solve this problem is quite simple. The smallest positive integer that is a multiple of both 2 and `n` can be determined by checking if `n` is even or odd. If `n` is even, it means that it is already a multiple of 2, so the answer should be `n`. If `n` is odd, we need to multiply `n` by 2 to get the smallest multiple that is also divisible by 2, so the answer should be `n * 2`.

## A solution in C++

```cpp
int smallestMultiple(int n) {
    return n % 2 == 0 ? n : n * 2;
}
```
The algorithm to solve this problem is quite simple. The smallest positive integer that is a multiple of both 2 and `n` can be determined by checking if `n` is even or odd. If `n` is even, it means that it is already a multiple of 2, so the answer should be `n`. If `n` is odd, we need to multiply `n` by 2 to get the smallest multiple that is also divisible by 2, so the answer should be `n * 2`.

## A solution in Python

```python
def smallest_multiple(n):
    return n if n % 2 == 0 else n * 2
```
The algorithm to solve this problem is quite simple. The smallest positive integer that is a multiple of both 2 and `n` can be determined by checking if `n` is even or odd. If `n` is even, it means that it is already a multiple of 2, so the answer should be `n`. If `n` is odd, we need to multiply `n` by 2 to get the smallest multiple that is also divisible by 2, so the answer should be `n * 2`.

## A solution in Javascript

```javascript
function smallestMultiple(n) {
    return n % 2 === 0 ? n : n * 2;
}
```
The algorithm to solve this problem is quite simple. The smallest positive integer that is a multiple of both 2 and `n` can be determined by checking if `n` is even or odd. If `n` is even, it means that it is already a multiple of 2, so the answer should be `n`. If `n` is odd, we need to multiply `n` by 2 to get the smallest multiple that is also divisible by 2, so the answer should be `n * 2`.


# Length of the Longest Alphabetical Continuous Substring

- slug: length-of-the-longest-alphabetical-continuous-substring
- difficulty: Medium

An **alphabetical continuous string** is a string consisting of consecutive letters in the alphabet. In other words, it is any substring of the string `"abcdefghijklmnopqrstuvwxyz "`.

*   For example, `"abc "` is an alphabetical continuous string, while `"acb "` and `"za "` are not.

Given a string `s` consisting of lowercase letters only, return the _length of the **longest** alphabetical continuous substring._

**Example 1:**

**Input:** s =  "abacaba "
**Output:** 2
**Explanation:** There are 4 distinct continuous substrings:  "a ",  "b ",  "c " and  "ab ".
 "ab " is the longest continuous substring.

**Example 2:**

**Input:** s =  "abcde "
**Output:** 5
**Explanation:**  "abcde " is the longest continuous substring.

**Constraints:**

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

## A solution in Java

```java
public int longestAlphabeticalContinuousSubstring(String s) {
    int maxLength = 1, currentLength = 1;
    for (int i = 1; i < s.length(); ++i) {
        if (s.charAt(i) == s.charAt(i - 1) + 1) {
            ++currentLength;
        } else {
            maxLength = Math.max(maxLength, currentLength);
            currentLength = 1;
        }
    }
    return Math.max(maxLength, currentLength);
}
```
1. Initialize two variables, `max_length` and `current_length` to keep track of the longest alphabetical continuous substring's length and the current alphabetical substring's length, respectively. Both are initially set to 1, as there is at least one character in the string.
2. Iterate through the string from the second character to the end.
3. Compare the current character and the previous character. If they are consecutive in the alphabet (i.e., the current character's Unicode code point is one greater than the previous character's code point), increment the current length.
4. If they are not consecutive, update the maximum length by comparing it with the current length and reset the current length to 1.
5. After finishing the loop, we need to compare the maximum length and the current length once more to make sure the last continuous substring is accounted for.
6. Return the largest value between the two as the answer.

## A solution in C++

```cpp
int longest_alphabetical_continuous_substring(string s) {
    int max_length = 1, current_length = 1;
    for (int i = 1; i < s.length(); ++i) {
        if (s[i] == s[i - 1] + 1) {
            ++current_length;
        } else {
            max_length = max(max_length, current_length);
            current_length = 1;
        }
    }
    return max(max_length, current_length);
}
```
1. Initialize two variables, `max_length` and `current_length` to keep track of the longest alphabetical continuous substring's length and the current alphabetical substring's length, respectively. Both are initially set to 1, as there is at least one character in the string.
2. Iterate through the string from the second character to the end.
3. Compare the current character and the previous character. If they are consecutive in the alphabet (i.e., the current character's Unicode code point is one greater than the previous character's code point), increment the current length.
4. If they are not consecutive, update the maximum length by comparing it with the current length and reset the current length to 1.
5. After finishing the loop, we need to compare the maximum length and the current length once more to make sure the last continuous substring is accounted for.
6. Return the largest value between the two as the answer.

## A solution in Python

```python
def longest_alphabetical_continuous_substring(s: str) -> int:
    max_length = current_length = 1
    for i in range(1, len(s)):
        if ord(s[i]) == ord(s[i - 1]) + 1:
            current_length += 1
        else:
            max_length = max(max_length, current_length)
            current_length = 1
    return max(max_length, current_length)
```
1. Initialize two variables, `max_length` and `current_length` to keep track of the longest alphabetical continuous substring's length and the current alphabetical substring's length, respectively. Both are initially set to 1, as there is at least one character in the string.
2. Iterate through the string from the second character to the end.
3. Compare the current character and the previous character. If they are consecutive in the alphabet (i.e., the current character's Unicode code point is one greater than the previous character's code point), increment the current length.
4. If they are not consecutive, update the maximum length by comparing it with the current length and reset the current length to 1.
5. After finishing the loop, we need to compare the maximum length and the current length once more to make sure the last continuous substring is accounted for.
6. Return the largest value between the two as the answer.

## A solution in Javascript

```javascript
function longestAlphabeticalContinuousSubstring(s) {
    let maxLength = 1, currentLength = 1;
    for (let i = 1; i < s.length; ++i) {
        if (s.charCodeAt(i) === s.charCodeAt(i - 1) + 1) {
            ++currentLength;
        } else {
            maxLength = Math.max(maxLength, currentLength);
            currentLength = 1;
        }
    }
    return Math.max(maxLength, currentLength);
}
```
1. Initialize two variables, `max_length` and `current_length` to keep track of the longest alphabetical continuous substring's length and the current alphabetical substring's length, respectively. Both are initially set to 1, as there is at least one character in the string.
2. Iterate through the string from the second character to the end.
3. Compare the current character and the previous character. If they are consecutive in the alphabet (i.e., the current character's Unicode code point is one greater than the previous character's code point), increment the current length.
4. If they are not consecutive, update the maximum length by comparing it with the current length and reset the current length to 1.
5. After finishing the loop, we need to compare the maximum length and the current length once more to make sure the last continuous substring is accounted for.
6. Return the largest value between the two as the answer.


# Reverse Odd Levels of Binary Tree

- slug: reverse-odd-levels-of-binary-tree
- difficulty: Medium

Given the `root` of a **perfect** binary tree, reverse the node values at each **odd** level of the tree.

*   For example, suppose the node values at level 3 are `[2,1,3,4,7,11,29,18]`, then it should become `[18,29,11,7,4,3,1,2]`.

Return _the root of the reversed tree_.

A binary tree is **perfect** if all parent nodes have two children and all leaves are on the same level.

The **level** of a node is the number of edges along the path between it and the root node.

**Example 1:**

**Input:** root = \[2,3,5,8,13,21,34\]
**Output:** \[2,5,3,8,13,21,34\]
**Explanation:**
The tree has only one odd level.
The nodes at level 1 are 3, 5 respectively, which are reversed and become 5, 3.

**Example 2:**

**Input:** root = \[7,13,11\]
**Output:** \[7,11,13\]
**Explanation:**
The nodes at level 1 are 13, 11, which are reversed and become 11, 13.

**Example 3:**

**Input:** root = \[0,1,2,0,0,0,0,1,1,1,1,2,2,2,2\]
**Output:** \[0,2,1,0,0,0,0,2,2,2,2,1,1,1,1\]
**Explanation:**
The odd levels have non-zero values.
The nodes at level 1 were 1, 2, and are 2, 1 after the reversal.
The nodes at level 3 were 1, 1, 1, 1, 2, 2, 2, 2, and are 2, 2, 2, 2, 1, 1, 1, 1 after the reversal.

**Constraints:**

*   The number of nodes in the tree is in the range `[1, 214]`.
*   `0 <= Node.val <= 105`
*   `root` is a **perfect** binary tree.

## A solution in Java

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

public void reverseOddLevels(TreeNode node, int level) {
    if (node == null) return;
    if (level % 2 == 1) {
        TreeNode temp = node.left;
        node.left = node.right;
        node.right = temp;
    }
    reverseOddLevels(node.left, level + 1);
    reverseOddLevels(node.right, level + 1);
}

public TreeNode reverseOddLevelNodes(TreeNode root) {
    reverseOddLevels(root, 0);
    return root;
}
```
The algorithm performs a depth-first traversal of the binary tree, keeping track of the current tree level. For each node, if the current level is odd, the child nodes are swapped. After swapping all nodes in odd levels, the root node of the modified tree is returned. This approach preserves the perfect binary tree property while reversing node values at odd levels.

## A solution in C++

```cpp
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
};

void reverseOddLevels(TreeNode* node, int level) {
    if (node == nullptr) return;
    if (level % 2 == 1) {
        TreeNode* temp = node->left;
        node->left = node->right;
        node->right = temp;
    }
    reverseOddLevels(node->left, level + 1);
    reverseOddLevels(node->right, level + 1);
}

TreeNode* reverseOddLevelNodes(TreeNode* root) {
    reverseOddLevels(root, 0);
    return root;
}
```
The algorithm performs a depth-first traversal of the binary tree, keeping track of the current tree level. For each node, if the current level is odd, the child nodes are swapped. After swapping all nodes in odd levels, the root node of the modified tree is returned. This approach preserves the perfect binary tree property while reversing node values at odd levels.

## A solution in Python

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

def reverse_odd_levels(node, level):
    if node is None: return
    if level % 2 == 1:
        node.left, node.right = node.right, node.left
    reverse_odd_levels(node.left, level + 1)
    reverse_odd_levels(node.right, level + 1)

def reverse_odd_level_nodes(root):
    reverse_odd_levels(root, 0)
    return root
```
The algorithm performs a depth-first traversal of the binary tree, keeping track of the current tree level. For each node, if the current level is odd, the child nodes are swapped. After swapping all nodes in odd levels, the root node of the modified tree is returned. This approach preserves the perfect binary tree property while reversing node values at odd levels.

## A solution in Javascript

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

function reverseOddLevels(node, level) {
    if (node === null) return;
    if (level % 2 === 1) {
        const temp = node.left;
        node.left = node.right;
        node.right = temp;
    }
    reverseOddLevels(node.left, level + 1);
    reverseOddLevels(node.right, level + 1);
}

function reverseOddLevelNodes(root) {
    reverseOddLevels(root, 0);
    return root;
}
```
The algorithm performs a depth-first traversal of the binary tree, keeping track of the current tree level. For each node, if the current level is odd, the child nodes are swapped. After swapping all nodes in odd levels, the root node of the modified tree is returned. This approach preserves the perfect binary tree property while reversing node values at odd levels.


# Sum of Prefix Scores of Strings

- slug: sum-of-prefix-scores-of-strings
- difficulty: Hard

You are given an array `words` of size `n` consisting of **non-empty** strings.

We define the **score** of a string `word` as the **number** of strings `words[i]` such that `word` is a **prefix** of `words[i]`.

*   For example, if `words = [ "a ", "ab ", "abc ", "cab "]`, then the score of `"ab "` is `2`, since `"ab "` is a prefix of both `"ab "` and `"abc "`.

Return _an array_ `answer` _of size_ `n` _where_ `answer[i]` _is the **sum** of scores of every **non-empty** prefix of_ `words[i]`.

**Note** that a string is considered as a prefix of itself.

**Example 1:**

**Input:** words = \[ "abc ", "ab ", "bc ", "b "\]
**Output:** \[5,4,3,2\]
**Explanation:** The answer for each string is the following:
-  "abc " has 3 prefixes:  "a ",  "ab ", and  "abc ".
- There are 2 strings with the prefix  "a ", 2 strings with the prefix  "ab ", and 1 string with the prefix  "abc ".
The total is answer\[0\] = 2 + 2 + 1 = 5.
-  "ab " has 2 prefixes:  "a " and  "ab ".
- There are 2 strings with the prefix  "a ", and 2 strings with the prefix  "ab ".
The total is answer\[1\] = 2 + 2 = 4.
-  "bc " has 2 prefixes:  "b " and  "bc ".
- There are 2 strings with the prefix  "b ", and 1 string with the prefix  "bc ".
The total is answer\[2\] = 2 + 1 = 3.
-  "b " has 1 prefix:  "b ".
- There are 2 strings with the prefix  "b ".
The total is answer\[3\] = 2.

**Example 2:**

**Input:** words = \[ "abcd "\]
**Output:** \[4\]
**Explanation:**
 "abcd " has 4 prefixes:  "a ",  "ab ",  "abc ", and  "abcd ".
Each prefix has a score of one, so the total is answer\[0\] = 1 + 1 + 1 + 1 = 4.

**Constraints:**

*   `1 <= words.length <= 1000`
*   `1 <= words[i].length <= 1000`
*   `words[i]` consists of lowercase English letters.

## A solution in Java

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

public List<Integer> prefixScoreSum(List<String> words) {
    List<Integer> result = new ArrayList<>(words.size());
    Map<String, Integer> prefixCount = new HashMap<>();

    for (String word : words) {
        String prefix = "";
        for (char c : word.toCharArray()) {
            prefix += c;
            prefixCount.put(prefix, prefixCount.getOrDefault(prefix, 0) + 1);
        }
    }

    for (String word : words) {
        String prefix = "";
        int sum = 0;
        for (char c : word.toCharArray()) {
            prefix += c;
            sum += prefixCount.getOrDefault(prefix, 0);
        }
        result.add(sum);
    }

    return result;
}
```
The algorithm works as follows:
1. For each word in `words`, count the number of occurrences of each of its prefixes using a dictionary/hashmap.
2. For each word in `words`, iterate through its prefixes and sum up the counts calculated in the previous step. Store the result for each word in the `result` list/array.

The algorithm's time complexity is O(n * max_len(words)), where n is the number of words and max_len(words) is the length of the longest word. The space complexity is also O(n * max_len(words)).

## A solution in C++

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

std::vector<int> prefix_score_sum(std::vector<std::string>& words) {
    std::vector<int> result(words.size(), 0);
    std::unordered_map<std::string, int> prefix_count;

    for (const auto& word : words) {
        std::string prefix = "";
        for (const auto& c : word) {
            prefix += c;
            prefix_count[prefix]++;
        }
    }

    for (int i = 0; i < words.size(); ++i) {
        std::string prefix = "";
        for (const auto& c : words[i]) {
            prefix += c;
            result[i] += prefix_count[prefix];
        }
    }

    return result;
}
```
The algorithm works as follows:
1. For each word in `words`, count the number of occurrences of each of its prefixes using a dictionary/hashmap.
2. For each word in `words`, iterate through its prefixes and sum up the counts calculated in the previous step. Store the result for each word in the `result` list/array.

The algorithm's time complexity is O(n * max_len(words)), where n is the number of words and max_len(words) is the length of the longest word. The space complexity is also O(n * max_len(words)).

## A solution in Python

```python
from collections import defaultdict

def prefix_score_sum(words):
    result = [0] * len(words)
    prefix_count = defaultdict(int)

    for word in words:
        prefix = ""
        for c in word:
            prefix += c
            prefix_count[prefix] += 1

    for i, word in enumerate(words):
        prefix = ""
        for c in word:
            prefix += c
            result[i] += prefix_count[prefix]

    return result
```
The algorithm works as follows:
1. For each word in `words`, count the number of occurrences of each of its prefixes using a dictionary/hashmap.
2. For each word in `words`, iterate through its prefixes and sum up the counts calculated in the previous step. Store the result for each word in the `result` list/array.

The algorithm's time complexity is O(n * max_len(words)), where n is the number of words and max_len(words) is the length of the longest word. The space complexity is also O(n * max_len(words)).

## A solution in Javascript

```javascript
function prefixScoreSum(words) {
    const result = new Array(words.length).fill(0);
    const prefixCount = {};

    for (const word of words) {
        let prefix = "";
        for (const c of word) {
            prefix += c;
            prefixCount[prefix] = (prefixCount[prefix] || 0) + 1;
        }
    }

    for (let i = 0; i < words.length; i++) {
        let prefix = "";
        for (const c of words[i]) {
            prefix += c;
            result[i] += prefixCount[prefix];
        }
    }

    return result;
}
```
The algorithm works as follows:
1. For each word in `words`, count the number of occurrences of each of its prefixes using a dictionary/hashmap.
2. For each word in `words`, iterate through its prefixes and sum up the counts calculated in the previous step. Store the result for each word in the `result` list/array.

The algorithm's time complexity is O(n * max_len(words)), where n is the number of words and max_len(words) is the length of the longest word. The space complexity is also O(n * max_len(words)).