# Most Beautiful Item for Each Query

- slug: most-beautiful-item-for-each-query
- difficulty: Medium

You are given a 2D integer array `items` where `items[i] = [pricei, beautyi]` denotes the **price** and **beauty** of an item respectively.

You are also given a **0-indexed** integer array `queries`. For each `queries[j]`, you want to determine the **maximum beauty** of an item whose **price** is **less than or equal** to `queries[j]`. If no such item exists, then the answer to this query is `0`.

Return _an array_ `answer` _of the same length as_ `queries` _where_ `answer[j]` _is the answer to the_ `jth` _query_.

**Example 1:**

**Input:** items = \[\[1,2\],\[3,2\],\[2,4\],\[5,6\],\[3,5\]\], queries = \[1,2,3,4,5,6\]
**Output:** \[2,4,5,5,6,6\]
**Explanation:**
- For queries\[0\]=1, \[1,2\] is the only item which has price <= 1. Hence, the answer for this query is 2.
- For queries\[1\]=2, the items which can be considered are \[1,2\] and \[2,4\].
  The maximum beauty among them is 4.
- For queries\[2\]=3 and queries\[3\]=4, the items which can be considered are \[1,2\], \[3,2\], \[2,4\], and \[3,5\].
  The maximum beauty among them is 5.
- For queries\[4\]=5 and queries\[5\]=6, all items can be considered.
  Hence, the answer for them is the maximum beauty of all items, i.e., 6.

**Example 2:**

**Input:** items = \[\[1,2\],\[1,2\],\[1,3\],\[1,4\]\], queries = \[1\]
**Output:** \[4\]
**Explanation:**
The price of every item is equal to 1, so we choose the item with the maximum beauty 4.
Note that multiple items can have the same price and/or beauty.

**Example 3:**

**Input:** items = \[\[10,1000\]\], queries = \[5\]
**Output:** \[0\]
**Explanation:**
No item has a price less than or equal to 5, so no item can be chosen.
Hence, the answer to the query is 0.

**Constraints:**

*   `1 <= items.length, queries.length <= 105`
*   `items[i].length == 2`
*   `1 <= pricei, beautyi, queries[j] <= 109`

## A solution in Java

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

public List<Integer> maxPrices(List<List<Integer>> items, List<Integer> queries) {
  List<Integer> answer = new ArrayList<>();
  List<Integer> sortedItems = new ArrayList<>();

  for (List<Integer> item : items) {
    sortedItems.add(item.get(0));
  }
  Collections.sort(sortedItems);

  int maxBeauty = 0;
  for (int i = 0; i < sortedItems.size(); ++i) {
    maxBeauty = Math.max(maxBeauty, items.get(i).get(1));
    sortedItems.set(i, maxBeauty);
  }

  for (int j = 0; j < queries.size(); ++j) {
    int idx = Collections.binarySearch(sortedItems, queries.get(j));
    if (idx < 0) {
      idx = -idx - 2;
    }
    answer.add(idx >= 0 ? sortedItems.get(idx) : 0);
  }

  return answer;
}
```
1. Create an empty list `answer` to store the result, and a list `sorted_items` to store the sorted prices of the items.
2. Sort the prices in `sorted_items`.
3. Iterate through the `sorted_items` and keep track of the maximum beauty for each price using variable `max_beauty`. Update `sorted_items` accordingly with the maximum beauty.
4. Iterate through each query in `queries`, find the last index in the `sorted_items` whose price is less than or equal to the query using binary search approach, and append the corresponding beauty found in `sorted_items` if the index is not negative, else append 0.
5. Return the `answer` list.

## A solution in C++

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

vector<int> maxPrices(const vector<vector<int>>& items, const vector<int>& queries) {
  vector<int> answer(queries.size());
  vector<int> sorted_items(items.size(), 0);

  for (const auto& item : items) {
    sorted_items.push_back(item[0]);
  }
  sort(sorted_items.begin(), sorted_items.end());

  int max_beauty = 0;
  for (int i = 0; i < sorted_items.size(); ++i) {
    max_beauty = max(max_beauty, items[i][1]);
    sorted_items[i] = max_beauty;
  }

  for (int j = 0; j < queries.size(); ++j) {
    int idx = upper_bound(sorted_items.begin(), sorted_items.end(), queries[j]) - sorted_items.begin() - 1;
    answer[j] = idx >= 0 ? sorted_items[idx] : 0;
  }

  return answer;
}
```
1. Create an empty list `answer` to store the result, and a list `sorted_items` to store the sorted prices of the items.
2. Sort the prices in `sorted_items`.
3. Iterate through the `sorted_items` and keep track of the maximum beauty for each price using variable `max_beauty`. Update `sorted_items` accordingly with the maximum beauty.
4. Iterate through each query in `queries`, find the last index in the `sorted_items` whose price is less than or equal to the query using binary search approach, and append the corresponding beauty found in `sorted_items` if the index is not negative, else append 0.
5. Return the `answer` list.

## A solution in Python

```python
from bisect import bisect_right

def maxPrices(items, queries):
    answer = []
    sorted_items = [item[0] for item in items]
    sorted_items.sort()

    max_beauty = 0
    for i, price in enumerate(sorted_items):
        max_beauty = max(max_beauty, items[i][1])
        sorted_items[i] = max_beauty

    for query in queries:
        idx = bisect_right(sorted_items, query) - 1
        answer.append(sorted_items[idx] if idx >= 0 else 0)

    return answer
```
1. Create an empty list `answer` to store the result, and a list `sorted_items` to store the sorted prices of the items.
2. Sort the prices in `sorted_items`.
3. Iterate through the `sorted_items` and keep track of the maximum beauty for each price using variable `max_beauty`. Update `sorted_items` accordingly with the maximum beauty.
4. Iterate through each query in `queries`, find the last index in the `sorted_items` whose price is less than or equal to the query using binary search approach, and append the corresponding beauty found in `sorted_items` if the index is not negative, else append 0.
5. Return the `answer` list.

## A solution in Javascript

```javascript
function maxPrices(items, queries) {
  const answer = [];
  const sortedItems = items.map(item => item[0]);
  sortedItems.sort((a, b) => a - b);

  let maxBeauty = 0;
  for (let i = 0; i < sortedItems.length; ++i) {
    maxBeauty = Math.max(maxBeauty, items[i][1]);
    sortedItems[i] = maxBeauty;
  }

  for (const query of queries) {
    const idx = sortedItems.filter(price => price <= query).length - 1;
    answer.push(idx >= 0 ? sortedItems[idx] : 0);
  }

  return answer;
}
```
1. Create an empty list `answer` to store the result, and a list `sorted_items` to store the sorted prices of the items.
2. Sort the prices in `sorted_items`.
3. Iterate through the `sorted_items` and keep track of the maximum beauty for each price using variable `max_beauty`. Update `sorted_items` accordingly with the maximum beauty.
4. Iterate through each query in `queries`, find the last index in the `sorted_items` whose price is less than or equal to the query using binary search approach, and append the corresponding beauty found in `sorted_items` if the index is not negative, else append 0.
5. Return the `answer` list.


# Maximum Number of Tasks You Can Assign

- slug: maximum-number-of-tasks-you-can-assign
- difficulty: Hard

You have `n` tasks and `m` workers. Each task has a strength requirement stored in a **0-indexed** integer array `tasks`, with the `ith` task requiring `tasks[i]` strength to complete. The strength of each worker is stored in a **0-indexed** integer array `workers`, with the `jth` worker having `workers[j]` strength. Each worker can only be assigned to a **single** task and must have a strength **greater than or equal** to the task's strength requirement (i.e., `workers[j] >= tasks[i]`).

Additionally, you have `pills` magical pills that will **increase a worker's strength** by `strength`. You can decide which workers receive the magical pills, however, you may only give each worker **at most one** magical pill.

Given the **0-indexed** integer arrays `tasks` and `workers` and the integers `pills` and `strength`, return _the **maximum** number of tasks that can be completed._

**Example 1:**

**Input:** tasks = \[**3**,**2**,**1**\], workers = \[**0**,**3**,**3**\], pills = 1, strength = 1
**Output:** 3
**Explanation:**
We can assign the magical pill and tasks as follows:
- Give the magical pill to worker 0.
- Assign worker 0 to task 2 (0 + 1 >= 1)
- Assign worker 1 to task 1 (3 >= 2)
- Assign worker 2 to task 0 (3 >= 3)

**Example 2:**

**Input:** tasks = \[**5**,4\], workers = \[**0**,0,0\], pills = 1, strength = 5
**Output:** 1
**Explanation:**
We can assign the magical pill and tasks as follows:
- Give the magical pill to worker 0.
- Assign worker 0 to task 0 (0 + 5 >= 5)

**Example 3:**

**Input:** tasks = \[**10**,**15**,30\], workers = \[**0**,**10**,10,10,10\], pills = 3, strength = 10
**Output:** 2
**Explanation:**
We can assign the magical pills and tasks as follows:
- Give the magical pill to worker 0 and worker 1.
- Assign worker 0 to task 0 (0 + 10 >= 10)
- Assign worker 1 to task 1 (10 + 10 >= 15)
The last pill is not given because it will not make any worker strong enough for the last task.

**Constraints:**

*   `n == tasks.length`
*   `m == workers.length`
*   `1 <= n, m <= 5 * 104`
*   `0 <= pills <= m`
*   `0 <= tasks[i], workers[j], strength <= 109`

## A solution in Java

```java
import java.util.Arrays;

public int maxTasks(int[] tasks, int[] workers, int pills, int strength) {
  Arrays.sort(tasks);
  Arrays.sort(workers);

  int cnt = 0;
  for (int i = 0, j = 0; j < pills; ++j) {
    while (i < tasks.length && tasks[i] > workers[j] + strength) {
      ++i;
    }
    if (i < tasks.length) {
      ++cnt;
      ++i;
    }
  }

  for (int i = 0, j = pills; i < tasks.length && j < workers.length; ++i) {
    if (tasks[i] <= workers[j]) {
      ++cnt;
      ++j;
    }
  }

  return cnt;
}
```
First, we sort both the tasks and the workers lists. This will simplify our assignments later.

We then count the number of tasks that will be completed given the available pills. Start with the lowest task and check if a worker with a pill can complete the task. If a worker with a pill can complete the task, we add 1 to our task counter and move to the next task. We do this for all pills as long as there are remaining tasks.

Finally, we check the remaining tasks and workers without pills to see if they can complete any tasks. We start with the lowest task and try to match it to a worker without a pill. If a worker can complete the task, we increment our task counter and move to the next task.

We return the total number of tasks that can be completed.

## A solution in C++

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

