# Minimum Time to Eat All Grains

- slug: minimum-time-to-eat-all-grains
- difficulty: Hard

There are `n` hens and `m` grains on a line. You are given the initial positions of the hens and the grains in two integer arrays `hens` and `grains` of size `n` and `m` respectively.

Any hen can eat a grain if they are on the same position. The time taken for this is negligible. One hen can also eat multiple grains.

In `1` second, a hen can move right or left by `1` unit. The hens can move simultaneously and independently of each other.

Return _the **minimum** time to eat all grains if the hens act optimally._

**Example 1:**

**Input:** hens = \[3,6,7\], grains = \[2,4,7,9\]
**Output:** 2
**Explanation:**
One of the ways hens eat all grains in 2 seconds is described below:
- The first hen eats the grain at position 2 in 1 second.
- The second hen eats the grain at position 4 in 2 seconds.
- The third hen eats the grains at positions 7 and 9 in 2 seconds.
So, the maximum time needed is 2.
It can be proven that the hens cannot eat all grains before 2 seconds.

**Example 2:**

**Input:** hens = \[4,6,109,111,213,215\], grains = \[5,110,214\]
**Output:** 1
**Explanation:**
One of the ways hens eat all grains in 1 second is described below:
- The first hen eats the grain at position 5 in 1 second.
- The fourth hen eats the grain at position 110 in 1 second.
- The sixth hen eats the grain at position 214 in 1 second.
- The other hens do not move.
So, the maximum time needed is 1.

**Constraints:**

*   `1 <= hens.length, grains.length <= 2*104`
*   `0 <= hens[i], grains[j] <= 109`

## A solution in Java

```java
import java.util.Arrays;

public int minTimeToEatGrains(int[] hens, int[] grains) {
    Arrays.sort(hens);
    Arrays.sort(grains);
    int left = 0, right = 1_000_000_000;

    while (left < right) {
        int mid = left + (right - left) / 2;
        boolean can_eat = true;
        int i = 0;

        for (int grain : grains) {
            if (i >= hens.length) {
                can_eat = false;
                break;
            }

            while (i < hens.length && hens[i] < grain - mid) {
                ++i;
            }

            if (i >= hens.length || hens[i] > grain + mid) {
                can_eat = false;
                break;
            }

            ++i;
        }

        if (can_eat) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }

    return left;
}
```
The algorithm uses a binary search between the minimum time (0) and the maximum possible time (10^9) to determine the minimum time required for the hens to eat all the grains. We first sort both the hens and the grains arrays to make it convenient for comparison. Inside the while loop, we simulate if all the grains can be eaten within the given mid value (current time). If true, then we can reduce the time; else, we increase the time. We iterate through the grains and hens and increment the counter by checking if the ith hen can eat the current grain within the mid seconds. If not, we move to the next hen. If none of the hens can eat the grain within mid seconds or there are not enough hens left, then can_eat is set to false, which indicates that the current mid value is not enough.

Finally, we return the left value, which represents the minimum time required for hens to eat all the grains.

## A solution in C++

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

int minTimeToEatGrains(std::vector<int>& hens, std::vector<int>& grains) {
    std::sort(hens.begin(), hens.end());
    std::sort(grains.begin(), grains.end());
    int left = 0, right = 1e9;

    while (left < right) {
        int mid = left + (right - left) / 2;
        bool can_eat = true;
        int i = 0;

        for (int grain : grains) {
            if (i >= hens.size()) {
                can_eat = false;
                break;
            }

            while (i < hens.size() && hens[i] < grain - mid) {
                ++i;
            }

            if (i >= hens.size() || hens[i] > grain + mid) {
                can_eat = false;
                break;
            }

            ++i;
        }

        if (can_eat) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }

    return left;
}
```
The algorithm uses a binary search between the minimum time (0) and the maximum possible time (10^9) to determine the minimum time required for the hens to eat all the grains. We first sort both the hens and the grains arrays to make it convenient for comparison. Inside the while loop, we simulate if all the grains can be eaten within the given mid value (current time). If true, then we can reduce the time; else, we increase the time. We iterate through the grains and hens and increment the counter by checking if the ith hen can eat the current grain within the mid seconds. If not, we move to the next hen. If none of the hens can eat the grain within mid seconds or there are not enough hens left, then can_eat is set to false, which indicates that the current mid value is not enough.

Finally, we return the left value, which represents the minimum time required for hens to eat all the grains.

## A solution in Python

```python
def min_time_to_eat_grains(hens, grains):
    hens.sort()
    grains.sort()
    left, right = 0, 10**9

    while left < right:
        mid = left + (right - left) // 2
        can_eat = True
        i = 0

        for grain in grains:
            if i >= len(hens):
                can_eat = False
                break

            while i < len(hens) and hens[i] < grain - mid:
                i += 1

            if i >= len(hens) or hens[i] > grain + mid:
                can_eat = False
                break

            i += 1

        if can_eat:
            right = mid
        else:
            left = mid + 1

    return left