int maxTasks(std::vector<int>& tasks, std::vector<int>& workers, int pills, int strength) {
  std::sort(tasks.begin(), tasks.end());
  std::sort(workers.begin(), workers.end());

  int cnt = 0;
  for (int i = 0, j = 0; j < pills; ++j) {
    while (i < tasks.size() && tasks[i] > workers[j] + strength) {
      ++i;
    }
    if (i < tasks.size()) {
      ++cnt;
      ++i;
    }
  }

  for (int i = 0, j = pills; i < tasks.size() && j < workers.size(); ++i) {
    if (tasks[i] <= workers[j]) {
      ++cnt;
      ++j;
    }
  }

  return cnt;
}
```
First, we sort both the tasks and the workers lists. This will simplify our assignments later.

We then count the number of tasks that will be completed given the available pills. Start with the lowest task and check if a worker with a pill can complete the task. If a worker with a pill can complete the task, we add 1 to our task counter and move to the next task. We do this for all pills as long as there are remaining tasks.

Finally, we check the remaining tasks and workers without pills to see if they can complete any tasks. We start with the lowest task and try to match it to a worker without a pill. If a worker can complete the task, we increment our task counter and move to the next task.

We return the total number of tasks that can be completed.

## A solution in Python

```python
def maxTasks(tasks, workers, pills, strength):
  tasks.sort()
  workers.sort()

  cnt = 0
  i = 0
  for j in range(pills):
    while i < len(tasks) and tasks[i] > workers[j] + strength:
      i += 1
    if i < len(tasks):
      cnt += 1
      i += 1

  i = 0
  for j in range(pills, len(workers)):
    if i < len(tasks) and tasks[i] <= workers[j]:
      cnt += 1
      i += 1

  return cnt
```
First, we sort both the tasks and the workers lists. This will simplify our assignments later.

We then count the number of tasks that will be completed given the available pills. Start with the lowest task and check if a worker with a pill can complete the task. If a worker with a pill can complete the task, we add 1 to our task counter and move to the next task. We do this for all pills as long as there are remaining tasks.

Finally, we check the remaining tasks and workers without pills to see if they can complete any tasks. We start with the lowest task and try to match it to a worker without a pill. If a worker can complete the task, we increment our task counter and move to the next task.

We return the total number of tasks that can be completed.

## A solution in Javascript

```javascript
function maxTasks(tasks, workers, pills, strength) {
  tasks.sort((a, b) => a - b);
  workers.sort((a, b) => a - b);

  let cnt = 0;
  let i = 0;
  for (let j = 0; j < pills; ++j) {
    while (i < tasks.length && tasks[i] > workers[j] + strength) {
      ++i;
    }
    if (i < tasks.length) {
      ++cnt;
      ++i;
    }
  }

  for (i = 0, j = pills; i < tasks.length && j < workers.length; ++i) {
    if (tasks[i] <= workers[j]) {
      ++cnt;
      ++j;
    }
  }

  return cnt;
}
```
First, we sort both the tasks and the workers lists. This will simplify our assignments later.

We then count the number of tasks that will be completed given the available pills. Start with the lowest task and check if a worker with a pill can complete the task. If a worker with a pill can complete the task, we add 1 to our task counter and move to the next task. We do this for all pills as long as there are remaining tasks.

Finally, we check the remaining tasks and workers without pills to see if they can complete any tasks. We start with the lowest task and try to match it to a worker without a pill. If a worker can complete the task, we increment our task counter and move to the next task.

We return the total number of tasks that can be completed.


# Time Needed to Buy Tickets

- slug: time-needed-to-buy-tickets
- difficulty: Easy

There are `n` people in a line queuing to buy tickets, where the `0th` person is at the **front** of the line and the `(n - 1)th` person is at the **back** of the line.

You are given a **0-indexed** integer array `tickets` of length `n` where the number of tickets that the `ith` person would like to buy is `tickets[i]`.

Each person takes **exactly 1 second** to buy a ticket. A person can only buy **1 ticket at a time** and has to go back to **the end** of the line (which happens **instantaneously**) in order to buy more tickets. If a person does not have any tickets left to buy, the person will **leave** the line.

Return _the **time taken** for the person at position_ `k` **_(0-indexed)_** _to finish buying tickets_.

**Example 1:**

**Input:** tickets = \[2,3,2\], k = 2
**Output:** 6
**Explanation:**
- In the first pass, everyone in the line buys a ticket and the line becomes \[1, 2, 1\].
- In the second pass, everyone in the line buys a ticket and the line becomes \[0, 1, 0\].
The person at position 2 has successfully bought 2 tickets and it took 3 + 3 = 6 seconds.

**Example 2:**

**Input:** tickets = \[5,1,1,1\], k = 0
**Output:** 8
**Explanation:**
- In the first pass, everyone in the line buys a ticket and the line becomes \[4, 0, 0, 0\].
- In the next 4 passes, only the person in position 0 is buying tickets.
The person at position 0 has successfully bought 5 tickets and it took 4 + 1 + 1 + 1 + 1 = 8 seconds.

**Constraints:**

*   `n == tickets.length`
*   `1 <= n <= 100`
*   `1 <= tickets[i] <= 100`
*   `0 <= k < n`

## A solution in Java

```java
public int timeToBuyTickets(int[] tickets, int k) {
    int time = 0;
    while (tickets[k] > 0) {
        for (int i = 0; i < tickets.length; ++i) {
            if (tickets[i] > 0) {
                --tickets[i];
                ++time;
                if (i == k && tickets[k] == 0) {
                    break;
                }
            }
        }
    }
    return time;
}
```
The algorithm starts with a variable `time` set to 0. It then enters into a loop that will continue until the person at position `k` has bought all their tickets (`tickets[k] > 0`).

Inside the loop, we iterate through each person in the queue. If the person has remaining tickets to buy, we decrement the number of tickets they need to buy (`tickets[i]`), increment the `time` variable, and check if the person is the one at position `k` and has finished buying all their tickets. If so, we break out of the inner loop.

After the person at position `k` has bought all their tickets, the algorithm will exit the outer loop and return the `time` variable.

## A solution in C++

```cpp
int time_to_buy_tickets(vector<int>& tickets, int k) {
    int time = 0;
    while (tickets[k] > 0) {
        for (int i = 0; i < tickets.size(); ++i) {
            if (tickets[i] > 0) {
                --tickets[i];
                ++time;
                if (i == k && tickets[k] == 0) {
                    break;
                }
            }
        }
    }
    return time;
}
```
The algorithm starts with a variable `time` set to 0. It then enters into a loop that will continue until the person at position `k` has bought all their tickets (`tickets[k] > 0`).

Inside the loop, we iterate through each person in the queue. If the person has remaining tickets to buy, we decrement the number of tickets they need to buy (`tickets[i]`), increment the `time` variable, and check if the person is the one at position `k` and has finished buying all their tickets. If so, we break out of the inner loop.

After the person at position `k` has bought all their tickets, the algorithm will exit the outer loop and return the `time` variable.

## A solution in Python

```python
def time_to_buy_tickets(tickets, k):
    time = 0
    while tickets[k] > 0:
        for i in range(len(tickets)):
            if tickets[i] > 0:
                tickets[i] -= 1
                time += 1
                if i == k and tickets[k] == 0:
                    break
    return time
```
The algorithm starts with a variable `time` set to 0. It then enters into a loop that will continue until the person at position `k` has bought all their tickets (`tickets[k] > 0`).

Inside the loop, we iterate through each person in the queue. If the person has remaining tickets to buy, we decrement the number of tickets they need to buy (`tickets[i]`), increment the `time` variable, and check if the person is the one at position `k` and has finished buying all their tickets. If so, we break out of the inner loop.

After the person at position `k` has bought all their tickets, the algorithm will exit the outer loop and return the `time` variable.

## A solution in Javascript

```javascript
function timeToBuyTickets(tickets, k) {
    let time = 0;
    while (tickets[k] > 0) {
        for (let i = 0; i < tickets.length; ++i) {
            if (tickets[i] > 0) {
                --tickets[i];
                ++time;
                if (i === k && tickets[k] === 0) {
                    break;
                }
            }
        }
    }
    return time;
}
```
The algorithm starts with a variable `time` set to 0. It then enters into a loop that will continue until the person at position `k` has bought all their tickets (`tickets[k] > 0`).

Inside the loop, we iterate through each person in the queue. If the person has remaining tickets to buy, we decrement the number of tickets they need to buy (`tickets[i]`), increment the `time` variable, and check if the person is the one at position `k` and has finished buying all their tickets. If so, we break out of the inner loop.

After the person at position `k` has bought all their tickets, the algorithm will exit the outer loop and return the `time` variable.


# Reverse Nodes in Even Length Groups

- slug: reverse-nodes-in-even-length-groups
- difficulty: Medium

You are given the `head` of a linked list.

The nodes in the linked list are **sequentially** assigned to **non-empty** groups whose lengths form the sequence of the natural numbers (`1, 2, 3, 4, ...`). The **length** of a group is the number of nodes assigned to it. In other words,

*   The `1st` node is assigned to the first group.
*   The `2nd` and the `3rd` nodes are assigned to the second group.
*   The `4th`, `5th`, and `6th` nodes are assigned to the third group, and so on.

Note that the length of the last group may be less than or equal to `1 + the length of the second to last group`.

**Reverse** the nodes in each group with an **even** length, and return _the_ `head` _of the modified linked list_.

**Example 1:**

**Input:** head = \[5,2,6,3,9,1,7,3,8,4\]
**Output:** \[5,6,2,3,9,1,4,8,3,7\]
**Explanation:**
- The length of the first group is 1, which is odd, hence no reversal occurs.
- The length of the second group is 2, which is even, hence the nodes are reversed.
- The length of the third group is 3, which is odd, hence no reversal occurs.
- The length of the last group is 4, which is even, hence the nodes are reversed.

**Example 2:**

**Input:** head = \[1,1,0,6\]
**Output:** \[1,0,1,6\]
**Explanation:**
- The length of the first group is 1. No reversal occurs.
- The length of the second group is 2. The nodes are reversed.
- The length of the last group is 1. No reversal occurs.

**Example 3:**

**Input:** head = \[1,1,0,6,5\]
**Output:** \[1,0,1,5,6\]
**Explanation:**
- The length of the first group is 1. No reversal occurs.
- The length of the second group is 2. The nodes are reversed.
- The length of the last group is 2. The nodes are reversed.

**Constraints:**

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

## A solution in Java

```java
public class Solution {
    public ListNode reverseGroup(ListNode head, int k) {
        if (head == null || k == 1) return head;
        ListNode prev = null;
        ListNode cur = head;
        for (int i = 0; i < k; i++) {
            ListNode next = cur.next;
            cur.next = prev;
            prev = cur;
            cur = next;
        }
        head.next = cur;
        return prev;
    }

    public ListNode reverseEvenGroups(ListNode head) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode prev = dummy;
        int n = 0;
        for (ListNode cur = head; cur != null; cur = cur.next)
            n++;
        for (int i = 1, k = 1; n >= 0 && k <= n; i++, k += i) {
            if (i % 2 == 0) {
                ListNode tail = prev.next;
                ListNode next = prev.next;
                for (int j = 0; j < k; j++)
                    next = next.next;
                prev.next = reverseGroup(tail, k);
                tail.next = next;
            }
            n -= k;
            for (int j = 0; j < k && prev != null; j++)
                prev = prev.next;
        }
        return dummy.next;
    }
}
```
We'll create a helper function, `reverseGroup`, to reverse a segment of the linked list of a specified length, starting from the head. This function uses three pointers (prev, cur, next) to reverse the order iteratively.

The main function, `reverseEvenGroups`, takes the head of the linked list and reverses the groups with even length using the helper function. It starts by initializing a dummy node that points to the head, and we calculate the total length of the list, n.

Then, using iterators i and k, we iterate over the linked list while grouping nodes. k is incremented by the current value of i on each iteration, and i is incremented by 1 on each iteration, resulting in groups 1, 2, 3, etc.

We reverse the groups with even length, i.e., if i % 2 == 0, by using the helper function. After reversing, we update the tail's next to point to the next group.

We continue this process until we reach the end of the list, and finally, we return the head of the modified linked list, which is the next of the dummy node.

## A solution in C++

```cpp
class Solution {
public:
    ListNode* reverseGroup(ListNode* head, int k) {
        if (head == nullptr || k == 1) return head;
        ListNode* prev = nullptr;
        ListNode* cur = head;
        for (int i = 0; i < k; i++) {
            ListNode* next = cur->next;
            cur->next = prev;
            prev = cur;
            cur = next;
        }
        head->next = cur;
        return prev;
    }

    ListNode* reverseEvenGroups(ListNode* head) {
        ListNode* dummy = new ListNode(0);
        dummy->next = head;
        ListNode* prev = dummy;
        int n = 0;
        for (ListNode* cur = head; cur != nullptr; cur = cur->next)
            n++;
        for (int i = 1, k = 1; n >= 0 && k <= n; i++, k += i) {
            if (i % 2 == 0) {
                ListNode* tail = prev->next;
                ListNode* next = prev->next;
                for (int j = 0; j < k; j++)
                    next = next->next;
                prev->next = reverseGroup(tail, k);
                tail->next = next;
            }
            n -= k;
            for (int j = 0; j < k && prev != nullptr; j++)
                prev = prev->next;
        }
        return dummy->next;
    }
};
```
We'll create a helper function, `reverseGroup`, to reverse a segment of the linked list of a specified length, starting from the head. This function uses three pointers (prev, cur, next) to reverse the order iteratively.

The main function, `reverseEvenGroups`, takes the head of the linked list and reverses the groups with even length using the helper function. It starts by initializing a dummy node that points to the head, and we calculate the total length of the list, n.

Then, using iterators i and k, we iterate over the linked list while grouping nodes. k is incremented by the current value of i on each iteration, and i is incremented by 1 on each iteration, resulting in groups 1, 2, 3, etc.

We reverse the groups with even length, i.e., if i % 2 == 0, by using the helper function. After reversing, we update the tail's next to point to the next group.

We continue this process until we reach the end of the list, and finally, we return the head of the modified linked list, which is the next of the dummy node.

## A solution in Python

```python
class Solution:
    def reverseGroup(self, head, k):
        if not head or k == 1:
            return head
        prev = None
        cur = head
        for _ in range(k):
            next = cur.next
            cur.next = prev
            prev = cur
            cur = next
        head.next = cur
        return prev

    def reverseEvenGroups(self, head):
        dummy = ListNode(0)
        dummy.next = head
        prev = dummy
        n = 0
        cur = head
        while cur:
            n += 1
            cur = cur.next
        i, k = 1, 1
        while n >= 0 and k <= n:
            if i % 2 == 0:
                tail = prev.next
                next = prev.next
                for _ in range(k):
                    next = next.next
                prev.next = self.reverseGroup(tail, k)
                tail.next = next
            n -= k
            for _ in range(k):
                prev = prev.next
            i += 1
            k += i
        return dummy.next
```
We'll create a helper function, `reverseGroup`, to reverse a segment of the linked list of a specified length, starting from the head. This function uses three pointers (prev, cur, next) to reverse the order iteratively.

The main function, `reverseEvenGroups`, takes the head of the linked list and reverses the groups with even length using the helper function. It starts by initializing a dummy node that points to the head, and we calculate the total length of the list, n.

Then, using iterators i and k, we iterate over the linked list while grouping nodes. k is incremented by the current value of i on each iteration, and i is incremented by 1 on each iteration, resulting in groups 1, 2, 3, etc.

We reverse the groups with even length, i.e., if i % 2 == 0, by using the helper function. After reversing, we update the tail's next to point to the next group.

We continue this process until we reach the end of the list, and finally, we return the head of the modified linked list, which is the next of the dummy node.

## A solution in Javascript

```javascript
class Solution {
    reverseGroup(head, k) {
        if (!head || k === 1) return head;
        let prev = null;
        let cur = head;
        for (let i = 0; i < k; i++) {
            const next = cur.next;
            cur.next = prev;
            prev = cur;
            cur = next;
        }
        head.next = cur;
        return prev;
    }

    reverseEvenGroups(head) {
        const dummy = new ListNode(0);
        dummy.next = head;
        let prev = dummy;
        let n = 0;
        for (let cur = head; cur !== null; cur = cur.next)
            n++;
        for (let i = 1, k = 1; n >= 0 && k <= n; i++, k += i) {
            if (i % 2 === 0) {
                const tail = prev.next;
                let next = prev.next;
                for (let j = 0; j < k; j++)
                    next = next.next;
                prev.next = this.reverseGroup(tail, k);
                tail.next = next;
            }
            n -= k;
            for (let j = 0; j < k && prev !== null; j++)
                prev = prev.next;
        }
        return dummy.next;
    }
}
```
We'll create a helper function, `reverseGroup`, to reverse a segment of the linked list of a specified length, starting from the head. This function uses three pointers (prev, cur, next) to reverse the order iteratively.

The main function, `reverseEvenGroups`, takes the head of the linked list and reverses the groups with even length using the helper function. It starts by initializing a dummy node that points to the head, and we calculate the total length of the list, n.

Then, using iterators i and k, we iterate over the linked list while grouping nodes. k is incremented by the current value of i on each iteration, and i is incremented by 1 on each iteration, resulting in groups 1, 2, 3, etc.

We reverse the groups with even length, i.e., if i % 2 == 0, by using the helper function. After reversing, we update the tail's next to point to the next group.

We continue this process until we reach the end of the list, and finally, we return the head of the modified linked list, which is the next of the dummy node.


# Decode the Slanted Ciphertext

- slug: decode-the-slanted-ciphertext
- difficulty: Medium

A string `originalText` is encoded using a **slanted transposition cipher** to a string `encodedText` with the help of a matrix having a **fixed number of rows** `rows`.

`originalText` is placed first in a top-left to bottom-right manner.

The blue cells are filled first, followed by the red cells, then the yellow cells, and so on, until we reach the end of `originalText`. The arrow indicates the order in which the cells are filled. All empty cells are filled with `' '`. The number of columns is chosen such that the rightmost column will **not be empty** after filling in `originalText`.

`encodedText` is then formed by appending all characters of the matrix in a row-wise fashion.

The characters in the blue cells are appended first to `encodedText`, then the red cells, and so on, and finally the yellow cells. The arrow indicates the order in which the cells are accessed.

For example, if `originalText = "cipher "` and `rows = 3`, then we encode it in the following manner:

The blue arrows depict how `originalText` is placed in the matrix, and the red arrows denote the order in which `encodedText` is formed. In the above example, `encodedText = "ch ie pr "`.

Given the encoded string `encodedText` and number of rows `rows`, return _the original string_ `originalText`.

**Note:** `originalText` **does not** have any trailing spaces `' '`. The test cases are generated such that there is only one possible `originalText`.

**Example 1:**

**Input:** encodedText =  "ch   ie   pr ", rows = 3
**Output:**  "cipher "
**Explanation:** This is the same example described in the problem description.

**Example 2:**

**Input:** encodedText =  "iveo    eed   l te   olc ", rows = 4
**Output:**  "i love leetcode "
**Explanation:** The figure above denotes the matrix that was used to encode originalText.
The blue arrows show how we can find originalText from encodedText.

**Example 3:**

**Input:** encodedText =  "coding ", rows = 1
**Output:**  "coding "
**Explanation:** Since there is only 1 row, both originalText and encodedText are the same.

**Constraints:**

*   `0 <= encodedText.length <= 106`
*   `encodedText` consists of lowercase English letters and `' '` only.
*   `encodedText` is a valid encoding of some `originalText` that **does not** have trailing spaces.
*   `1 <= rows <= 1000`
*   The testcases are generated such that there is **only one** possible `originalText`.

## A solution in Java

```java
public String slanted_transposition_cipher(String encodedText, int rows) {
    if(rows == 1)
        return encodedText;

    int n = encodedText.length();
    int cols = (n + rows - 2) / (rows - 1);
    int pos = 0;
    char[][] matrix = new char[rows][cols];
    for(int k = 0; k < cols; ++k) {
        for(int i = 0; i < rows; ++i) {
            if(k % 2 == 0 || i != 0) {
                matrix[i][k] = encodedText.charAt(pos++);
            }
        }
    }
    StringBuilder originalText = new StringBuilder();
    for(char[] row : matrix) {
        for (char c : row) {
            originalText.append(c);
        }
    }
    return originalText.toString();
}
```
The algorithm works as follows:
1. If there's only 1 row, the original text is the same as the encoded text.
2. Given the length of the encoded text, calculate the number of columns while ensuring the rightmost column is filled completely. This is calculated using the formula: `(n + rows - 2) / (rows - 1)`.
3. Create a matrix with the given number of rows and calculated number of columns.
4. Fill in the matrix by iterating through each row and column. If the current column is even or the current row is not the first row, add the current character of the encodedText at the current matrix position.
5. Iterate through the matrix and append each character to a new string, forming the original text.

## A solution in C++

```cpp
std::string slanted_transposition_cipher(std::string encodedText, int rows) {
    if(rows == 1)
        return encodedText;

    int n = encodedText.size();
    int cols = (n + rows - 2) / (rows - 1);
    int pos = 0;
    std::vector<std::vector<char>> matrix(rows, std::vector<char>(cols, ' '));
    for(int k = 0; k < cols; ++k) {
        for(int i = 0; i < rows; ++i) {
            if(k % 2 == 0 || i != 0) {
                matrix[i][k] = encodedText[pos++];
            }
        }
    }
    std::string originalText;
    for(const auto& row : matrix) {
        originalText += std::string(row.begin(), row.end());
    }
    return originalText;
}
```
The algorithm works as follows:
1. If there's only 1 row, the original text is the same as the encoded text.
2. Given the length of the encoded text, calculate the number of columns while ensuring the rightmost column is filled completely. This is calculated using the formula: `(n + rows - 2) / (rows - 1)`.
3. Create a matrix with the given number of rows and calculated number of columns.
4. Fill in the matrix by iterating through each row and column. If the current column is even or the current row is not the first row, add the current character of the encodedText at the current matrix position.
5. Iterate through the matrix and append each character to a new string, forming the original text.

## A solution in Python

```python
def slanted_transposition_cipher(encodedText, rows):
    if rows == 1:
        return encodedText

    n = len(encodedText)
    cols = (n + rows - 2) // (rows - 1)
    pos = 0
    matrix = [[' ' for col in range(cols)] for row in range(rows)]
    for k in range(cols):
        for i in range(rows):
            if k % 2 == 0 or i != 0:
                matrix[i][k] = encodedText[pos]
                pos += 1

    originalText = ''.join(''.join(row) for row in matrix)

    return originalText