```
The algorithm uses a binary search between the minimum time (0) and the maximum possible time (10^9) to determine the minimum time required for the hens to eat all the grains. We first sort both the hens and the grains arrays to make it convenient for comparison. Inside the while loop, we simulate if all the grains can be eaten within the given mid value (current time). If true, then we can reduce the time; else, we increase the time. We iterate through the grains and hens and increment the counter by checking if the ith hen can eat the current grain within the mid seconds. If not, we move to the next hen. If none of the hens can eat the grain within mid seconds or there are not enough hens left, then can_eat is set to false, which indicates that the current mid value is not enough.

Finally, we return the left value, which represents the minimum time required for hens to eat all the grains.

## A solution in Javascript

```javascript
function minTimeToEatGrains(hens, grains) {
    hens.sort((a, b) => a - b);
    grains.sort((a, b) => a - b);

    let left = 0, right = 1000000000;

    while (left < right) {
        let mid = Math.floor(left + (right - left) / 2);
        let can_eat = true;
        let i = 0;

        for (let grain of grains) {
            if (i >= hens.length) {
                can_eat = false;
                break;
            }

            while (i < hens.length && hens[i] < grain - mid) {
                ++i;
            }

            if (i >= hens.length || hens[i] > grain + mid) {
                can_eat = false;
                break;
            }

            ++i;
        }

        if (can_eat) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }

    return left;
}
```
The algorithm uses a binary search between the minimum time (0) and the maximum possible time (10^9) to determine the minimum time required for the hens to eat all the grains. We first sort both the hens and the grains arrays to make it convenient for comparison. Inside the while loop, we simulate if all the grains can be eaten within the given mid value (current time). If true, then we can reduce the time; else, we increase the time. We iterate through the grains and hens and increment the counter by checking if the ith hen can eat the current grain within the mid seconds. If not, we move to the next hen. If none of the hens can eat the grain within mid seconds or there are not enough hens left, then can_eat is set to false, which indicates that the current mid value is not enough.

Finally, we return the left value, which represents the minimum time required for hens to eat all the grains.


# Form Smallest Number From Two Digit Arrays

- slug: form-smallest-number-from-two-digit-arrays
- difficulty: Easy

Given two arrays of **unique** digits `nums1` and `nums2`, return _the **smallest** number that contains **at least** one digit from each array_.

**Example 1:**

**Input:** nums1 = \[4,1,3\], nums2 = \[5,7\]
**Output:** 15
**Explanation:** The number 15 contains the digit 1 from nums1 and the digit 5 from nums2. It can be proven that 15 is the smallest number we can have.

**Example 2:**

**Input:** nums1 = \[3,5,2,6\], nums2 = \[3,1,7\]
**Output:** 3
**Explanation:** The number 3 contains the digit 3 which exists in both arrays.

**Constraints:**

*   `1 <= nums1.length, nums2.length <= 9`
*   `1 <= nums1[i], nums2[i] <= 9`
*   All digits in each array are **unique**.

## A solution in Java

```java
public int smallestNumberWithAtLeastOneDigitFromEachArray(int[] nums1, int[] nums2) {
    int min1 = Arrays.stream(nums1).min().getAsInt();
    int min2 = Arrays.stream(nums2).min().getAsInt();
    for (int num1 : nums1) {
        for (int num2 : nums2) {
            if (num1 == num2) {
                return num1;
            }
        }
    }
    return min1 * 10 + min2;
}
```
The algorithm works as follows:
1. Find the smallest numbers `min1` and `min2` in each input array `nums1` and `nums2` respectively.
2. Check if there is any identical number `num1` and `num2` in `nums1` and `nums2` respectively (`num1 == num2`). If found, return that shared number. This is because the problem states that we need the smallest number that contains at least one digit from each array, and a shared number will always be smaller than the result obtained by concatenating the smallest digits from each array (due to the unique digits constraint in the problem statement).
3. If no shared number is found, concatenate the smallest numbers of each array (`min1 * 10 + min2`). This gives the smallest possible number containing at least one digit from each array.

## A solution in C++

```cpp
int smallestNumberWithAtLeastOneDigitFromEachArray(vector<int>& nums1, vector<int>& nums2) {
    int min1 = *min_element(nums1.begin(), nums1.end());
    int min2 = *min_element(nums2.begin(), nums2.end());
    for (int num1 : nums1) {
        for (int num2 : nums2) {
            if (num1 == num2) {
                return num1;
            }
        }
    }
    return min1 * 10 + min2;
}
```
The algorithm works as follows:
1. Find the smallest numbers `min1` and `min2` in each input array `nums1` and `nums2` respectively.
2. Check if there is any identical number `num1` and `num2` in `nums1` and `nums2` respectively (`num1 == num2`). If found, return that shared number. This is because the problem states that we need the smallest number that contains at least one digit from each array, and a shared number will always be smaller than the result obtained by concatenating the smallest digits from each array (due to the unique digits constraint in the problem statement).
3. If no shared number is found, concatenate the smallest numbers of each array (`min1 * 10 + min2`). This gives the smallest possible number containing at least one digit from each array.

## A solution in Python

```python
def smallest_number_with_at_least_one_digit_from_each_array(nums1, nums2):
    min1 = min(nums1)
    min2 = min(nums2)
    for num1 in nums1:
        for num2 in nums2:
            if num1 == num2:
                return num1
    return min1 * 10 + min2
```
The algorithm works as follows:
1. Find the smallest numbers `min1` and `min2` in each input array `nums1` and `nums2` respectively.
2. Check if there is any identical number `num1` and `num2` in `nums1` and `nums2` respectively (`num1 == num2`). If found, return that shared number. This is because the problem states that we need the smallest number that contains at least one digit from each array, and a shared number will always be smaller than the result obtained by concatenating the smallest digits from each array (due to the unique digits constraint in the problem statement).
3. If no shared number is found, concatenate the smallest numbers of each array (`min1 * 10 + min2`). This gives the smallest possible number containing at least one digit from each array.

## A solution in Javascript

```javascript
function smallestNumberWithAtLeastOneDigitFromEachArray(nums1, nums2) {
    const min1 = Math.min(...nums1);
    const min2 = Math.min(...nums2);
    for (const num1 of nums1) {
        for (const num2 of nums2) {
            if (num1 === num2) {
                return num1;
            }
        }
    }
    return min1 * 10 + min2;
}
```
The algorithm works as follows:
1. Find the smallest numbers `min1` and `min2` in each input array `nums1` and `nums2` respectively.
2. Check if there is any identical number `num1` and `num2` in `nums1` and `nums2` respectively (`num1 == num2`). If found, return that shared number. This is because the problem states that we need the smallest number that contains at least one digit from each array, and a shared number will always be smaller than the result obtained by concatenating the smallest digits from each array (due to the unique digits constraint in the problem statement).
3. If no shared number is found, concatenate the smallest numbers of each array (`min1 * 10 + min2`). This gives the smallest possible number containing at least one digit from each array.


# Find the Substring With Maximum Cost

- slug: find-the-substring-with-maximum-cost
- difficulty: Medium

You are given a string `s`, a string `chars` of **distinct** characters and an integer array `vals` of the same length as `chars`.

The **cost of the substring** is the sum of the values of each character in the substring. The cost of an empty string is considered `0`.

The **value of the character** is defined in the following way:

*   If the character is not in the string `chars`, then its value is its corresponding position **(1-indexed)** in the alphabet.
    *   For example, the value of `'a'` is `1`, the value of `'b'` is `2`, and so on. The value of `'z'` is `26`.
*   Otherwise, assuming `i` is the index where the character occurs in the string `chars`, then its value is `vals[i]`.

Return _the maximum cost among all substrings of the string_ `s`.

**Example 1:**

**Input:** s =  "adaa ", chars =  "d ", vals = \[-1000\]
**Output:** 2
**Explanation:** The value of the characters  "a " and  "d " is 1 and -1000 respectively.
The substring with the maximum cost is  "aa " and its cost is 1 + 1 = 2.
It can be proven that 2 is the maximum cost.

**Example 2:**

**Input:** s =  "abc ", chars =  "abc ", vals = \[-1,-1,-1\]
**Output:** 0
**Explanation:** The value of the characters  "a ",  "b " and  "c " is -1, -1, and -1 respectively.
The substring with the maximum cost is the empty substring  " " and its cost is 0.
It can be proven that 0 is the maximum cost.

**Constraints:**

*   `1 <= s.length <= 105`
*   `s` consist of lowercase English letters.
*   `1 <= chars.length <= 26`
*   `chars` consist of **distinct** lowercase English letters.
*   `vals.length == chars.length`
*   `-1000 <= vals[i] <= 1000`

## A solution in Java

```java
public int maxValueSubstring(String s, String chars, int[] vals) {
    Map<Character, Integer> values = new HashMap<>();

    for (int i = 0; i < chars.length(); i++) {
        values.put(chars.charAt(i), vals[i]);
    }

    int max_cost = 0;
    int cost = 0;

    for (char c : s.toCharArray()) {
        int value = values.containsKey(c) ? values.get(c) : (c - 'a' + 1);

        cost = Math.max(0, cost + value);
        max_cost = Math.max(max_cost, cost);
    }

    return max_cost;
}
```
1. Create a dictionary (hash_map/hash_table) to store the custom values of the characters provided in 'chars' and 'vals'.
2. Initialize variables 'max_cost' and 'cost' to 0.
3. Iterate through each character in the input string 's'.
4. Inside the loop, calculate the value of the current character
   - If it is in the custom values dictionary, use the custom value.
   - If it is not in the custom values dictionary, use the position of the character in the alphabet (1-indexed).
5. Update the cost by adding the value: `cost = max(0, cost + value)`. By setting it to max, we are taking into account the largest continuous substring cost.
6. Update the max_cost with the maximum value between the current max_cost and the current cost.
7. Return the max_cost after the loop ends.

## A solution in C++

```cpp
int maxValueSubstring(std::string s, std::string chars, std::vector<int> vals) {
    std::unordered_map<char, int> values;

    for (int i = 0; i < chars.length(); i++) {
        values[chars[i]] = vals[i];
    }

    int max_cost = 0;
    int cost = 0;

    for (char c : s) {
        int value = values.count(c) ? values[c] : static_cast<int>(c - 'a' + 1);

        cost = std::max(0, cost + value);
        max_cost = std::max(max_cost, cost);
    }

    return max_cost;
}
```
1. Create a dictionary (hash_map/hash_table) to store the custom values of the characters provided in 'chars' and 'vals'.
2. Initialize variables 'max_cost' and 'cost' to 0.
3. Iterate through each character in the input string 's'.
4. Inside the loop, calculate the value of the current character
   - If it is in the custom values dictionary, use the custom value.
   - If it is not in the custom values dictionary, use the position of the character in the alphabet (1-indexed).
5. Update the cost by adding the value: `cost = max(0, cost + value)`. By setting it to max, we are taking into account the largest continuous substring cost.
6. Update the max_cost with the maximum value between the current max_cost and the current cost.
7. Return the max_cost after the loop ends.

## A solution in Python

```python
def max_value_substring(s, chars, vals):
    values = {key: val for key, val in zip(chars, vals)}

    max_cost = 0
    cost = 0

    for c in s:
        value = values.get(c) if c in values else ord(c) - ord('a') + 1

        cost = max(0, cost + value)
        max_cost = max(max_cost, cost)

    return max_cost