```
The algorithm works as follows:
1. If there's only 1 row, the original text is the same as the encoded text.
2. Given the length of the encoded text, calculate the number of columns while ensuring the rightmost column is filled completely. This is calculated using the formula: `(n + rows - 2) / (rows - 1)`.
3. Create a matrix with the given number of rows and calculated number of columns.
4. Fill in the matrix by iterating through each row and column. If the current column is even or the current row is not the first row, add the current character of the encodedText at the current matrix position.
5. Iterate through the matrix and append each character to a new string, forming the original text.

## A solution in Javascript

```javascript
function slanted_transposition_cipher(encodedText, rows) {
    if(rows === 1)
        return encodedText;

    const n = encodedText.length;
    const cols = Math.floor((n + rows - 2) / (rows - 1));
    let pos = 0;
    const matrix = new Array(rows).fill(null).map(() => new Array(cols).fill(' '));
    for(let k = 0; k < cols; ++k) {
        for(let i = 0; i < rows; ++i) {
            if(k % 2 === 0 || i !== 0) {
                matrix[i][k] = encodedText[pos++];
            }
        }
    }
    let originalText = '';
    for(const row of matrix) {
        originalText += row.join('');
    }
    return originalText;
}
```
The algorithm works as follows:
1. If there's only 1 row, the original text is the same as the encoded text.
2. Given the length of the encoded text, calculate the number of columns while ensuring the rightmost column is filled completely. This is calculated using the formula: `(n + rows - 2) / (rows - 1)`.
3. Create a matrix with the given number of rows and calculated number of columns.
4. Fill in the matrix by iterating through each row and column. If the current column is even or the current row is not the first row, add the current character of the encodedText at the current matrix position.
5. Iterate through the matrix and append each character to a new string, forming the original text.


# Process Restricted Friend Requests

- slug: process-restricted-friend-requests
- difficulty: Hard

You are given an integer `n` indicating the number of people in a network. Each person is labeled from `0` to `n - 1`.

You are also given a **0-indexed** 2D integer array `restrictions`, where `restrictions[i] = [xi, yi]` means that person `xi` and person `yi` **cannot** become **friends**, either **directly** or **indirectly** through other people.

Initially, no one is friends with each other. You are given a list of friend requests as a **0-indexed** 2D integer array `requests`, where `requests[j] = [uj, vj]` is a friend request between person `uj` and person `vj`.

A friend request is **successful** if `uj` and `vj` can be **friends**. Each friend request is processed in the given order (i.e., `requests[j]` occurs before `requests[j + 1]`), and upon a successful request, `uj` and `vj` **become direct friends** for all future friend requests.

Return _a **boolean array**_ `result`, _where each_ `result[j]` _is_ `true` _if the_ `jth` _friend request is **successful** or_ `false` _if it is not_.

**Note:** If `uj` and `vj` are already direct friends, the request is still **successful**.

**Example 1:**

**Input:** n = 3, restrictions = \[\[0,1\]\], requests = \[\[0,2\],\[2,1\]\]
**Output:** \[true,false\]
**Explanation:**
Request 0: Person 0 and person 2 can be friends, so they become direct friends.
Request 1: Person 2 and person 1 cannot be friends since person 0 and person 1 would be indirect friends (1--2--0).

**Example 2:**

**Input:** n = 3, restrictions = \[\[0,1\]\], requests = \[\[1,2\],\[0,2\]\]
**Output:** \[true,false\]
**Explanation:**
Request 0: Person 1 and person 2 can be friends, so they become direct friends.
Request 1: Person 0 and person 2 cannot be friends since person 0 and person 1 would be indirect friends (0--2--1).

**Example 3:**

**Input:** n = 5, restrictions = \[\[0,1\],\[1,2\],\[2,3\]\], requests = \[\[0,4\],\[1,2\],\[3,1\],\[3,4\]\]
**Output:** \[true,false,true,false\]
**Explanation:**
Request 0: Person 0 and person 4 can be friends, so they become direct friends.
Request 1: Person 1 and person 2 cannot be friends since they are directly restricted.
Request 2: Person 3 and person 1 can be friends, so they become direct friends.
Request 3: Person 3 and person 4 cannot be friends since person 0 and person 1 would be indirect friends (0--4--3--1).

**Constraints:**

*   `2 <= n <= 1000`
*   `0 <= restrictions.length <= 1000`
*   `restrictions[i].length == 2`
*   `0 <= xi, yi <= n - 1`
*   `xi != yi`
*   `1 <= requests.length <= 1000`
*   `requests[j].length == 2`
*   `0 <= uj, vj <= n - 1`
*   `uj != vj`

## A solution in Java

```java
int alphabet_position_sum(String s, int k) {
    int sum = 0;
    for (char c : s.toCharArray()) {
        sum += c - 'a' + 1;
    }
    for (int i = 0; i < k; i++) {
        int new_sum = 0;
        while (sum > 0) {
            new_sum += sum % 10;
            sum /= 10;
        }
        sum = new_sum;
    }
    return sum;
}
```
1. Calculate the initial sum by iterating through each character in the string and adding the position of the letter in the alphabet to the sum. The position can be determined by subtracting the ASCII value of 'a' from the character's ASCII value and adding 1 (`c - 'a' + 1`).
2. For `k` number of times, perform the "transform operation" by setting the sum to the sum of its individual digits. This is done by iterating through the number while it's greater than zero, adding the remainder of the number divided by 10 (which gives the last digit) to a new sum variable, and then dividing the number by 10 to remove the last digit. After the loop is done, set the sum variable to the new sum.
3. Return the resulting integer.

## A solution in C++

```cpp
int alphabet_position_sum(const std::string &s, int k) {
    int sum = 0;
    for (char c : s) {
        sum += c - 'a' + 1;
    }
    for (int i = 0; i < k; ++i) {
        int new_sum = 0;
        while (sum > 0) {
            new_sum += sum % 10;
            sum /= 10;
        }
        sum = new_sum;
    }
    return sum;
}
```
1. Calculate the initial sum by iterating through each character in the string and adding the position of the letter in the alphabet to the sum. The position can be determined by subtracting the ASCII value of 'a' from the character's ASCII value and adding 1 (`c - 'a' + 1`).
2. For `k` number of times, perform the "transform operation" by setting the sum to the sum of its individual digits. This is done by iterating through the number while it's greater than zero, adding the remainder of the number divided by 10 (which gives the last digit) to a new sum variable, and then dividing the number by 10 to remove the last digit. After the loop is done, set the sum variable to the new sum.
3. Return the resulting integer.

## A solution in Python

```python
def alphabet_position_sum(s, k):
    sum = 0
    for c in s:
        sum += ord(c) - ord('a') + 1
    for _ in range(k):
        new_sum = 0
        while sum > 0:
            new_sum += sum % 10
            sum //= 10
        sum = new_sum
    return sum
```
1. Calculate the initial sum by iterating through each character in the string and adding the position of the letter in the alphabet to the sum. The position can be determined by subtracting the ASCII value of 'a' from the character's ASCII value and adding 1 (`c - 'a' + 1`).
2. For `k` number of times, perform the "transform operation" by setting the sum to the sum of its individual digits. This is done by iterating through the number while it's greater than zero, adding the remainder of the number divided by 10 (which gives the last digit) to a new sum variable, and then dividing the number by 10 to remove the last digit. After the loop is done, set the sum variable to the new sum.
3. Return the resulting integer.

## A solution in Javascript

```javascript
function alphabet_position_sum(s, k) {
    let sum = 0;
    for (let c of s) {
        sum += c.charCodeAt(0) - 'a'.charCodeAt(0) + 1;
    }
    for (let i = 0; i < k; i++) {
        let new_sum = 0;
        while (sum > 0) {
            new_sum += sum % 10;
            sum = Math.floor(sum / 10);
        }
        sum = new_sum;
    }
    return sum;
}
```
1. Calculate the initial sum by iterating through each character in the string and adding the position of the letter in the alphabet to the sum. The position can be determined by subtracting the ASCII value of 'a' from the character's ASCII value and adding 1 (`c - 'a' + 1`).
2. For `k` number of times, perform the "transform operation" by setting the sum to the sum of its individual digits. This is done by iterating through the number while it's greater than zero, adding the remainder of the number divided by 10 (which gives the last digit) to a new sum variable, and then dividing the number by 10 to remove the last digit. After the loop is done, set the sum variable to the new sum.
3. Return the resulting integer.


# Paths in Maze That Lead to Same Room

- slug: paths-in-maze-that-lead-to-same-room
- difficulty: Medium

A maze consists of `n` rooms numbered from `1` to `n`, and some rooms are connected by corridors. You are given a 2D integer array `corridors` where `corridors[i] = [room1i, room2i]` indicates that there is a corridor connecting `room1i` and `room2i`, allowing a person in the maze to go from `room1i` to `room2i` **and vice versa**.

The designer of the maze wants to know how confusing the maze is. The **confusion** **score** of the maze is the number of different cycles of **length 3**.

*   For example, `1 -> 2 -> 3 -> 1` is a cycle of length 3, but `1 -> 2 -> 3 -> 4` and `1 -> 2 -> 3 -> 2 -> 1` are not.

Two cycles are considered to be **different** if one or more of the rooms visited in the first cycle is **not** in the second cycle.

Return _the_ _**confusion** **score** of the maze._

**Example 1:**

**Input:** n = 5, corridors = \[\[1,2\],\[5,2\],\[4,1\],\[2,4\],\[3,1\],\[3,4\]\]
**Output:** 2
**Explanation:**
One cycle of length 3 is 4 -> 1 -> 3 -> 4, denoted in red.
Note that this is the same cycle as 3 -> 4 -> 1 -> 3 or 1 -> 3 -> 4 -> 1 because the rooms are the same.
Another cycle of length 3 is 1 -> 2 -> 4 -> 1, denoted in blue.
Thus, there are two different cycles of length 3.

**Example 2:**

**Input:** n = 4, corridors = \[\[1,2\],\[3,4\]\]
**Output:** 0
**Explanation:**
There are no cycles of length 3.

**Constraints:**

*   `2 <= n <= 1000`
*   `1 <= corridors.length <= 5 * 104`
*   `corridors[i].length == 2`
*   `1 <= room1i, room2i <= n`
*   `room1i != room2i`
*   There are no duplicate corridors.

## A solution in Java

```java
public String maximumNumber(String num, int[] change) {
    boolean mutatable = false;
    char[] numArray = num.toCharArray();
    for (int i = 0; i < numArray.length; i++) {
        int digit = numArray[i] - '0';
        if (digit < change[digit]) {
            if (!mutatable) mutatable = true;
            numArray[i] = (char) (change[digit] + '0');
        } else if (digit > change[digit] && mutatable) {
            break;
        }
    }
    return new String(numArray);
}
```
1. Convert the input string to a mutable data structure (C++: string, Java: char array, Python: list of characters, JavaScript: array of characters).
2. Initialize a boolean variable `mutatable` to keep track of whether we have started mutating or not.
3. Iterate through the digits of input string `num`.
4. For each digit, compare it to the corresponding value in the `change` array.
5. If the digit is smaller than its corresponding change value and mutatable is false, set mutatable to true, and replace the digit with the change value.
6. If the digit is larger than its corresponding change value and mutatable is true, break the loop because the string is now non-increasing.
7. Convert the mutable data structure back to the string and return it.

## A solution in C++

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

string maximumNumber(string num, vector<int>& change) {
    bool mutatable = false;
    for (int i = 0; i < num.size(); i++) {
        int digit = num[i] - '0';
        if (digit < change[digit]) {
            if (!mutatable) mutatable = true;
            num[i] = change[digit] + '0';
        } else if (digit > change[digit] && mutatable) {
            break;
        }
    }
    return num;
}
```
1. Convert the input string to a mutable data structure (C++: string, Java: char array, Python: list of characters, JavaScript: array of characters).
2. Initialize a boolean variable `mutatable` to keep track of whether we have started mutating or not.
3. Iterate through the digits of input string `num`.
4. For each digit, compare it to the corresponding value in the `change` array.
5. If the digit is smaller than its corresponding change value and mutatable is false, set mutatable to true, and replace the digit with the change value.
6. If the digit is larger than its corresponding change value and mutatable is true, break the loop because the string is now non-increasing.
7. Convert the mutable data structure back to the string and return it.

## A solution in Python

```python
def maximumNumber(num: str, change: List[int]) -> str:
    num = list(num)
    mutatable = False
    for i in range(len(num)):
        digit = int(num[i])
        if digit < change[digit]:
            if not mutatable: mutatable = True
            num[i] = str(change[digit])
        elif digit > change[digit] and mutatable:
            break
    return "".join(num)
```
1. Convert the input string to a mutable data structure (C++: string, Java: char array, Python: list of characters, JavaScript: array of characters).
2. Initialize a boolean variable `mutatable` to keep track of whether we have started mutating or not.
3. Iterate through the digits of input string `num`.
4. For each digit, compare it to the corresponding value in the `change` array.
5. If the digit is smaller than its corresponding change value and mutatable is false, set mutatable to true, and replace the digit with the change value.
6. If the digit is larger than its corresponding change value and mutatable is true, break the loop because the string is now non-increasing.
7. Convert the mutable data structure back to the string and return it.

## A solution in Javascript

```javascript
function maximumNumber(num, change) {
    let mutatable = false;
    let numArray = num.split('');
    for (let i = 0; i < numArray.length; i++) {
        let digit = numArray[i] - '0';
        if (digit < change[digit]) {
            if (!mutatable) mutatable = true;
            numArray[i] = change[digit] + '0';
        } else if (digit > change[digit] && mutatable) {
            break;
        }
    }
    return numArray.join('');
}
```
1. Convert the input string to a mutable data structure (C++: string, Java: char array, Python: list of characters, JavaScript: array of characters).
2. Initialize a boolean variable `mutatable` to keep track of whether we have started mutating or not.
3. Iterate through the digits of input string `num`.
4. For each digit, compare it to the corresponding value in the `change` array.
5. If the digit is smaller than its corresponding change value and mutatable is false, set mutatable to true, and replace the digit with the change value.
6. If the digit is larger than its corresponding change value and mutatable is true, break the loop because the string is now non-increasing.
7. Convert the mutable data structure back to the string and return it.


# Two Furthest Houses With Different Colors

- slug: two-furthest-houses-with-different-colors
- difficulty: Easy

There are `n` houses evenly lined up on the street, and each house is beautifully painted. You are given a **0-indexed** integer array `colors` of length `n`, where `colors[i]` represents the color of the `ith` house.

Return _the **maximum** distance between **two** houses with **different** colors_.

The distance between the `ith` and `jth` houses is `abs(i - j)`, where `abs(x)` is the **absolute value** of `x`.

**Example 1:**

**Input:** colors = \[**1**,1,1,**6**,1,1,1\]
**Output:** 3
**Explanation:** In the above image, color 1 is blue, and color 6 is red.
The furthest two houses with different colors are house 0 and house 3.
House 0 has color 1, and house 3 has color 6. The distance between them is abs(0 - 3) = 3.
Note that houses 3 and 6 can also produce the optimal answer.

**Example 2:**

**Input:** colors = \[**1**,8,3,8,**3**\]
**Output:** 4
**Explanation:** In the above image, color 1 is blue, color 8 is yellow, and color 3 is green.
The furthest two houses with different colors are house 0 and house 4.
House 0 has color 1, and house 4 has color 3. The distance between them is abs(0 - 4) = 4.

**Example 3:**

**Input:** colors = \[**0**,**1**\]
**Output:** 1
**Explanation:** The furthest two houses with different colors are house 0 and house 1.
House 0 has color 0, and house 1 has color 1. The distance between them is abs(0 - 1) = 1.

**Constraints:**

*   `n == colors.length`
*   `2 <= n <= 100`
*   `0 <= colors[i] <= 100`
*   Test data are generated such that **at least** two houses have different colors.

## A solution in Java

```java
import java.util.Arrays;

public int maxCompatibilitySum(int[][] students, int[][] mentors) {
    Arrays.sort(students, (a, b) -> Arrays.toString(a).compareTo(Arrays.toString(b)));
    Arrays.sort(mentors, (a, b) -> Arrays.toString(a).compareTo(Arrays.toString(b)));
    return helper(students, mentors, 0);
}

private int helper(int[][] students, int[][] mentors, int idx) {
    if (idx == students.length)
        return 0;
    int ans = 0;
    for (int i = 0; i < mentors.length; i++) {
        if (mentors[i] != null) {
            int[] temp = mentors[i];
            int count = 0;
            for (int j = 0; j < students[idx].length; j++) {
                if (students[idx][j] == temp[j])
                    count++;
            }
            mentors[i] = null;
            ans = Math.max(ans, count + helper(students, mentors, idx + 1));
            mentors[i] = temp;
        }
    }
    return ans;
}
```
The algorithm first sorts both the students and the mentors arrays. Then, it finds all possible pairings between students and mentors. For each pairing, it calculates the compatibility score by counting the number of matching answers. The sum of the compatibility scores for each pairing is then calculated, and the maximum sum is returned as the final result.

In Python, the itertools.permutations function is used to generate all possible orderings of mentors. In Java, the arrays are sorted using compareTo on the string representation of the array. In JavaScript, the arrays are sorted using the join function to concatenate the array elements for comparison. For all languages, the helper function calculates the compatibility score sum and keeps track of the maximum sum found so far.

## A solution in C++

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

int maxCompatibilitySum(std::vector<std::vector<int>>& students, std::vector<std::vector<int>>& mentors) {
    std::sort(students.begin(), students.end());
    std::sort(mentors.begin(), mentors.end());
    int ans = 0;
    do {
        int cur_sum = 0;
        for (int i = 0; i < students.size(); i++) {
            int match = 0;
            for (int j = 0; j < students[i].size(); j++) {
                if (students[i][j] == mentors[i][j]) match++;
            }
            cur_sum += match;
        }
        ans = std::max(ans, cur_sum);
    } while (std::next_permutation(mentors.begin(), mentors.end()));
    return ans;
}
```
The algorithm first sorts both the students and the mentors arrays. Then, it finds all possible pairings between students and mentors. For each pairing, it calculates the compatibility score by counting the number of matching answers. The sum of the compatibility scores for each pairing is then calculated, and the maximum sum is returned as the final result.

In Python, the itertools.permutations function is used to generate all possible orderings of mentors. In Java, the arrays are sorted using compareTo on the string representation of the array. In JavaScript, the arrays are sorted using the join function to concatenate the array elements for comparison. For all languages, the helper function calculates the compatibility score sum and keeps track of the maximum sum found so far.

## A solution in Python

```python
from itertools import permutations

def maxCompatibilitySum(students, mentors):
    ans = 0
    for mentors_perm in permutations(mentors):
        cur_sum = sum(sum(a == b for a, b in zip(student, mentor)) for student, mentor in zip(students, mentors_perm))
        ans = max(ans, cur_sum)
    return ans
```
The algorithm first sorts both the students and the mentors arrays. Then, it finds all possible pairings between students and mentors. For each pairing, it calculates the compatibility score by counting the number of matching answers. The sum of the compatibility scores for each pairing is then calculated, and the maximum sum is returned as the final result.

In Python, the itertools.permutations function is used to generate all possible orderings of mentors. In Java, the arrays are sorted using compareTo on the string representation of the array. In JavaScript, the arrays are sorted using the join function to concatenate the array elements for comparison. For all languages, the helper function calculates the compatibility score sum and keeps track of the maximum sum found so far.

## A solution in Javascript

```javascript
function maxCompatibilitySum(students, mentors) {
    students.sort((a, b) => a.join("") - b.join(""));
    mentors.sort((a, b) => a.join("") - b.join(""));
    return helper(students, mentors, 0);
}