```
1. Create a dictionary (hash_map/hash_table) to store the custom values of the characters provided in 'chars' and 'vals'.
2. Initialize variables 'max_cost' and 'cost' to 0.
3. Iterate through each character in the input string 's'.
4. Inside the loop, calculate the value of the current character
   - If it is in the custom values dictionary, use the custom value.
   - If it is not in the custom values dictionary, use the position of the character in the alphabet (1-indexed).
5. Update the cost by adding the value: `cost = max(0, cost + value)`. By setting it to max, we are taking into account the largest continuous substring cost.
6. Update the max_cost with the maximum value between the current max_cost and the current cost.
7. Return the max_cost after the loop ends.

## A solution in Javascript

```javascript
function maxValueSubstring(s, chars, vals) {
    let values = {};

    for (let i = 0; i < chars.length; i++) {
        values[chars[i]] = vals[i];
    }

    let max_cost = 0;
    let cost = 0;

    for (let c of s) {
        let value = c in values ? values[c] : (c.charCodeAt(0) - 'a'.charCodeAt(0) + 1);

        cost = Math.max(0, cost + value);
        max_cost = Math.max(max_cost, cost);
    }

    return max_cost;
}
```
1. Create a dictionary (hash_map/hash_table) to store the custom values of the characters provided in 'chars' and 'vals'.
2. Initialize variables 'max_cost' and 'cost' to 0.
3. Iterate through each character in the input string 's'.
4. Inside the loop, calculate the value of the current character
   - If it is in the custom values dictionary, use the custom value.
   - If it is not in the custom values dictionary, use the position of the character in the alphabet (1-indexed).
5. Update the cost by adding the value: `cost = max(0, cost + value)`. By setting it to max, we are taking into account the largest continuous substring cost.
6. Update the max_cost with the maximum value between the current max_cost and the current cost.
7. Return the max_cost after the loop ends.


# Make K-Subarray Sums Equal

- slug: make-k-subarray-sums-equal
- difficulty: Medium

You are given a **0-indexed** integer array `arr` and an integer `k`. The array `arr` is circular. In other words, the first element of the array is the next element of the last element, and the last element of the array is the previous element of the first element.

You can do the following operation any number of times:

*   Pick any element from `arr` and increase or decrease it by `1`.

Return _the minimum number of operations such that the sum of each **subarray** of length_ `k` _is equal_.

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

**Example 1:**

**Input:** arr = \[1,4,1,3\], k = 2
**Output:** 1
**Explanation:** we can do one operation on index 1 to make its value equal to 3.
The array after the operation is \[1,3,1,3\]
- Subarray starts at index 0 is \[1, 3\], and its sum is 4
- Subarray starts at index 1 is \[3, 1\], and its sum is 4
- Subarray starts at index 2 is \[1, 3\], and its sum is 4
- Subarray starts at index 3 is \[3, 1\], and its sum is 4

**Example 2:**

**Input:** arr = \[2,5,5,7\], k = 3
**Output:** 5
**Explanation:** we can do three operations on index 0 to make its value equal to 5 and two operations on index 3 to make its value equal to 5.
The array after the operations is \[5,5,5,5\]
- Subarray starts at index 0 is \[5, 5, 5\], and its sum is 15
- Subarray starts at index 1 is \[5, 5, 5\], and its sum is 15
- Subarray starts at index 2 is \[5, 5, 5\], and its sum is 15
- Subarray starts at index 3 is \[5, 5, 5\], and its sum is 15

**Constraints:**

*   `1 <= k <= arr.length <= 105`
*   `1 <= arr[i] <= 109`

## A solution in Java

```java
public int minOperations(int[] arr, int k) {
    int n = arr.length, res = Integer.MAX_VALUE;
    int[] prefix = new int[n + 1];

    for (int i = 1; i <= n; i++) {
        prefix[i] = prefix[i - 1] + arr[i - 1];
    }

    for (int i = 1; i <= n - k + 1; i++) {
        int target = (prefix[i - 1] + prefix[n] - prefix[i + k - 1] + n / k - 1) / (n / k);
        int curr_cost = 0;
        for (int j = i; j < i + k; j++) {
            curr_cost += Math.abs(arr[j - 1] - target);
        }
        res = Math.min(res, curr_cost);
    }
    return res;
}
```
1. Compute the prefix sum `prefix` of the input array `arr`.
2. Iterate through all possible starting indices i of the subarrays with length k, and for each i:
   a. Calculate the target value (sum of the elements of the subarray) by dividing the sum of the elements not in the current subarray by the number of remaining subarrays (n/k).
   b. Calculate the cost (number of operations) to make the current subarray have a sum equal to the target value by adding the absolute difference of each element in the subarray and the target value.
   c. Update the result with the minimum cost (number of operations) seen so far.
3. Return the minimum cost (number of operations).

## A solution in C++

```cpp
int minOperations(vector<int>& arr, int k) {
    int n = arr.size(), res = INT_MAX;
    vector<int> prefix(n + 1);

    for (int i = 1; i <= n; i++) {
        prefix[i] = prefix[i - 1] + arr[i - 1];
    }

    for (int i = 1; i <= n - k + 1; i++) {
        int target = (prefix[i - 1] + prefix[n] - prefix[i + k - 1] + n / k - 1) / (n / k);
        int curr_cost = 0;
        for (int j = i; j < i + k; j++) {
            curr_cost += abs(arr[j - 1] - target);
        }
        res = min(res, curr_cost);
    }
    return res;
}
```
1. Compute the prefix sum `prefix` of the input array `arr`.
2. Iterate through all possible starting indices i of the subarrays with length k, and for each i:
   a. Calculate the target value (sum of the elements of the subarray) by dividing the sum of the elements not in the current subarray by the number of remaining subarrays (n/k).
   b. Calculate the cost (number of operations) to make the current subarray have a sum equal to the target value by adding the absolute difference of each element in the subarray and the target value.
   c. Update the result with the minimum cost (number of operations) seen so far.
3. Return the minimum cost (number of operations).

## A solution in Python

```python
def minOperations(arr: List[int], k: int) -> int:
    n = len(arr)
    res = float('inf')
    prefix = [0] * (n + 1)

    for i in range(1, n + 1):
        prefix[i] = prefix[i - 1] + arr[i - 1]

    for i in range(1, n - k + 2):
        target = (prefix[i - 1] + prefix[n] - prefix[i + k - 1] + n // k - 1) // (n // k)
        curr_cost = 0
        for j in range(i, i + k):
            curr_cost += abs(arr[j - 1] - target)
        res = min(res, curr_cost)

    return res
```
1. Compute the prefix sum `prefix` of the input array `arr`.
2. Iterate through all possible starting indices i of the subarrays with length k, and for each i:
   a. Calculate the target value (sum of the elements of the subarray) by dividing the sum of the elements not in the current subarray by the number of remaining subarrays (n/k).
   b. Calculate the cost (number of operations) to make the current subarray have a sum equal to the target value by adding the absolute difference of each element in the subarray and the target value.
   c. Update the result with the minimum cost (number of operations) seen so far.
3. Return the minimum cost (number of operations).

## A solution in Javascript

```javascript
function minOperations(arr, k) {
    let n = arr.length;
    let res = Number.MAX_SAFE_INTEGER;
    let prefix = new Array(n + 1).fill(0);

    for (let i = 1; i <= n; i++) {
        prefix[i] = prefix[i - 1] + arr[i - 1];
    }

    for (let i = 1; i <= n - k + 1; i++) {
        let target = Math.floor((prefix[i - 1] + prefix[n] - prefix[i + k - 1] + n / k - 1) / (n / k));
        let curr_cost = 0;
        for (let j = i; j < i + k; j++) {
            curr_cost += Math.abs(arr[j - 1] - target);
        }
        res = Math.min(res, curr_cost);
    }
    return res;
}
```
1. Compute the prefix sum `prefix` of the input array `arr`.
2. Iterate through all possible starting indices i of the subarrays with length k, and for each i:
   a. Calculate the target value (sum of the elements of the subarray) by dividing the sum of the elements not in the current subarray by the number of remaining subarrays (n/k).
   b. Calculate the cost (number of operations) to make the current subarray have a sum equal to the target value by adding the absolute difference of each element in the subarray and the target value.
   c. Update the result with the minimum cost (number of operations) seen so far.
3. Return the minimum cost (number of operations).


# Shortest Cycle in a Graph

- slug: shortest-cycle-in-a-graph
- difficulty: Hard

There is a **bi-directional** graph with `n` vertices, where each vertex is labeled from `0` to `n - 1`. The edges in the graph are represented by a given 2D integer array `edges`, where `edges[i] = [ui, vi]` denotes an edge between vertex `ui` and vertex `vi`. Every vertex pair is connected by at most one edge, and no vertex has an edge to itself.

Return _the length of the **shortest** cycle in the graph_. If no cycle exists, return `-1`.

A cycle is a path that starts and ends at the same node, and each edge in the path is used only once.

**Example 1:**

**Input:** n = 7, edges = \[\[0,1\],\[1,2\],\[2,0\],\[3,4\],\[4,5\],\[5,6\],\[6,3\]\]
**Output:** 3
**Explanation:** The cycle with the smallest length is : 0 -> 1 -> 2 -> 0

**Example 2:**

**Input:** n = 4, edges = \[\[0,1\],\[0,2\]\]
**Output:** -1
**Explanation:** There are no cycles in this graph.

**Constraints:**

*   `2 <= n <= 1000`
*   `1 <= edges.length <= 1000`
*   `edges[i].length == 2`
*   `0 <= ui, vi < n`
*   `ui != vi`
*   There are no repeated edges.

## A solution in Java

```java
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

public int shortestCycleLength(int n, int[][] edges) {
    ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
    for (int i = 0; i < n; ++i) {
        graph.add(new ArrayList<>());
    }
    for (int[] edge : edges) {
        graph.get(edge[0]).add(edge[1]);
        graph.get(edge[1]).add(edge[0]);
    }

    int shortestCycle = n + 1;
    for (int start = 0; start < n; ++start) {
        int[] dist = new int[n];
        for (int i = 0; i < n; ++i) {
            dist[i] = n + 1;
        }
        dist[start] = 0;
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(start);

        while (!queue.isEmpty()) {
            int cur = queue.poll();
            for (int neigh : graph.get(cur)) {
                if (dist[neigh] == n + 1) {
                    dist[neigh] = dist[cur] + 1;
                    queue.offer(neigh);
                } else if (dist[neigh] >= dist[cur] - 1) {
                    shortestCycle = Math.min(shortestCycle, dist[cur] + dist[neigh] + 1);
                }
            }
        }
    }

    return shortestCycle == n + 1 ? -1 : shortestCycle;
}
```
The algorithm starts by creating an adjacency list to represent the input graph. Then, it applies a Breadth-First Search (BFS) traversal from each of the `n` vertices. The BFS maintains an array `dist` representing the distance from the starting vertex `start`.

During the BFS traversal, if we encounter a node that has a greater distance than the `dist[cur] - 1`, it implies that there is a cycle in the graph. In this case, we update the shortest cycle found till now with the value `dist[cur] + dist[neigh] + 1`.

Once the traversal is completed for all the vertices, we return the shortest cycle found. If no cycle was found, we return -1.

## A solution in C++

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

using namespace std;

int shortestCycleLength(int n, vector<vector<int>>& edges) {
    vector<vector<int>> graph(n);
    for (const vector<int>& edge : edges) {
        graph[edge[0]].push_back(edge[1]);
        graph[edge[1]].push_back(edge[0]);
    }

    int shortestCycle = n + 1;
    for (int start = 0; start < n; ++start) {
        vector<int> dist(n, n + 1);
        dist[start] = 0;
        queue<int> q;
        q.push(start);

        while (!q.empty()) {
            int cur = q.front();
            q.pop();
            for (int neigh : graph[cur]) {
                if (dist[neigh] == n + 1) {
                    dist[neigh] = dist[cur] + 1;
                    q.push(neigh);
                } else if (dist[neigh] >= dist[cur] - 1) {
                    shortestCycle = min(shortestCycle, dist[cur] + dist[neigh] + 1);
                }
            }
        }
    }

    return shortestCycle == n + 1 ? -1 : shortestCycle;
}
```
The algorithm starts by creating an adjacency list to represent the input graph. Then, it applies a Breadth-First Search (BFS) traversal from each of the `n` vertices. The BFS maintains an array `dist` representing the distance from the starting vertex `start`.

During the BFS traversal, if we encounter a node that has a greater distance than the `dist[cur] - 1`, it implies that there is a cycle in the graph. In this case, we update the shortest cycle found till now with the value `dist[cur] + dist[neigh] + 1`.

Once the traversal is completed for all the vertices, we return the shortest cycle found. If no cycle was found, we return -1.

## A solution in Python

```python
from collections import deque

def shortest_cycle_length(n, edges):
    graph = [[] for _ in range(n)]
    for u, v in edges:
        graph[u].append(v)
        graph[v].append(u)

    shortest_cycle = n + 1
    for start in range(n):
        dist = [n + 1] * n
        dist[start] = 0
        queue = deque([start])

        while queue:
            cur = queue.popleft()
            for neigh in graph[cur]:
                if dist[neigh] == n + 1:
                    dist[neigh] = dist[cur] + 1
                    queue.append(neigh)
                elif dist[neigh] >= dist[cur] - 1:
                    shortest_cycle = min(shortest_cycle, dist[cur] + dist[neigh] + 1)

    return -1 if shortest_cycle == n + 1 else shortest_cycle
```
The algorithm starts by creating an adjacency list to represent the input graph. Then, it applies a Breadth-First Search (BFS) traversal from each of the `n` vertices. The BFS maintains an array `dist` representing the distance from the starting vertex `start`.

During the BFS traversal, if we encounter a node that has a greater distance than the `dist[cur] - 1`, it implies that there is a cycle in the graph. In this case, we update the shortest cycle found till now with the value `dist[cur] + dist[neigh] + 1`.

Once the traversal is completed for all the vertices, we return the shortest cycle found. If no cycle was found, we return -1.

## A solution in Javascript

```javascript
function shortestCycleLength(n, edges) {
    const graph = Array.from({ length: n }, () => []);
    for (const [u, v] of edges) {
        graph[u].push(v);
        graph[v].push(u);
    }

    let shortestCycle = n + 1;
    for (let start = 0; start < n; ++start) {
        const dist = new Array(n).fill(n + 1);
        dist[start] = 0;
        const queue = [start];

        while (queue.length) {
            const cur = queue.shift();
            for (const neigh of graph[cur]) {
                if (dist[neigh] === n + 1) {
                    dist[neigh] = dist[cur] + 1;
                    queue.push(neigh);
                } else if (dist[neigh] >= dist[cur] - 1) {
                    shortestCycle = Math.min(shortestCycle, dist[cur] + dist[neigh] + 1);
                }
            }
        }
    }

    return shortestCycle === n + 1 ? -1 : shortestCycle;
}
```
The algorithm starts by creating an adjacency list to represent the input graph. Then, it applies a Breadth-First Search (BFS) traversal from each of the `n` vertices. The BFS maintains an array `dist` representing the distance from the starting vertex `start`.

During the BFS traversal, if we encounter a node that has a greater distance than the `dist[cur] - 1`, it implies that there is a cycle in the graph. In this case, we update the shortest cycle found till now with the value `dist[cur] + dist[neigh] + 1`.

Once the traversal is completed for all the vertices, we return the shortest cycle found. If no cycle was found, we return -1.


# Find the Longest Balanced Substring of a Binary String

- slug: find-the-longest-balanced-substring-of-a-binary-string
- difficulty: Easy

You are given a binary string `s` consisting only of zeroes and ones.

A substring of `s` is considered balanced if **all zeroes are before ones** and the number of zeroes is equal to the number of ones inside the substring. Notice that the empty substring is considered a balanced substring.

Return _the length of the longest balanced substring of_ `s`.

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

**Example 1:**

**Input:** s =  "01000111 "
**Output:** 6
**Explanation:** The longest balanced substring is  "000111 ", which has length 6.

**Example 2:**

**Input:** s =  "00111 "
**Output:** 4
**Explanation:** The longest balanced substring is  "0011 ", which has length 4.

**Example 3:**

**Input:** s =  "111 "
**Output:** 0
**Explanation:** There is no balanced substring except the empty substring, so the answer is 0.

**Constraints:**

*   `1 <= s.length <= 50`
*   `'0' <= s[i] <= '1'`

## A solution in Java

```java
public int longestBalancedSubstring(String s) {
    int max_len = 0;
    int zeros = 0;
    int ones = 0;
    for (int i = 0; i < s.length(); ++i) {
        if (s.charAt(i) == '0') {
            zeros++;
        } else {
            ones++;
        }
        if (zeros == ones) {
            max_len = Math.max(max_len, zeros * 2);
        } else if (zeros > ones) {
            zeros = ones = 0;
        }
    }
    zeros = ones = 0;
    for (int i = s.length() - 1; i >= 0; --i) {
        if (s.charAt(i) == '0') {
            zeros++;
        } else {
            ones++;
        }
        if (zeros == ones) {
            max_len = Math.max(max_len, zeros * 2);
        } else if (zeros < ones) {
            zeros = ones = 0;
        }
    }
    return max_len;
}
```
The algorithm scans the string `s` twice. In the first pass, it counts the number of zeros and ones.
1. Whenever the count of zeros and ones is the same, the maximum length of the balanced substring should be updated by selecting the maximum value between `max_len` and `zeros * 2`.
2. If the count of zeros is greater than the count of ones, the current possibility of a balanced substring has failed, so `zeros` and `ones` are reset to 0.

In the second pass, the process is almost the same, but this time it iterates from the end of the string to the beginning. When the count of ones is greater than the count of zeros, `zeros` and `ones` are reset to 0.

After the two passes, the variable `max_len` stores the length of the longest balanced substring in the input string `s`.

## A solution in C++

```cpp
int longestBalancedSubstring(string s) {
    int max_len = 0;
    int zeros = 0;
    int ones = 0;
    for (int i = 0; i < s.size(); ++i) {
        if (s[i] == '0') {
            zeros++;
        } else {
            ones++;
        }
        if (zeros == ones) {
            max_len = max(max_len, zeros * 2);
        } else if (zeros > ones) {
            zeros = ones = 0;
        }
    }
    zeros = ones = 0;
    for (int i = s.size() - 1; i >= 0; --i) {
        if (s[i] == '0') {
            zeros++;
        } else {
            ones++;
        }
        if (zeros == ones) {
            max_len = max(max_len, zeros * 2);
        } else if (zeros < ones) {
            zeros = ones = 0;
        }
    }
    return max_len;
}
```
The algorithm scans the string `s` twice. In the first pass, it counts the number of zeros and ones.
1. Whenever the count of zeros and ones is the same, the maximum length of the balanced substring should be updated by selecting the maximum value between `max_len` and `zeros * 2`.
2. If the count of zeros is greater than the count of ones, the current possibility of a balanced substring has failed, so `zeros` and `ones` are reset to 0.

In the second pass, the process is almost the same, but this time it iterates from the end of the string to the beginning. When the count of ones is greater than the count of zeros, `zeros` and `ones` are reset to 0.

After the two passes, the variable `max_len` stores the length of the longest balanced substring in the input string `s`.

## A solution in Python

```python
def longestBalancedSubstring(s):
    max_len = 0
    zeros = ones = 0
    for c in s:
        if c == '0':
            zeros += 1
        else:
            ones += 1
        if zeros == ones:
            max_len = max(max_len, zeros * 2)
        elif zeros > ones:
            zeros = ones = 0
    zeros = ones = 0
    for c in reversed(s):
        if c == '0':
            zeros += 1
        else:
            ones += 1
        if zeros == ones:
            max_len = max(max_len, zeros * 2)
        elif zeros < ones:
            zeros = ones = 0
    return max_len
```
The algorithm scans the string `s` twice. In the first pass, it counts the number of zeros and ones.
1. Whenever the count of zeros and ones is the same, the maximum length of the balanced substring should be updated by selecting the maximum value between `max_len` and `zeros * 2`.
2. If the count of zeros is greater than the count of ones, the current possibility of a balanced substring has failed, so `zeros` and `ones` are reset to 0.

In the second pass, the process is almost the same, but this time it iterates from the end of the string to the beginning. When the count of ones is greater than the count of zeros, `zeros` and `ones` are reset to 0.

After the two passes, the variable `max_len` stores the length of the longest balanced substring in the input string `s`.

## A solution in Javascript

```javascript
function longestBalancedSubstring(s) {
    let max_len = 0;
    let zeros = 0;
    let ones = 0;
    for (const c of s) {
        if (c === '0') {
            zeros++;
        } else {
            ones++;
        }
        if (zeros === ones) {
            max_len = Math.max(max_len, zeros * 2);
        } else if (zeros > ones) {
            zeros = ones = 0;
        }
    }
    zeros = ones = 0;
    for (let i = s.length - 1; i >= 0; --i) {
        if (s[i] === '0') {
            zeros++;
        } else {
            ones++;
        }
        if (zeros === ones) {
            max_len = Math.max(max_len, zeros * 2);
        } else if (zeros < ones) {
            zeros = ones = 0;
        }
    }
    return max_len;
}
```
The algorithm scans the string `s` twice. In the first pass, it counts the number of zeros and ones.
1. Whenever the count of zeros and ones is the same, the maximum length of the balanced substring should be updated by selecting the maximum value between `max_len` and `zeros * 2`.
2. If the count of zeros is greater than the count of ones, the current possibility of a balanced substring has failed, so `zeros` and `ones` are reset to 0.

In the second pass, the process is almost the same, but this time it iterates from the end of the string to the beginning. When the count of ones is greater than the count of zeros, `zeros` and `ones` are reset to 0.

After the two passes, the variable `max_len` stores the length of the longest balanced substring in the input string `s`.


# Convert an Array Into a 2D Array With Conditions

- slug: convert-an-array-into-a-2d-array-with-conditions
- difficulty: Medium

You are given an integer array `nums`. You need to create a 2D array from `nums` satisfying the following conditions:

*   The 2D array should contain **only** the elements of the array `nums`.
*   Each row in the 2D array contains **distinct** integers.
*   The number of rows in the 2D array should be **minimal**.

Return _the resulting array_. If there are multiple answers, return any of them.

**Note** that the 2D array can have a different number of elements on each row.

**Example 1:**

**Input:** nums = \[1,3,4,1,2,3,1\]
**Output:** \[\[1,3,4,2\],\[1,3\],\[1\]\]
**Explanation:** We can create a 2D array that contains the following rows:
- 1,3,4,2
- 1,3
- 1
All elements of nums were used, and each row of the 2D array contains distinct integers, so it is a valid answer.
It can be shown that we cannot have less than 3 rows in a valid array.

**Example 2:**

**Input:** nums = \[1,2,3,4\]
**Output:** \[\[4,3,2,1\]\]
**Explanation:** All elements of the array are distinct, so we can keep all of them in the first row of the 2D array.

**Constraints:**

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

## A solution in Java

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

public List<List<Integer>> distinctRowsFrom(int[] nums) {
    List<HashSet<Integer>> rows = new ArrayList<>();

    for(int num : nums) {
        boolean inserted = false;
        for(HashSet<Integer> row : rows) {
            if(!row.contains(num)) {
                row.add(num);
                inserted = true;
                break;
            }
        }

        if(!inserted) {
            HashSet<Integer> newRow = new HashSet<>();
            newRow.add(num);
            rows.add(newRow);
        }
    }

    List<List<Integer>> result = new ArrayList<>();
    for (HashSet<Integer> row : rows) {
        result.add(new ArrayList<Integer>(row));
    }

    return result;
}
```
The algorithm iterates through the input array (`nums`). For each number in `nums`, it checks if the number can be inserted in any existing row in the result without violating the distinct condition. If yes, it inserts the number in the first available row; if not, it creates a new row with that number. Finally, it converts the sets containing distinct numbers into arrays/Lists and returns the resulting 2D array.

The time complexity of this algorithm is O(n^2), where n is the length of the input array `nums`. In the worst case, every number in `nums` would need to be inserted in a separate row, resulting in n separate iterations for each number. However, in practice, the algorithm's performance is usually better than the worst-case scenario.

## A solution in C++

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

std::vector<std::vector<int>> distinctRowsFrom(nums std::vector<int>& nums) {
    std::vector<std::unordered_set<int>> rows;

    for(int num : nums) {
        bool inserted = false;
        for(auto& row : rows) {
            if(row.find(num) == row.end()) {
                row.insert(num);
                inserted = true;
                break;
            }
        }

        if(!inserted) rows.push_back({num});
    }

    std::vector<std::vector<int>> result;
    for(auto& row : rows) {
        result.emplace_back(row.begin(), row.end());
    }

    return result;
}
```
The algorithm iterates through the input array (`nums`). For each number in `nums`, it checks if the number can be inserted in any existing row in the result without violating the distinct condition. If yes, it inserts the number in the first available row; if not, it creates a new row with that number. Finally, it converts the sets containing distinct numbers into arrays/Lists and returns the resulting 2D array.

The time complexity of this algorithm is O(n^2), where n is the length of the input array `nums`. In the worst case, every number in `nums` would need to be inserted in a separate row, resulting in n separate iterations for each number. However, in practice, the algorithm's performance is usually better than the worst-case scenario.

## A solution in Python

```python
def distinct_rows_from(nums):
    rows = []

    for num in nums:
        inserted = False
        for row in rows:
            if num not in row:
                row.add(num)
                inserted = True
                break

        if not inserted:
            rows.append({num})

    return [list(row) for row in rows]
```
The algorithm iterates through the input array (`nums`). For each number in `nums`, it checks if the number can be inserted in any existing row in the result without violating the distinct condition. If yes, it inserts the number in the first available row; if not, it creates a new row with that number. Finally, it converts the sets containing distinct numbers into arrays/Lists and returns the resulting 2D array.

The time complexity of this algorithm is O(n^2), where n is the length of the input array `nums`. In the worst case, every number in `nums` would need to be inserted in a separate row, resulting in n separate iterations for each number. However, in practice, the algorithm's performance is usually better than the worst-case scenario.

## A solution in Javascript

```javascript
function distinctRowsFrom(nums) {
    const rows = [];

    for(const num of nums) {
        let inserted = false;
        for(const row of rows) {
            if(!row.has(num)) {
                row.add(num);
                inserted = true;
                break;
            }
        }

        if(!inserted) rows.push(new Set([num]));
    }

    return rows.map(row => Array.from(row));
}
```
The algorithm iterates through the input array (`nums`). For each number in `nums`, it checks if the number can be inserted in any existing row in the result without violating the distinct condition. If yes, it inserts the number in the first available row; if not, it creates a new row with that number. Finally, it converts the sets containing distinct numbers into arrays/Lists and returns the resulting 2D array.

The time complexity of this algorithm is O(n^2), where n is the length of the input array `nums`. In the worst case, every number in `nums` would need to be inserted in a separate row, resulting in n separate iterations for each number. However, in practice, the algorithm's performance is usually better than the worst-case scenario.


# Mice and Cheese

- slug: mice-and-cheese
- difficulty: Medium

There are two mice and `n` different types of cheese, each type of cheese should be eaten by exactly one mouse.

A point of the cheese with index `i` (**0-indexed**) is:

*   `reward1[i]` if the first mouse eats it.
*   `reward2[i]` if the second mouse eats it.

You are given a positive integer array `reward1`, a positive integer array `reward2`, and a non-negative integer `k`.

Return _**the maximum** points the mice can achieve if the first mouse eats exactly_ `k` _types of cheese._

**Example 1:**

**Input:** reward1 = \[1,1,3,4\], reward2 = \[4,4,1,1\], k = 2
**Output:** 15
**Explanation:** In this example, the first mouse eats the 2nd (0-indexed) and the 3rd types of cheese, and the second mouse eats the 0th and the 1st types of cheese.
The total points are 4 + 4 + 3 + 4 = 15.
It can be proven that 15 is the maximum total points that the mice can achieve.

**Example 2:**

**Input:** reward1 = \[1,1\], reward2 = \[1,1\], k = 2
**Output:** 2
**Explanation:** In this example, the first mouse eats the 0th (0-indexed) and 1st types of cheese, and the second mouse does not eat any cheese.
The total points are 1 + 1 = 2.
It can be proven that 2 is the maximum total points that the mice can achieve.

**Constraints:**

*   `1 <= n == reward1.length == reward2.length <= 105`
*   `1 <= reward1[i], reward2[i] <= 1000`
*   `0 <= k <= n`

## A solution in Java

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

public int maxPoints(int[] reward1, int[] reward2, int k) {
    List<Pair<Integer, Integer>> gap = new ArrayList<>();
    for (int i = 0; i < reward1.length; ++i) {
        gap.add(new Pair<>(reward2[i] - reward1[i], i));
    }
    Collections.sort(gap, Comparator.reverseOrder());
    int firstMousePoints = 0;
    int secondMousePoints = 0;
    for (int i = 0; i < k; ++i) {
        firstMousePoints += reward1[gap.get(i).getValue()];
    }
    for (int i = k; i < reward1.length; ++i) {
        secondMousePoints += reward2[gap.get(i).getValue()];
    }
    return firstMousePoints + secondMousePoints;
}
```
1. For each type of cheese, calculate the difference between reward2 and reward1. Store it as `gap` as (difference, index) pairs in a list.
2. Sort the `gap` list in descending order based on the difference values.
3. Initialize variables `firstMousePoints` and `secondMousePoints` to store the points earned by the first and second mouse.
4. Iterate over the first `k` elements in the sorted `gap` list and increment `firstMousePoints` by the corresponding reward1 value at the index taken from the pair.
5. Iterate over the remaining `n-k` elements in the sorted `gap` list and increment `secondMousePoints` by the corresponding reward2 value at the index taken from the pair.
6. Return the sum of `firstMousePoints` and `secondMousePoints` as the final answer.

## A solution in C++

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

int maxPoints(const std::vector<int>& reward1, const std::vector<int>& reward2, int k) {
    std::vector<std::pair<int, int>> gap(reward1.size());
    for (size_t i = 0; i < reward1.size(); ++i) {
        gap[i] = {reward2[i] - reward1[i], i};
    }
    std::sort(gap.rbegin(), gap.rend());
    int firstMousePoints = 0;
    int secondMousePoints = 0;
    for (int i = 0; i < k; ++i) {
        firstMousePoints += reward1[gap[i].second];
    }
    for (int i = k; i < reward1.size(); ++i) {
        secondMousePoints += reward2[gap[i].second];
    }
    return firstMousePoints + secondMousePoints;
}
```
1. For each type of cheese, calculate the difference between reward2 and reward1. Store it as `gap` as (difference, index) pairs in a list.
2. Sort the `gap` list in descending order based on the difference values.
3. Initialize variables `firstMousePoints` and `secondMousePoints` to store the points earned by the first and second mouse.
4. Iterate over the first `k` elements in the sorted `gap` list and increment `firstMousePoints` by the corresponding reward1 value at the index taken from the pair.
5. Iterate over the remaining `n-k` elements in the sorted `gap` list and increment `secondMousePoints` by the corresponding reward2 value at the index taken from the pair.
6. Return the sum of `firstMousePoints` and `secondMousePoints` as the final answer.

## A solution in Python

```python
def maxPoints(reward1, reward2, k):
    gap = sorted([(reward2[i] - reward1[i], i) for i in range(len(reward1))], reverse=True)
    firstMousePoints = sum(reward1[gap[i][1]] for i in range(k))
    secondMousePoints = sum(reward2[gap[i][1]] for i in range(k, len(reward1)))
    return firstMousePoints + secondMousePoints
```
1. For each type of cheese, calculate the difference between reward2 and reward1. Store it as `gap` as (difference, index) pairs in a list.
2. Sort the `gap` list in descending order based on the difference values.
3. Initialize variables `firstMousePoints` and `secondMousePoints` to store the points earned by the first and second mouse.
4. Iterate over the first `k` elements in the sorted `gap` list and increment `firstMousePoints` by the corresponding reward1 value at the index taken from the pair.
5. Iterate over the remaining `n-k` elements in the sorted `gap` list and increment `secondMousePoints` by the corresponding reward2 value at the index taken from the pair.
6. Return the sum of `firstMousePoints` and `secondMousePoints` as the final answer.

## A solution in Javascript

```javascript
function maxPoints(reward1, reward2, k) {
    let gap = reward1.map((value, index) => ({ diff: reward2[index] - value, index })).sort((a, b) => b.diff - a.diff);
    let firstMousePoints = 0;
    let secondMousePoints = 0;
    for (let i = 0; i < k; ++i) {
        firstMousePoints += reward1[gap[i].index];
    }
    for (let i = k; i < reward1.length; ++i) {
        secondMousePoints += reward2[gap[i].index];
    }
    return firstMousePoints + secondMousePoints;
}
```
1. For each type of cheese, calculate the difference between reward2 and reward1. Store it as `gap` as (difference, index) pairs in a list.
2. Sort the `gap` list in descending order based on the difference values.
3. Initialize variables `firstMousePoints` and `secondMousePoints` to store the points earned by the first and second mouse.
4. Iterate over the first `k` elements in the sorted `gap` list and increment `firstMousePoints` by the corresponding reward1 value at the index taken from the pair.
5. Iterate over the remaining `n-k` elements in the sorted `gap` list and increment `secondMousePoints` by the corresponding reward2 value at the index taken from the pair.
6. Return the sum of `firstMousePoints` and `secondMousePoints` as the final answer.


# Minimum Reverse Operations

- slug: minimum-reverse-operations
- difficulty: Hard

You are given an integer `n` and an integer `p` in the range `[0, n - 1]`. Representing a **0-indexed** array `arr` of length `n` where all positions are set to `0`'s, except position `p` which is set to `1`.

You are also given an integer array `banned` containing some positions from the array. For the **i****th** position in `banned`, `arr[banned[i]] = 0`, and `banned[i] != p`.

You can perform **multiple** operations on `arr`. In an operation, you can choose a **subarray** with size `k` and **reverse** the subarray. However, the `1` in `arr` should never go to any of the positions in `banned`. In other words, after each operation `arr[banned[i]]` **remains** `0`.

_Return an array_ `ans` _where_ _for each_ `i` _from_ `[0, n - 1]`, `ans[i]` _is the **minimum** number of reverse operations needed to bring the_ `1` _to position_ `i` _in arr_, _or_ `-1` _if it is impossible_.

*   A **subarray** is a contiguous **non-empty** sequence of elements within an array.
*   The values of `ans[i]` are independent for all `i`'s.
*   The **reverse** of an array is an array containing the values in **reverse order**.

**Example 1:**

**Input:** n = 4, p = 0, banned = \[1,2\], k = 4
**Output:** \[0,-1,-1,1\]
**Explanation:** In this case `k = 4` so there is only one possible reverse operation we can perform, which is reversing the whole array. Initially, 1 is placed at position 0 so the amount of operations we need for position 0 is `0`. We can never place a 1 on the banned positions, so the answer for positions 1 and 2 is `-1`. Finally, with one reverse operation we can bring the 1 to index 3, so the answer for position 3 is `1`.

**Example 2:**

**Input:** n = 5, p = 0, banned = \[2,4\], k = 3
**Output:** \[0,-1,-1,-1,-1\]
**Explanation:** In this case the 1 is initially at position 0, so the answer for that position is `0`. We can perform reverse operations of size 3. The 1 is currently located at position 0, so we need to reverse the subarray `[0, 2]` for it to leave that position, but reversing that subarray makes position 2 have a 1, which shouldn't happen. So, we can't move the 1 from position 0, making the result for all the other positions `-1`.

**Example 3:**

**Input:** n = 4, p = 2, banned = \[0,1,3\], k = 1
**Output:** \[-1,-1,0,-1\]
**Explanation:** In this case we can only perform reverse operations of size 1. So the 1 never changes its position.

**Constraints:**

*   `1 <= n <= 105`
*   `0 <= p <= n - 1`
*   `0 <= banned.length <= n - 1`
*   `0 <= banned[i] <= n - 1`
*   `1 <= k <= n`
*   `banned[i] != p`
*   all values in `banned` are **unique**

## A solution in Java

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

public int[] reachPosition(int n, int p, int[] banned, int k) {
    Set<Integer> banned_positions = new HashSet<>();
    for (int pos : banned) {
        banned_positions.add(pos);
    }

    int[] ans = new int[n];

    for (int i = 0; i < n; ++i) {
        if (banned_positions.contains(i) || i == p) {
            ans[i] = -1;
            continue;
        }

        int steps = 0;
        int an = Math.abs(p - i) / k;
        if ((Math.abs(p - i) % k == 0) && ((an & 1) == (((n - 1) & 1) ^ (k & 1)))) {
            steps = an;
        }
        else {
            steps = -1;
        }

        ans[i] = steps;
    }

    ans[p] = 0;
    return ans;
}
```
1. Create a set from the `banned` positions for faster look-ups.
2. Initialize the `ans` array with zeros.
3. Iterate `i` from `0` to `n-1`.
4. If the current position `i` is in banned positions or it is equal to p, set the `ans[i]` as -1, and continue.
5. Calculate the possible `an` value by getting the absolute difference between `p` and `i` and divide it by `k`.
6. If the absolute difference between `p` and `i` modulo `k` is zero, and the bitwise AND of `an`, `n-1`, and `k` equals, set the `ans[i]` to the value of `an`.
7. Otherwise, set the `ans[i]` to -1.
8. Set `ans[p]` to 0.
9. Return the `ans` array.

The main idea of the algorithm is to check if the current index `i` is reachable or not under the constraints of the problem. We calculate the required steps for the number `1` to reach the position `i`, and if it is an available position, we update the result accordingly. Otherwise, we keep the default value of -1 for the position.

The bitwise operations are used to calculate the parity relationship between the positions based on the constraints. If the positions are reachable, their parity should match each other with respect to the restrictions.

## A solution in C++

```cpp
#include <vector>
#include <set>

std::vector<int> reachPosition(int n, int p, std::vector<int> &banned, int k) {
    std::set<int> banned_positions(banned.begin(), banned.end());
    std::vector<int> ans(n, 0);

    for (int i = 0; i < n; ++i) {
        if (banned_positions.find(i) != banned_positions.end() || i == p) {
            ans[i] = -1;
            continue;
        }

        int steps = 0;
        int an = abs(p - i) / k;
        if ((abs(p - i) % k == 0) && ((an & 1) == (((n - 1) & 1) ^ (k & 1)))) {
            steps = an;
        }
        else {
            steps = -1;
        }

        ans[i] = steps;
    }

    ans[p] = 0;
    return ans;
}
```
1. Create a set from the `banned` positions for faster look-ups.
2. Initialize the `ans` array with zeros.
3. Iterate `i` from `0` to `n-1`.
4. If the current position `i` is in banned positions or it is equal to p, set the `ans[i]` as -1, and continue.
5. Calculate the possible `an` value by getting the absolute difference between `p` and `i` and divide it by `k`.
6. If the absolute difference between `p` and `i` modulo `k` is zero, and the bitwise AND of `an`, `n-1`, and `k` equals, set the `ans[i]` to the value of `an`.
7. Otherwise, set the `ans[i]` to -1.
8. Set `ans[p]` to 0.
9. Return the `ans` array.

The main idea of the algorithm is to check if the current index `i` is reachable or not under the constraints of the problem. We calculate the required steps for the number `1` to reach the position `i`, and if it is an available position, we update the result accordingly. Otherwise, we keep the default value of -1 for the position.

The bitwise operations are used to calculate the parity relationship between the positions based on the constraints. If the positions are reachable, their parity should match each other with respect to the restrictions.

## A solution in Python

```python
def reach_position(n, p, banned, k):
    banned_positions = set(banned)
    ans = [0] * n

    for i in range(n):
        if i in banned_positions or i == p:
            ans[i] = -1
            continue

        an = abs(p - i) // k
        if abs(p - i) % k == 0 and (an & 1) == (((n - 1) & 1) ^ (k & 1)):
            steps = an
        else:
            steps = -1

        ans[i] = steps

    ans[p] = 0
    return ans
```
1. Create a set from the `banned` positions for faster look-ups.
2. Initialize the `ans` array with zeros.
3. Iterate `i` from `0` to `n-1`.
4. If the current position `i` is in banned positions or it is equal to p, set the `ans[i]` as -1, and continue.
5. Calculate the possible `an` value by getting the absolute difference between `p` and `i` and divide it by `k`.
6. If the absolute difference between `p` and `i` modulo `k` is zero, and the bitwise AND of `an`, `n-1`, and `k` equals, set the `ans[i]` to the value of `an`.
7. Otherwise, set the `ans[i]` to -1.
8. Set `ans[p]` to 0.
9. Return the `ans` array.

The main idea of the algorithm is to check if the current index `i` is reachable or not under the constraints of the problem. We calculate the required steps for the number `1` to reach the position `i`, and if it is an available position, we update the result accordingly. Otherwise, we keep the default value of -1 for the position.

The bitwise operations are used to calculate the parity relationship between the positions based on the constraints. If the positions are reachable, their parity should match each other with respect to the restrictions.

## A solution in Javascript

```javascript
function reachPosition(n, p, banned, k) {
    const banned_positions = new Set(banned);
    const ans = Array(n).fill(0);

    for (let i = 0; i < n; ++i) {
        if (banned_positions.has(i) || i === p) {
            ans[i] = -1;
            continue;
        }

        let steps = 0;
        const an = Math.abs(p - i) / k;
        if (Math.abs(p - i) % k === 0 && (an & 1) === ((n - 1) & 1) ^ (k & 1)) {
            steps = an;
        } else {
            steps = -1;
        }

        ans[i] = steps;
    }

    ans[p] = 0;
    return ans;
}
```
1. Create a set from the `banned` positions for faster look-ups.
2. Initialize the `ans` array with zeros.
3. Iterate `i` from `0` to `n-1`.
4. If the current position `i` is in banned positions or it is equal to p, set the `ans[i]` as -1, and continue.
5. Calculate the possible `an` value by getting the absolute difference between `p` and `i` and divide it by `k`.
6. If the absolute difference between `p` and `i` modulo `k` is zero, and the bitwise AND of `an`, `n-1`, and `k` equals, set the `ans[i]` to the value of `an`.
7. Otherwise, set the `ans[i]` to -1.
8. Set `ans[p]` to 0.
9. Return the `ans` array.

The main idea of the algorithm is to check if the current index `i` is reachable or not under the constraints of the problem. We calculate the required steps for the number `1` to reach the position `i`, and if it is an available position, we update the result accordingly. Otherwise, we keep the default value of -1 for the position.

The bitwise operations are used to calculate the parity relationship between the positions based on the constraints. If the positions are reachable, their parity should match each other with respect to the restrictions.