function helper(students, mentors, idx) {
    if (idx == students.length) {
        return 0;
    }
    let ans = 0;
    for (let i = 0; i < mentors.length; i++) {
        if (mentors[i] !== null) {
            let count = 0;
            let temp = mentors[i];
            for (let j = 0; j < students[idx].length; j++) {
                if (students[idx][j] === temp[j]) {
                    count++;
                }
            }
            mentors[i] = null;
            ans = Math.max(ans, count + helper(students, mentors, idx + 1));
            mentors[i] = temp;
        }
    }
    return ans;
}
```
The algorithm first sorts both the students and the mentors arrays. Then, it finds all possible pairings between students and mentors. For each pairing, it calculates the compatibility score by counting the number of matching answers. The sum of the compatibility scores for each pairing is then calculated, and the maximum sum is returned as the final result.

In Python, the itertools.permutations function is used to generate all possible orderings of mentors. In Java, the arrays are sorted using compareTo on the string representation of the array. In JavaScript, the arrays are sorted using the join function to concatenate the array elements for comparison. For all languages, the helper function calculates the compatibility score sum and keeps track of the maximum sum found so far.


# Watering Plants

- slug: watering-plants
- difficulty: Medium

You want to water `n` plants in your garden with a watering can. The plants are arranged in a row and are labeled from `0` to `n - 1` from left to right where the `ith` plant is located at `x = i`. There is a river at `x = -1` that you can refill your watering can at.

Each plant needs a specific amount of water. You will water the plants in the following way:

*   Water the plants in order from left to right.
*   After watering the current plant, if you do not have enough water to **completely** water the next plant, return to the river to fully refill the watering can.
*   You **cannot** refill the watering can early.

You are initially at the river (i.e., `x = -1`). It takes **one step** to move **one unit** on the x-axis.

Given a **0-indexed** integer array `plants` of `n` integers, where `plants[i]` is the amount of water the `ith` plant needs, and an integer `capacity` representing the watering can capacity, return _the **number of steps** needed to water all the plants_.

**Example 1:**

**Input:** plants = \[2,2,3,3\], capacity = 5
**Output:** 14
**Explanation:** Start at the river with a full watering can:
- Walk to plant 0 (1 step) and water it. Watering can has 3 units of water.
- Walk to plant 1 (1 step) and water it. Watering can has 1 unit of water.
- Since you cannot completely water plant 2, walk back to the river to refill (2 steps).
- Walk to plant 2 (3 steps) and water it. Watering can has 2 units of water.
- Since you cannot completely water plant 3, walk back to the river to refill (3 steps).
- Walk to plant 3 (4 steps) and water it.
Steps needed = 1 + 1 + 2 + 3 + 3 + 4 = 14.

**Example 2:**

**Input:** plants = \[1,1,1,4,2,3\], capacity = 4
**Output:** 30
**Explanation:** Start at the river with a full watering can:
- Water plants 0, 1, and 2 (3 steps). Return to river (3 steps).
- Water plant 3 (4 steps). Return to river (4 steps).
- Water plant 4 (5 steps). Return to river (5 steps).
- Water plant 5 (6 steps).
Steps needed = 3 + 3 + 4 + 4 + 5 + 5 + 6 = 30.

**Example 3:**

**Input:** plants = \[7,7,7,7,7,7,7\], capacity = 8
**Output:** 49
**Explanation:** You have to refill before watering each plant.
Steps needed = 1 + 1 + 2 + 2 + 3 + 3 + 4 + 4 + 5 + 5 + 6 + 6 + 7 = 49.

**Constraints:**

*   `n == plants.length`
*   `1 <= n <= 1000`
*   `1 <= plants[i] <= 106`
*   `max(plants[i]) <= capacity <= 109`

## A solution in Java

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

public List<List<String>> deleteDuplicateFolder(List<List<String>> paths) {
    Map<String, Set<String>> graph = new HashMap<>();
    Map<Set<String>, Integer> count = new HashMap<>();

    for (List<String> path : paths) {
        String serialized_path = "";
        for (String folder : path) {
            serialized_path += "/" + folder;
            graph.putIfAbsent(serialized_path, new HashSet<>());
            graph.get(serialized_path).add(folder);
        }
    }

    for (Set<String> value : graph.values()) {
        count.put(value, count.getOrDefault(value, 0) + 1);
    }

    List<List<String>> ans = new ArrayList<>();
    for (List<String> path : paths) {
        String serialized_path = "";
        boolean duplicate = false;
        for (String folder : path) {
            serialized_path += "/" + folder;
            if (count.get(graph.get(serialized_path)) > 1) {
                duplicate = true;
                break;
            }
        }
        if (!duplicate)
            ans.add(path);
    }

    return ans;
}
```
1. Create an adjacency graph that goes from root to children, counting the number of occurrences of similar subfolders.
2. Iterate through all paths and check if any folders in the path, including the root, have a count greater than 1. If true, mark the path as duplicate.
3. If the path is not marked as duplicate, add it to the ans array.
4. Return the ans array with all the paths remaining after the deletion.

## A solution in C++

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

std::vector<std::vector<std::string>> deleteDuplicateFolder(std::vector<std::vector<std::string>>& paths) {
    std::unordered_map<std::string, std::unordered_set<std::string>> graph;
    std::unordered_map<std::string, int> count;

    for (const auto& path : paths) {
        std::string serialized_path;
        for (const auto& folder : path) {
            serialized_path += "/" + folder;
            graph[serialized_path].insert(folder);
        }
    }

    for (const auto& pair : graph) {
        count[pair.second]++;
    }

    std::vector<std::vector<std::string>> ans;
    for (const auto& path : paths) {
        std::string serialized_path;
        bool duplicate = false;
        for (const auto& folder : path) {
            serialized_path += "/" + folder;
            if (count[graph[serialized_path]] > 1) {
                duplicate = true;
                break;
            }
        }
        if (!duplicate)
            ans.push_back(path);
    }

    return ans;
}
```
1. Create an adjacency graph that goes from root to children, counting the number of occurrences of similar subfolders.
2. Iterate through all paths and check if any folders in the path, including the root, have a count greater than 1. If true, mark the path as duplicate.
3. If the path is not marked as duplicate, add it to the ans array.
4. Return the ans array with all the paths remaining after the deletion.

## A solution in Python

```python
from collections import defaultdict

def deleteDuplicateFolder(paths):
    graph = defaultdict(set)
    count = defaultdict(int)

    for path in paths:
        serialized_path = ""
        for folder in path:
            serialized_path += "/" + folder
            graph[serialized_path].add(folder)

    for value in graph.values():
        count[str(value)] += 1

    ans = []
    for path in paths:
        serialized_path = ""
        duplicate = False
        for folder in path:
            serialized_path += "/" + folder
            if count[str(graph[serialized_path])] > 1:
                duplicate = True
                break
        if not duplicate:
            ans.append(path)

    return ans
```
1. Create an adjacency graph that goes from root to children, counting the number of occurrences of similar subfolders.
2. Iterate through all paths and check if any folders in the path, including the root, have a count greater than 1. If true, mark the path as duplicate.
3. If the path is not marked as duplicate, add it to the ans array.
4. Return the ans array with all the paths remaining after the deletion.

## A solution in Javascript

```javascript
function deleteDuplicateFolder(paths) {
    const graph = new Map();
    const count = new Map();

    for (const path of paths) {
        let serialized_path = "";
        for (const folder of path) {
            serialized_path += "/" + folder;
            if (!graph.has(serialized_path)) {
                graph.set(serialized_path, new Set());
            }
            graph.get(serialized_path).add(folder);
        }
    }

    for (const value of graph.values()) {
        const key = JSON.stringify(Array.from(value));
        count.set(key, (count.get(key) || 0) + 1);
    }

    const ans = [];
    for (const path of paths) {
        let serialized_path = "";
        let duplicate = false;
        for (const folder of path) {
            serialized_path += "/" + folder;
            const key = JSON.stringify(Array.from(graph.get(serialized_path)));
            if (count.get(key) > 1) {
                duplicate = true;
                break;
            }
        }
        if (!duplicate)
            ans.push(path);
    }

    return ans;
}
```
1. Create an adjacency graph that goes from root to children, counting the number of occurrences of similar subfolders.
2. Iterate through all paths and check if any folders in the path, including the root, have a count greater than 1. If true, mark the path as duplicate.
3. If the path is not marked as duplicate, add it to the ans array.
4. Return the ans array with all the paths remaining after the deletion.


# Range Frequency Queries

- slug: range-frequency-queries
- difficulty: Medium

Design a data structure to find the **frequency** of a given value in a given subarray.

The **frequency** of a value in a subarray is the number of occurrences of that value in the subarray.

Implement the `RangeFreqQuery` class:

*   `RangeFreqQuery(int[] arr)` Constructs an instance of the class with the given **0-indexed** integer array `arr`.
*   `int query(int left, int right, int value)` Returns the **frequency** of `value` in the subarray `arr[left...right]`.

A **subarray** is a contiguous sequence of elements within an array. `arr[left...right]` denotes the subarray that contains the elements of `nums` between indices `left` and `right` (**inclusive**).

**Example 1:**

**Input**
\[ "RangeFreqQuery ",  "query ",  "query "\]
\[\[\[12, 33, 4, 56, 22, 2, 34, 33, 22, 12, 34, 56\]\], \[1, 2, 4\], \[0, 11, 33\]\]
**Output**
\[null, 1, 2\]

**Explanation**
RangeFreqQuery rangeFreqQuery = new RangeFreqQuery(\[12, 33, 4, 56, 22, 2, 34, 33, 22, 12, 34, 56\]);
rangeFreqQuery.query(1, 2, 4); // return 1. The value 4 occurs 1 time in the subarray \[33, 4\]
rangeFreqQuery.query(0, 11, 33); // return 2. The value 33 occurs 2 times in the whole array.

**Constraints:**

*   `1 <= arr.length <= 105`
*   `1 <= arr[i], value <= 104`
*   `0 <= left <= right < arr.length`
*   At most `105` calls will be made to `query`

## A solution in Java

```java
public boolean checkGoodLine(char[][] board, int r, int c, char color, int dr, int dc) {
    char oppColor = color == 'W' ? 'B' : 'W';
    int count = 0;
    r += dr;
    c += dc;
    while (r >= 0 && r < 8 && c >= 0 && c < 8 && board[r][c] == oppColor) {
        count++;
        r += dr;
        c += dc;
    }
    return r >= 0 && r < 8 && c >= 0 && c < 8 && board[r][c] == color && count >= 2;
}

public boolean isLegalMove(char[][] board, int rMove, int cMove, char color) {
    if (board[rMove][cMove] != '.') return false;
    board[rMove][cMove] = color;
    for (int dr = -1; dr <= 1; dr++) {
        for (int dc = -1; dc <= 1; dc++) {
            if (!(dr == 0 && dc == 0) && checkGoodLine(board, rMove, cMove, color, dr, dc)) {
                return true;
            }
        }
    }
    return false;
}
```
The algorithm works as follows:

1. Check if the given cell is free, marked by '.'. If not, return false.
2. Change the given cell to the given color (white or black).
3. Iterate through all the neighboring cells in 8 directions (up, down, left, right, and four diagonals).
4. For each direction, use a helper function `check_good_line` which:
    a. Initializes a counter to 0.
    b. Moves in the given direction, checking if the next cell is of the opposite color.
    c. If it is, increment the counter and continue moving in the same direction.
    d. If it's not, break the loop and check if the last cell found is of the same color, and if the counter is greater than or equal to 2.
    e. If so, return true. Otherwise, return false.
5. If any of the directions return true from the helper function, the move is legal, so return true from the main function. Otherwise, return false.

## A solution in C++

```cpp
bool check_good_line(vector<vector<char>>& board, int r, int c, char color, int dr, int dc) {
    char opp_color = color == 'W' ? 'B' : 'W';
    int count = 0;
    r += dr;
    c += dc;
    while (r >= 0 && r < 8 && c >= 0 && c < 8 && board[r][c] == opp_color) {
        count++;
        r += dr;
        c += dc;
    }
    return r >= 0 && r < 8 && c >= 0 && c < 8 && board[r][c] == color && count >= 2;
}

bool is_legal_move(vector<vector<char>>& board, int rMove, int cMove, char(color)) {
    if (board[rMove][cMove] != '.') return false;
    board[rMove][cMove] = color;
    for (int dr = -1; dr <= 1; dr++) {
        for (int dc = -1; dc <= 1; dc++) {
            if (!(dr == 0 && dc == 0) && check_good_line(board, rMove, cMove, color, dr, dc)) {
                return true;
            }
        }
    }
    return false;
}
```
The algorithm works as follows:

1. Check if the given cell is free, marked by '.'. If not, return false.
2. Change the given cell to the given color (white or black).
3. Iterate through all the neighboring cells in 8 directions (up, down, left, right, and four diagonals).
4. For each direction, use a helper function `check_good_line` which:
    a. Initializes a counter to 0.
    b. Moves in the given direction, checking if the next cell is of the opposite color.
    c. If it is, increment the counter and continue moving in the same direction.
    d. If it's not, break the loop and check if the last cell found is of the same color, and if the counter is greater than or equal to 2.
    e. If so, return true. Otherwise, return false.
5. If any of the directions return true from the helper function, the move is legal, so return true from the main function. Otherwise, return false.

## A solution in Python

```python
def check_good_line(board, r, c, color, dr, dc):
    opp_color = 'B' if color == 'W' else 'W'
    count = 0
    r += dr
    c += dc
    while 0 <= r < 8 and 0 <= c < 8 and board[r][c] == opp_color:
        count += 1
        r += dr
        c += dc
    return 0 <= r < 8 and 0 <= c < 8 and board[r][c] == color and count >= 2

def is_legal_move(board, r_move, c_move, color):
    if board[r_move][c_move] != '.':
        return False
    board[r_move][c_move] = color
    for dr in range(-1, 2):
        for dc in range(-1, 2):
            if not (dr == 0 and dc == 0) and check_good_line(board, r_move, c_move, color, dr, dc):
                return True
    return False
```
The algorithm works as follows:

1. Check if the given cell is free, marked by '.'. If not, return false.
2. Change the given cell to the given color (white or black).
3. Iterate through all the neighboring cells in 8 directions (up, down, left, right, and four diagonals).
4. For each direction, use a helper function `check_good_line` which:
    a. Initializes a counter to 0.
    b. Moves in the given direction, checking if the next cell is of the opposite color.
    c. If it is, increment the counter and continue moving in the same direction.
    d. If it's not, break the loop and check if the last cell found is of the same color, and if the counter is greater than or equal to 2.
    e. If so, return true. Otherwise, return false.
5. If any of the directions return true from the helper function, the move is legal, so return true from the main function. Otherwise, return false.

## A solution in Javascript

```javascript
function checkGoodLine(board, r, c, color, dr, dc) {
    let oppColor = color === 'W' ? 'B' : 'W';
    let count = 0;
    r += dr;
    c += dc;
    while (r >= 0 && r < 8 && c >= 0 && c < 8 && board[r][c] === oppColor) {
        count++;
        r += dr;
        c += dc;
    }
    return r >= 0 && r < 8 && c >= 0 && c < 8 && board[r][c] === color && count >= 2;
}

function isLegalMove(board, rMove, cMove, color) {
    if (board[rMove][cMove] !== '.') return false;
    board[rMove][cMove] = color;
    for (let dr = -1; dr <= 1; dr++) {
        for (let dc = -1; dc <= 1; dc++) {
            if (!(dr === 0 && dc === 0) && checkGoodLine(board, rMove, cMove, color, dr, dc)) {
                return true;
            }
        }
    }
    return false;
}
```
The algorithm works as follows:

1. Check if the given cell is free, marked by '.'. If not, return false.
2. Change the given cell to the given color (white or black).
3. Iterate through all the neighboring cells in 8 directions (up, down, left, right, and four diagonals).
4. For each direction, use a helper function `check_good_line` which:
    a. Initializes a counter to 0.
    b. Moves in the given direction, checking if the next cell is of the opposite color.
    c. If it is, increment the counter and continue moving in the same direction.
    d. If it's not, break the loop and check if the last cell found is of the same color, and if the counter is greater than or equal to 2.
    e. If so, return true. Otherwise, return false.
5. If any of the directions return true from the helper function, the move is legal, so return true from the main function. Otherwise, return false.


# Sum of k-Mirror Numbers

- slug: sum-of-k-mirror-numbers
- difficulty: Hard

A **k-mirror number** is a **positive** integer **without leading zeros** that reads the same both forward and backward in base-10 **as well as** in base-k.

*   For example, `9` is a 2-mirror number. The representation of `9` in base-10 and base-2 are `9` and `1001` respectively, which read the same both forward and backward.
*   On the contrary, `4` is not a 2-mirror number. The representation of `4` in base-2 is `100`, which does not read the same both forward and backward.

Given the base `k` and the number `n`, return _the **sum** of the_ `n` _**smallest** k-mirror numbers_.

**Example 1:**

**Input:** k = 2, n = 5
**Output:** 25
**Explanation:**
The 5 smallest 2-mirror numbers and their representations in base-2 are listed as follows:
  base-10    base-2
    1          1
    3          11
    5          101
    7          111
    9          1001
Their sum = 1 + 3 + 5 + 7 + 9 = 25.

**Example 2:**

**Input:** k = 3, n = 7
**Output:** 499
**Explanation:**
The 7 smallest 3-mirror numbers are and their representations in base-3 are listed as follows:
  base-10    base-3
    1          1
    2          2
    4          11
    8          22
    121        11111
    151        12121
    212        21212
Their sum = 1 + 2 + 4 + 8 + 121 + 151 + 212 = 499.

**Example 3:**

**Input:** k = 7, n = 17
**Output:** 20379000
**Explanation:** The 17 smallest 7-mirror numbers are:
1, 2, 3, 4, 5, 6, 8, 121, 171, 242, 292, 16561, 65656, 2137312, 4602064, 6597956, 6958596

**Constraints:**

*   `2 <= k <= 9`
*   `1 <= n <= 30`

## A solution in Java

```java
public int minWastedSpace(int[] nums, int k) {
    int n = nums.length;
    int[][] dp = new int[n + 1][k + 1];
    for(int[] row : dp) Arrays.fill(row, Integer.MAX_VALUE);
    dp[0][0] = 0;

    for(int i = 1; i <= n; ++i) {
        int total = 0;
        for(int j = i; j > 0; --j) {
            total += nums[j - 1];
            for(int l = 0; l < k; ++l) {
                dp[i][l + 1] = Math.min(dp[i][l + 1], dp[j - 1][l] + (i - j + 1) * nums[j - 1] - total);
            }
        }
    }

    int min = dp[n][0];
    for(int s : dp[n]) min = Math.min(min, s);
    return min;
}
```
The algorithm uses dynamic programming to keep track of and minimize the total wasted space for each possible resizing operation. The main idea is to use an n-by-(k+1) table that represents the wasted space given a certain number of resizing operations. At the beginning, the table is initialized with an infinitely large wasted space value to guarantee that every additional resizing operation will lead to a smaller wasted space.

The algorithm then iterates through each possible time step in the nums array and determines the total number of elements to be stored at each given timestep. This information is updated within the nested loop, iterating through each of the previous timesteps and for each possible number of resizing operations.

At each iteration, the algorithm calculates the current wasted space and updates the dynamic programming table with the minimum value for the current resizing operation. In the end, the minimum wasted space given the maximum number of resizing operations can be found in the last column of the dynamic programming table.

## A solution in C++

```cpp
int minWastedSpace(vector<int>& nums, int k) {
    int n = nums.size();
    vector<vector<int>> dp(n + 1, vector<int>(k + 1, INT_MAX));
    dp[0][0] = 0;

    for(int i = 1; i <= n; ++i) {
        int total = 0;
        for(int j = i; j > 0; --j) {
            total += nums[j - 1];
            for(int l = 0; l < k; ++l) {
                dp[i][l + 1] = min(dp[i][l + 1], dp[j - 1][l] + (i - j + 1) * nums[j - 1] - total);
            }
        }
    }

    return *min_element(dp[n].begin(), dp[n].end());
}
```
The algorithm uses dynamic programming to keep track of and minimize the total wasted space for each possible resizing operation. The main idea is to use an n-by-(k+1) table that represents the wasted space given a certain number of resizing operations. At the beginning, the table is initialized with an infinitely large wasted space value to guarantee that every additional resizing operation will lead to a smaller wasted space.

The algorithm then iterates through each possible time step in the nums array and determines the total number of elements to be stored at each given timestep. This information is updated within the nested loop, iterating through each of the previous timesteps and for each possible number of resizing operations.

At each iteration, the algorithm calculates the current wasted space and updates the dynamic programming table with the minimum value for the current resizing operation. In the end, the minimum wasted space given the maximum number of resizing operations can be found in the last column of the dynamic programming table.

## A solution in Python

```python
def minWastedSpace(nums, k):
    n = len(nums)
    dp = [[float('inf')] * (k + 1) for _ in range(n + 1)]
    dp[0][0] = 0

    for i in range(1, n + 1):
        total = 0
        for j in range(i, 0, -1):
            total += nums[j - 1]
            for l in range(k):
                dp[i][l + 1] = min(dp[i][l + 1], dp[j - 1][l] + (i - j + 1) * nums[j - 1] - total)

    return min(dp[n])
```
The algorithm uses dynamic programming to keep track of and minimize the total wasted space for each possible resizing operation. The main idea is to use an n-by-(k+1) table that represents the wasted space given a certain number of resizing operations. At the beginning, the table is initialized with an infinitely large wasted space value to guarantee that every additional resizing operation will lead to a smaller wasted space.

The algorithm then iterates through each possible time step in the nums array and determines the total number of elements to be stored at each given timestep. This information is updated within the nested loop, iterating through each of the previous timesteps and for each possible number of resizing operations.

At each iteration, the algorithm calculates the current wasted space and updates the dynamic programming table with the minimum value for the current resizing operation. In the end, the minimum wasted space given the maximum number of resizing operations can be found in the last column of the dynamic programming table.

## A solution in Javascript

```javascript
function minWastedSpace(nums, k) {
    const n = nums.length;
    const dp = Array.from({length: n + 1}, () => Array(k + 1).fill(Infinity));
    dp[0][0] = 0;

    for(let i = 1; i <= n; ++i) {
        let total = 0;
        for(let j = i; j > 0; --j) {
            total += nums[j - 1];
            for(let l = 0; l < k; ++l) {
                dp[i][l + 1] = Math.min(dp[i][l + 1], dp[j - 1][l] + (i - j + 1) * nums[j - 1] - total);
            }
        }
    }

    return Math.min(...dp[n]);
}
```
The algorithm uses dynamic programming to keep track of and minimize the total wasted space for each possible resizing operation. The main idea is to use an n-by-(k+1) table that represents the wasted space given a certain number of resizing operations. At the beginning, the table is initialized with an infinitely large wasted space value to guarantee that every additional resizing operation will lead to a smaller wasted space.

The algorithm then iterates through each possible time step in the nums array and determines the total number of elements to be stored at each given timestep. This information is updated within the nested loop, iterating through each of the previous timesteps and for each possible number of resizing operations.

At each iteration, the algorithm calculates the current wasted space and updates the dynamic programming table with the minimum value for the current resizing operation. In the end, the minimum wasted space given the maximum number of resizing operations can be found in the last column of the dynamic programming table.


# Substrings That Begin and End With the Same Letter

- slug: substrings-that-begin-and-end-with-the-same-letter
- difficulty: Medium

You are given a **0-indexed** string `s` consisting of only lowercase English letters. Return _the number of **substrings** in_ `s` _that begin and end with the **same** character._

A **substring** is a contiguous non-empty sequence of characters within a string.

**Example 1:**

**Input:** s =  "abcba "
**Output:** 7
**Explanation:**
The substrings of length 1 that start and end with the same letter are:  "a ",  "b ",  "c ",  "b ", and  "a ".
The substring of length 3 that starts and ends with the same letter is:  "bcb ".
The substring of length 5 that starts and ends with the same letter is:  "abcba ".

**Example 2:**

**Input:** s =  "abacad "
**Output:** 9
**Explanation:**
The substrings of length 1 that start and end with the same letter are:  "a ",  "b ",  "a ",  "c ",  "a ", and  "d ".
The substrings of length 3 that start and end with the same letter are:  "aba " and  "aca ".
The substring of length 5 that starts and ends with the same letter is:  "abaca ".

**Example 3:**

**Input:** s =  "a "
**Output:** 1
**Explanation:**
The substring of length 1 that starts and ends with the same letter is:  "a ".

**Constraints:**

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

## A solution in Java

```java
boolean hasThreeDivisors(int n) {
    int count = 0;
    for (int i = 1; i <= Math.sqrt(n); i++) {
        if (n % i == 0) {
            if (n / i == i)
                count++;
            else
                count += 2;
        }
        if (count > 3)
            break;
    }
    return count == 3;
}
```
The algorithm iterates through every integer i from 1 to the square root of n. For each integer i, it checks if n is divisible by i, indicating that i is a divisor of n. If n is divisible by i, the algorithm further calculates n/i, which is the other divisor. If i and n/i are equal, count is incremented by 1; otherwise, count is incremented by 2, as there are two distinct divisors. If the count goes over 3, the loop is broken since we only care about finding exactly three divisors. At the end of the loop, it checks if count is equal to 3, and returns true if it is, otherwise it returns false.

Given an integer n, this algorithm will return true if n has exactly three positive divisors, otherwise, it will return false.

## A solution in C++

```cpp
bool hasThreeDivisors(int n) {
    int count = 0;
    for (int i = 1; i <= sqrt(n); i++) {
        if (n % i == 0) {
            if (n / i == i)
                count++;
            else
                count += 2;
        }
        if (count > 3)
            break;
    }
    return count == 3;
}
```
The algorithm iterates through every integer i from 1 to the square root of n. For each integer i, it checks if n is divisible by i, indicating that i is a divisor of n. If n is divisible by i, the algorithm further calculates n/i, which is the other divisor. If i and n/i are equal, count is incremented by 1; otherwise, count is incremented by 2, as there are two distinct divisors. If the count goes over 3, the loop is broken since we only care about finding exactly three divisors. At the end of the loop, it checks if count is equal to 3, and returns true if it is, otherwise it returns false.

Given an integer n, this algorithm will return true if n has exactly three positive divisors, otherwise, it will return false.

## A solution in Python

```python
def has_three_divisors(n):
    count = 0
    for i in range(1, int(n**0.5) + 1):
        if n % i == 0:
            if n // i == i:
                count += 1
            else:
                count += 2
        if count > 3:
            break
    return count == 3
```
The algorithm iterates through every integer i from 1 to the square root of n. For each integer i, it checks if n is divisible by i, indicating that i is a divisor of n. If n is divisible by i, the algorithm further calculates n/i, which is the other divisor. If i and n/i are equal, count is incremented by 1; otherwise, count is incremented by 2, as there are two distinct divisors. If the count goes over 3, the loop is broken since we only care about finding exactly three divisors. At the end of the loop, it checks if count is equal to 3, and returns true if it is, otherwise it returns false.

Given an integer n, this algorithm will return true if n has exactly three positive divisors, otherwise, it will return false.

## A solution in Javascript

```javascript
function hasThreeDivisors(n) {
    let count = 0;
    for (let i = 1; i <= Math.sqrt(n); i++) {
        if (n % i === 0) {
            if (n / i === i)
                count++;
            else
                count += 2;
        }
        if (count > 3)
            break;
    }
    return count === 3;
}
```
The algorithm iterates through every integer i from 1 to the square root of n. For each integer i, it checks if n is divisible by i, indicating that i is a divisor of n. If n is divisible by i, the algorithm further calculates n/i, which is the other divisor. If i and n/i are equal, count is incremented by 1; otherwise, count is incremented by 2, as there are two distinct divisors. If the count goes over 3, the loop is broken since we only care about finding exactly three divisors. At the end of the loop, it checks if count is equal to 3, and returns true if it is, otherwise it returns false.

Given an integer n, this algorithm will return true if n has exactly three positive divisors, otherwise, it will return false.


# Count Common Words With One Occurrence

- slug: count-common-words-with-one-occurrence
- difficulty: Easy

Given two string arrays `words1` and `words2`, return _the number of strings that appear **exactly once** in **each** of the two arrays._

**Example 1:**

**Input:** words1 = \[ "leetcode ", "is ", "amazing ", "as ", "is "\], words2 = \[ "amazing ", "leetcode ", "is "\]
**Output:** 2
**Explanation:**
-  "leetcode " appears exactly once in each of the two arrays. We count this string.
-  "amazing " appears exactly once in each of the two arrays. We count this string.
-  "is " appears in each of the two arrays, but there are 2 occurrences of it in words1. We do not count this string.
-  "as " appears once in words1, but does not appear in words2. We do not count this string.
Thus, there are 2 strings that appear exactly once in each of the two arrays.

**Example 2:**

**Input:** words1 = \[ "b ", "bb ", "bbb "\], words2 = \[ "a ", "aa ", "aaa "\]
**Output:** 0
**Explanation:** There are no strings that appear in each of the two arrays.

**Example 3:**

**Input:** words1 = \[ "a ", "ab "\], words2 = \[ "a ", "a ", "a ", "ab "\]
**Output:** 1
**Explanation:** The only string that appears exactly once in each of the two arrays is  "ab ".

**Constraints:**

*   `1 <= words1.length, words2.length <= 1000`
*   `1 <= words1[i].length, words2[j].length <= 30`
*   `words1[i]` and `words2[j]` consists only of lowercase English letters.

## A solution in Java

```java
import java.util.Arrays;

public int[] rearrangeArray(int[] nums) {
    Arrays.sort(nums);
    for (int i = 1; i < nums.length - 1; i += 2) {
        int temp = nums[i];
        nums[i] = nums[i + 1];
        nums[i + 1] = temp;
    }
    return nums;
}
```

    The algorithm first sorts the array. Then, we swap every two adjacent elements starting from the first index until the end of the array. By doing this, we can ensure that no element will be equal to the average of its neighbors, as the elements are distinct integers and the property described in the problem cannot hold after swapping.

For example, let's take the following array:

```
3 1 5 9 7
```

Sort the array:

```
1 3 5 7 9
```

Swap every two adjacent elements starting from the first index:

```
1 5 3 9 7
```
Now we can observe that no element in the array is equal to the average of its neighbors.

## A solution in C++

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

std::vector<int> rearrangeArray(std::vector<int>& nums) {
    std::sort(nums.begin(), nums.end());
    for (int i = 1; i < nums.size() - 1; i += 2) {
        std::swap(nums[i], nums[i + 1]);
    }
    return nums;
}
```

    The algorithm first sorts the array. Then, we swap every two adjacent elements starting from the first index until the end of the array. By doing this, we can ensure that no element will be equal to the average of its neighbors, as the elements are distinct integers and the property described in the problem cannot hold after swapping.

For example, let's take the following array:

```
3 1 5 9 7
```

Sort the array:

```
1 3 5 7 9
```

Swap every two adjacent elements starting from the first index:

```
1 5 3 9 7
```
Now we can observe that no element in the array is equal to the average of its neighbors.

## A solution in Python

```python
def rearrangeArray(nums):
    nums.sort()
    for i in range(1, len(nums) - 1, 2):
        nums[i], nums[i + 1] = nums[i + 1], nums[i]
    return nums
```

    The algorithm first sorts the array. Then, we swap every two adjacent elements starting from the first index until the end of the array. By doing this, we can ensure that no element will be equal to the average of its neighbors, as the elements are distinct integers and the property described in the problem cannot hold after swapping.

For example, let's take the following array:

```
3 1 5 9 7
```

Sort the array:

```
1 3 5 7 9
```

Swap every two adjacent elements starting from the first index:

```
1 5 3 9 7
```
Now we can observe that no element in the array is equal to the average of its neighbors.

## A solution in Javascript

```javascript
function rearrangeArray(nums) {
    nums.sort((a, b) => a - b);
    for (let i = 1; i < nums.length - 1; i += 2) {
        [nums[i], nums[i + 1]] = [nums[i + 1], nums[i]];
    }
    return nums;
}
```

    The algorithm first sorts the array. Then, we swap every two adjacent elements starting from the first index until the end of the array. By doing this, we can ensure that no element will be equal to the average of its neighbors, as the elements are distinct integers and the property described in the problem cannot hold after swapping.

For example, let's take the following array:

```
3 1 5 9 7
```

Sort the array:

```
1 3 5 7 9
```

Swap every two adjacent elements starting from the first index:

```
1 5 3 9 7
```
Now we can observe that no element in the array is equal to the average of its neighbors.