# Faulty Sensor

- slug: faulty-sensor
- difficulty: Easy

An experiment is being conducted in a lab. To ensure accuracy, there are **two** sensors collecting data simultaneously. You are given two arrays `sensor1` and `sensor2`, where `sensor1[i]` and `sensor2[i]` are the `ith` data points collected by the two sensors.

However, this type of sensor has a chance of being defective, which causes **exactly one** data point to be dropped. After the data is dropped, all the data points to the **right** of the dropped data are **shifted** one place to the left, and the last data point is replaced with some **random value**. It is guaranteed that this random value will **not** be equal to the dropped value.

*   For example, if the correct data is `[1,2,**3**,4,5]` and `3` is dropped, the sensor could return `[1,2,4,5,**7**]` (the last position can be **any** value, not just `7`).

We know that there is a defect in **at most one** of the sensors. Return _the sensor number (_`1` _or_ `2`_) with the defect. If there is **no defect** in either sensor or if it is **impossible** to determine the defective sensor, return_ `-1`_._

**Example 1:**

**Input:** sensor1 = \[2,3,4,5\], sensor2 = \[2,1,3,4\]
**Output:** 1
**Explanation:** Sensor 2 has the correct values.
The second data point from sensor 2 is dropped, and the last value of sensor 1 is replaced by a 5.

**Example 2:**

**Input:** sensor1 = \[2,2,2,2,2\], sensor2 = \[2,2,2,2,5\]
**Output:** -1
**Explanation:** It is impossible to determine which sensor has a defect.
Dropping the last value for either sensor could produce the output for the other sensor.

**Example 3:**

**Input:** sensor1 = \[2,3,2,2,3,2\], sensor2 = \[2,3,2,3,2,7\]
**Output:** 2
**Explanation:** Sensor 1 has the correct values.
The fourth data point from sensor 1 is dropped, and the last value of sensor 1 is replaced by a 7.

**Constraints:**

*   `sensor1.length == sensor2.length`
*   `1 <= sensor1.length <= 100`
*   `1 <= sensor1[i], sensor2[i] <= 100`

## A solution in Java

```java
import java.util.Arrays;
import java.util.Comparator;

public int[] maximizeXor(int[] nums, int[][] queries) {
    int[][] newQueries = new int[queries.length][];
    Arrays.sort(nums);
    for (int i = 0; i < queries.length; ++i) {
        newQueries[i] = new int[]{queries[i][0], queries[i][1], i};
    }
    Arrays.sort(newQueries, Comparator.comparingInt(a -> a[1]));

    int[] ans = new int[queries.length];
    int[][] trie = new int[200010][2];
    int[] sum = new int[200010];
    sum[0] = 1;
    int idx = 0, cnt = 0;
    for (int[] q : newQueries) {
        int x = q[0], m = q[1], k = q[2], p = 0;
        while (idx < nums.length && nums[idx] <= m) {
            int cur = 0, t = nums[idx++];
            for (int i = 31; i >= 0; --i) {
                int bit = ((t >> i) & 1);
                if (trie[cur][bit] == 0) {
                    trie[cur][bit] = ++cnt;
                }
                cur = trie[cur][bit];
            }
            sum[cur]++;
        }
        if (cnt == 0) {
            ans[k] = -1;
            continue;
        }
        int cur = 0, ans2 = 0;
        for (int i = 31; i >= 0; --i) {
            int bit = ((x >> i) & 1);
            if (trie[cur][bit ^ 1] != 0) {
                cur = trie[cur][bit ^ 1];
                ans2 |= (1 << i);
            } else {
                cur = trie[cur][bit];
            }
        }
        ans[k] = ans2;
    }
    return ans;
}
```
The algorithm uses a Trie data structure to store the binary representation of numbers in the nums array.

1. First, sort the nums array in ascending order.
2. Create a new queries array, adding the index to each query, and sort according to the mi value.
3. Iterate through the sorted queries array and update Trie with nums elements that are less than or equal to mi.
4. For each x in the query, traverse the Trie and find the highest XOR value achievable.
5. If there are no Trie nodes, set the answer to -1 for that query.
6. Store the answer of each query in the ans array at the index originally present in the original query array.
7. Return the ans array containing the answer to all queries.

## A solution in C++

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

vector<int> maximizeXor(vector<int>& nums, vector<vector<int>>& queries) {
    sort(nums.begin(), nums.end());
    for (int i = 0; i < queries.size(); ++i) {
        queries[i].push_back(i);
    }
    sort(queries.begin(), queries.end(), [](vector<int> &a, vector<int> &b) {
        return a[1] < b[1];
    });

    vector<int> ans(queries.size());
    int idx = 0, trie[200010][2] = {}, sum[200010] = {1}, cnt = 0;
    for (const auto &q : queries) {
        int x = q[0], m = q[1], k = q[2], p = 0;
        while (idx < nums.size() && nums[idx] <= m) {
            int cur = 0, t = nums[idx++];
            for (int i = 31; i >= 0; --i) {
                int bit = ((t >> i) & 1);
                if (!trie[cur][bit]) {
                    trie[cur][bit] = ++cnt;
                }
                cur = trie[cur][bit];
            }
            sum[cur]++;
        }
        if (!cnt) {
            ans[k] = -1;
            continue;
        }
        int cur = 0, ans2 = 0;
        for (int i = 31; i >= 0; --i) {
            int bit = ((x >> i) & 1);
            if (trie[cur][bit ^ 1]) {
                cur = trie[cur][bit ^ 1];
                ans2 |= (1 << i);
            } else {
                cur = trie[cur][bit];
            }
        }
        ans[k] = ans2;
    }
    return ans;
}
```
The algorithm uses a Trie data structure to store the binary representation of numbers in the nums array.

1. First, sort the nums array in ascending order.
2. Create a new queries array, adding the index to each query, and sort according to the mi value.
3. Iterate through the sorted queries array and update Trie with nums elements that are less than or equal to mi.
4. For each x in the query, traverse the Trie and find the highest XOR value achievable.
5. If there are no Trie nodes, set the answer to -1 for that query.
6. Store the answer of each query in the ans array at the index originally present in the original query array.
7. Return the ans array containing the answer to all queries.

## A solution in Python

```python
def maximizeXor(nums, queries):
    trie = {}
    nums.sort()

    new_queries = sorted([(x, m, i) for i, (x, m) in enumerate(queries)], key=lambda x: x[1])

    ans = [0] * len(queries)

    idx = 0
    for x, m, i in new_queries:
        while idx < len(nums) and nums[idx] <= m:
            t = nums[idx]
            idx += 1
            cur = trie
            for j in range(31, -1, -1):
                bit = (t >> j) & 1
                cur = cur.setdefault(bit, {})
        cur = trie
        xor_value = 0
        for j in range(31, -1, -1):
            bit = (x >> j) & 1
            if 1 ^ bit in cur:
                cur = cur[1 ^ bit]
                xor_value |= 1 << j
            else:
                cur = cur[bit]
        ans[i] = xor_value if cur else -1

    return ans
```
The algorithm uses a Trie data structure to store the binary representation of numbers in the nums array.

1. First, sort the nums array in ascending order.
2. Create a new queries array, adding the index to each query, and sort according to the mi value.
3. Iterate through the sorted queries array and update Trie with nums elements that are less than or equal to mi.
4. For each x in the query, traverse the Trie and find the highest XOR value achievable.
5. If there are no Trie nodes, set the answer to -1 for that query.
6. Store the answer of each query in the ans array at the index originally present in the original query array.
7. Return the ans array containing the answer to all queries.

## A solution in Javascript

```javascript
function maximizeXor(nums, queries) {
    nums.sort((a, b) => a - b);
    const newQueries = queries.map((q, idx) => [q[0], q[1], idx]).sort((a, b) => a[1] - b[1]);

    const trie = new Array(200010).fill(null).map(() => new Array(2).fill(0));
    const sum = new Array(200010).fill(0);
    sum[0] = 1;

    let idx = 0, cnt = 0;
    const ans = new Array(queries.length).fill(0);

    for (const q of newQueries) {
        const [x, m, k] = q;
        let p = 0;
        while (idx < nums.length && nums[idx] <= m) {
            let cur = 0, t = nums[idx++];
            for (let i = 31; i >= 0; --i) {
                const bit = ((t >> i) & 1);
                if (!trie[cur][bit]) {
                    trie[cur][bit] = ++cnt;
                }
                cur = trie[cur][bit];
            }
            sum[cur]++;
        }
        if (!cnt) {
            ans[k] = -1;
            continue;
        }
        let cur = 0, ans2 = 0;
        for (let i = 31; i >= 0; --i) {
            const bit = ((x >> i) & 1);
            if (trie[cur][bit ^ 1]) {
                cur = trie[cur][bit ^ 1];
                ans2 |= (1 << i);
            } else {
                cur = trie[cur][bit];
            }
        }
        ans[k] = ans2;
    }

    return ans;
}
```
The algorithm uses a Trie data structure to store the binary representation of numbers in the nums array.

1. First, sort the nums array in ascending order.
2. Create a new queries array, adding the index to each query, and sort according to the mi value.
3. Iterate through the sorted queries array and update Trie with nums elements that are less than or equal to mi.
4. For each x in the query, traverse the Trie and find the highest XOR value achievable.
5. If there are no Trie nodes, set the answer to -1 for that query.
6. Store the answer of each query in the ans array at the index originally present in the original query array.
7. Return the ans array containing the answer to all queries.


# Minimum Operations to Make the Array Increasing

- slug: minimum-operations-to-make-the-array-increasing
- difficulty: Easy

You are given an integer array `nums` (**0-indexed**). In one operation, you can choose an element of the array and increment it by `1`.

*   For example, if `nums = [1,2,3]`, you can choose to increment `nums[1]` to make `nums = [1,**3**,3]`.

Return _the **minimum** number of operations needed to make_ `nums` _**strictly** **increasing**._

An array `nums` is **strictly increasing** if `nums[i] < nums[i+1]` for all `0 <= i < nums.length - 1`. An array of length `1` is trivially strictly increasing.

**Example 1:**

**Input:** nums = \[1,1,1\]
**Output:** 3
**Explanation:** You can do the following operations:
1) Increment nums\[2\], so nums becomes \[1,1,**2**\].
2) Increment nums\[1\], so nums becomes \[1,**2**,2\].
3) Increment nums\[2\], so nums becomes \[1,2,**3**\].

**Example 2:**

**Input:** nums = \[1,5,2,4,1\]
**Output:** 14

**Example 3:**

**Input:** nums = \[8\]
**Output:** 0

**Constraints:**

*   `1 <= nums.length <= 5000`
*   `1 <= nums[i] <= 104`

## A solution in Java

```java
public int minOperations(int[] nums) {
    int operations = 0;
    for (int i = 1; i < nums.length; i++) {
        if (nums[i] <= nums[i - 1]) {
            operations += (nums[i - 1] - nums[i]) + 1;
            nums[i] = nums[i - 1] + 1;
        }
    }
    return operations;
}
```
The algorithm iterates through the input array `nums` from the second element (index 1) to the end. For each element, if it is less than or equal to its previous element, we need to increment it to make the array strictly increasing. We calculate the difference between the current element and the previous element and add 1 to it to find the required number of increments. We then update both the element in the array and the total count of operations. At the end, we return the total count of operations.

## A solution in C++

```cpp
int min_operations(vector<int>& nums) {
    int operations = 0;
    for (int i = 1; i < nums.size(); i++) {
        if (nums[i] <= nums[i - 1]) {
            operations += (nums[i - 1] - nums[i]) + 1;
            nums[i] = nums[i - 1] + 1;
        }
    }
    return operations;
}
```
The algorithm iterates through the input array `nums` from the second element (index 1) to the end. For each element, if it is less than or equal to its previous element, we need to increment it to make the array strictly increasing. We calculate the difference between the current element and the previous element and add 1 to it to find the required number of increments. We then update both the element in the array and the total count of operations. At the end, we return the total count of operations.

## A solution in Python

```python
def min_operations(nums):
    operations = 0
    for i in range(1, len(nums)):
        if nums[i] <= nums[i - 1]:
            operations += (nums[i - 1] - nums[i]) + 1
            nums[i] = nums[i - 1] + 1
    return operations
```
The algorithm iterates through the input array `nums` from the second element (index 1) to the end. For each element, if it is less than or equal to its previous element, we need to increment it to make the array strictly increasing. We calculate the difference between the current element and the previous element and add 1 to it to find the required number of increments. We then update both the element in the array and the total count of operations. At the end, we return the total count of operations.

## A solution in Javascript

```javascript
function minOperations(nums) {
    let operations = 0;
    for (let i = 1; i < nums.length; i++) {
        if (nums[i] <= nums[i - 1]) {
            operations += (nums[i - 1] - nums[i]) + 1;
            nums[i] = nums[i - 1] + 1;
        }
    }
    return operations;
}
```
The algorithm iterates through the input array `nums` from the second element (index 1) to the end. For each element, if it is less than or equal to its previous element, we need to increment it to make the array strictly increasing. We calculate the difference between the current element and the previous element and add 1 to it to find the required number of increments. We then update both the element in the array and the total count of operations. At the end, we return the total count of operations.


# Queries on Number of Points Inside a Circle

- slug: queries-on-number-of-points-inside-a-circle
- difficulty: Medium

You are given an array `points` where `points[i] = [xi, yi]` is the coordinates of the `ith` point on a 2D plane. Multiple points can have the **same** coordinates.

You are also given an array `queries` where `queries[j] = [xj, yj, rj]` describes a circle centered at `(xj, yj)` with a radius of `rj`.

For each query `queries[j]`, compute the number of points **inside** the `jth` circle. Points **on the border** of the circle are considered **inside**.

Return _an array_ `answer`_, where_ `answer[j]` _is the answer to the_ `jth` _query_.

**Example 1:**

**Input:** points = \[\[1,3\],\[3,3\],\[5,3\],\[2,2\]\], queries = \[\[2,3,1\],\[4,3,1\],\[1,1,2\]\]
**Output:** \[3,2,2\]
**Explanation:** The points and circles are shown above.
queries\[0\] is the green circle, queries\[1\] is the red circle, and queries\[2\] is the blue circle.

**Example 2:**

**Input:** points = \[\[1,1\],\[2,2\],\[3,3\],\[4,4\],\[5,5\]\], queries = \[\[1,2,2\],\[2,2,2\],\[4,3,2\],\[4,3,3\]\]
**Output:** \[2,3,2,4\]
**Explanation:** The points and circles are shown above.
queries\[0\] is green, queries\[1\] is red, queries\[2\] is blue, and queries\[3\] is purple.

**Constraints:**

*   `1 <= points.length <= 500`
*   `points[i].length == 2`
*   `0 <= xi, yi <= 500`
*   `1 <= queries.length <= 500`
*   `queries[j].length == 3`
*   `0 <= xj, yj <= 500`
*   `1 <= rj <= 500`
*   All coordinates are integers.

**Follow up:** Could you find the answer for each query in better complexity than `O(n)`?

## A solution in Java

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

public int[] countPoints(int[][] points, int[][] queries) {
    int[] answer = new int[queries.length];
    for (int i = 0; i < queries.length; i++) {
        int inside = 0;
        for (int[] point : points) {
            int dx = point[0] - queries[i][0];
            int dy = point[1] - queries[i][1];
            if (dx * dx + dy * dy <= queries[i][2] * queries[i][2]) {
                inside++;
            }
        }
        answer[i] = inside;
    }
    return answer;
}
```
For each query circle, we iterate over each point to check if it lies inside the circle. To check if a point is inside the circle, we calculate the squared distance (dx * dx + dy * dy) between the point and the center of the circle. If the squared distance is less than or equal to the squared radius of the circle, that means the point is inside the circle or on its border. We increment an `inside` counter for each point that satisfies this condition. The counter gets added to the `answer` array after iterating over all the points for the current circle. We repeat this process for all query circles and return the array of `inside` counts.

## A solution in C++

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

vector<int> countPoints(vector<vector<int>>& points, vector<vector<int>>& queries) {
    vector<int> answer;
    for (auto& query : queries) {
        int inside = 0;
        for (auto& point : points) {
            int dx = point[0] - query[0];
            int dy = point[1] - query[1];
            if (dx * dx + dy * dy <= query[2] * query[2]) {
                inside++;
            }
        }
        answer.push_back(inside);
    }
    return answer;
}
```
For each query circle, we iterate over each point to check if it lies inside the circle. To check if a point is inside the circle, we calculate the squared distance (dx * dx + dy * dy) between the point and the center of the circle. If the squared distance is less than or equal to the squared radius of the circle, that means the point is inside the circle or on its border. We increment an `inside` counter for each point that satisfies this condition. The counter gets added to the `answer` array after iterating over all the points for the current circle. We repeat this process for all query circles and return the array of `inside` counts.

## A solution in Python

```python
def countPoints(points, queries):
    answer = []
    for query in queries:
        inside = 0
        for point in points:
            dx = point[0] - query[0]
            dy = point[1] - query[1]
            if dx * dx + dy * dy <= query[2] * query[2]:
                inside += 1
        answer.append(inside)
    return answer
```
For each query circle, we iterate over each point to check if it lies inside the circle. To check if a point is inside the circle, we calculate the squared distance (dx * dx + dy * dy) between the point and the center of the circle. If the squared distance is less than or equal to the squared radius of the circle, that means the point is inside the circle or on its border. We increment an `inside` counter for each point that satisfies this condition. The counter gets added to the `answer` array after iterating over all the points for the current circle. We repeat this process for all query circles and return the array of `inside` counts.

## A solution in Javascript

```javascript
function countPoints(points, queries) {
    const answer = [];
    for (const query of queries) {
        let inside = 0;
        for (const point of points) {
            const dx = point[0] - query[0];
            const dy = point[1] - query[1];
            if (dx * dx + dy * dy <= query[2] * query[2]) {
                inside++;
            }
        }
        answer.push(inside);
    }
    return answer;
}
```
For each query circle, we iterate over each point to check if it lies inside the circle. To check if a point is inside the circle, we calculate the squared distance (dx * dx + dy * dy) between the point and the center of the circle. If the squared distance is less than or equal to the squared radius of the circle, that means the point is inside the circle or on its border. We increment an `inside` counter for each point that satisfies this condition. The counter gets added to the `answer` array after iterating over all the points for the current circle. We repeat this process for all query circles and return the array of `inside` counts.


# Maximum XOR for Each Query

- slug: maximum-xor-for-each-query
- difficulty: Medium

You are given a **sorted** array `nums` of `n` non-negative integers and an integer `maximumBit`. You want to perform the following query `n` **times**:

1.  Find a non-negative integer `k < 2maximumBit` such that `nums[0] XOR nums[1] XOR ... XOR nums[nums.length-1] XOR k` is **maximized**. `k` is the answer to the `ith` query.
2.  Remove the **last** element from the current array `nums`.

Return _an array_ `answer`_, where_ `answer[i]` _is the answer to the_ `ith` _query_.

**Example 1:**

**Input:** nums = \[0,1,1,3\], maximumBit = 2
**Output:** \[0,3,2,3\]
**Explanation**: The queries are answered as follows:
1st query: nums = \[0,1,1,3\], k = 0 since 0 XOR 1 XOR 1 XOR 3 XOR 0 = 3.
2nd query: nums = \[0,1,1\], k = 3 since 0 XOR 1 XOR 1 XOR 3 = 3.
3rd query: nums = \[0,1\], k = 2 since 0 XOR 1 XOR 2 = 3.
4th query: nums = \[0\], k = 3 since 0 XOR 3 = 3.

**Example 2:**

**Input:** nums = \[2,3,4,7\], maximumBit = 3
**Output:** \[5,2,6,5\]
**Explanation**: The queries are answered as follows:
1st query: nums = \[2,3,4,7\], k = 5 since 2 XOR 3 XOR 4 XOR 7 XOR 5 = 7.
2nd query: nums = \[2,3,4\], k = 2 since 2 XOR 3 XOR 4 XOR 2 = 7.
3rd query: nums = \[2,3\], k = 6 since 2 XOR 3 XOR 6 = 7.
4th query: nums = \[2\], k = 5 since 2 XOR 5 = 7.

**Example 3:**

**Input:** nums = \[0,1,2,2,5,7\], maximumBit = 3
**Output:** \[4,3,6,4,6,7\]

**Constraints:**

*   `nums.length == n`
*   `1 <= n <= 105`
*   `1 <= maximumBit <= 20`
*   `0 <= nums[i] < 2maximumBit`
*   `nums` is sorted in **ascending** order.

## A solution in Java

```java
import java.util.Arrays;

public int maximumUnits(int[][] boxTypes, int truckSize) {
    Arrays.sort(boxTypes, (a, b) -> b[1] - a[1]);

    int totalUnits = 0;
    for (int[] box : boxTypes) {
        int boxCount = Math.min(truckSize, box[0]);
        totalUnits += boxCount * box[1];
        truckSize -= boxCount;
        if (truckSize == 0) {
            break;
        }
    }

    return totalUnits;
}
```
1. Sort the boxTypes array in descending order based on the numberOfUnitsPerBox.
2. Initialize a variable totalUnits to keep track of the total number of units we have added so far.
3. Iterate through the sorted boxTypes array.
4. For each box, find the minimum of truckSize and numberOfBoxes (taking as many boxes as possible without exceeding truckSize).
5. Add the product of the minimum value and numberOfUnitsPerBox to the totalUnits.
6. Decrease truckSize by the number of boxes we have taken.
7. If truckSize becomes 0, break the loop as we can't add any more boxes.
8. Return the totalUnits value, which is the maximum total number of units that can be put on the truck.

## A solution in C++

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

bool compare(vector<int>& a, vector<int>& b) {
    return a[1] > b[1];
}

int maximumUnits(vector<vector<int>>& boxTypes, int truckSize) {
    sort(boxTypes.begin(), boxTypes.end(), compare);

    int totalUnits = 0;
    for (auto& box : boxTypes) {
        int boxCount = min(truckSize, box[0]);
        totalUnits += boxCount * box[1];
        truckSize -= boxCount;
        if (truckSize == 0) {
            break;
        }
    }

    return totalUnits;
}
```
1. Sort the boxTypes array in descending order based on the numberOfUnitsPerBox.
2. Initialize a variable totalUnits to keep track of the total number of units we have added so far.
3. Iterate through the sorted boxTypes array.
4. For each box, find the minimum of truckSize and numberOfBoxes (taking as many boxes as possible without exceeding truckSize).
5. Add the product of the minimum value and numberOfUnitsPerBox to the totalUnits.
6. Decrease truckSize by the number of boxes we have taken.
7. If truckSize becomes 0, break the loop as we can't add any more boxes.
8. Return the totalUnits value, which is the maximum total number of units that can be put on the truck.

## A solution in Python

```python
def maximumUnits(boxTypes, truckSize):
    boxTypes.sort(key=lambda x: x[1], reverse=True)

    totalUnits = 0
    for box in boxTypes:
        boxCount = min(truckSize, box[0])
        totalUnits += boxCount * box[1]
        truckSize -= boxCount
        if truckSize == 0:
            break

    return totalUnits
```
1. Sort the boxTypes array in descending order based on the numberOfUnitsPerBox.
2. Initialize a variable totalUnits to keep track of the total number of units we have added so far.
3. Iterate through the sorted boxTypes array.
4. For each box, find the minimum of truckSize and numberOfBoxes (taking as many boxes as possible without exceeding truckSize).
5. Add the product of the minimum value and numberOfUnitsPerBox to the totalUnits.
6. Decrease truckSize by the number of boxes we have taken.
7. If truckSize becomes 0, break the loop as we can't add any more boxes.
8. Return the totalUnits value, which is the maximum total number of units that can be put on the truck.

## A solution in Javascript

```javascript
function maximumUnits(boxTypes, truckSize) {
    boxTypes.sort((a, b) => b[1] - a[1]);

    let totalUnits = 0;
    for (const box of boxTypes) {
        const boxCount = Math.min(truckSize, box[0]);
        totalUnits += boxCount * box[1];
        truckSize -= boxCount;
        if (truckSize === 0) {
            break;
        }
    }

    return totalUnits;
}
```
1. Sort the boxTypes array in descending order based on the numberOfUnitsPerBox.
2. Initialize a variable totalUnits to keep track of the total number of units we have added so far.
3. Iterate through the sorted boxTypes array.
4. For each box, find the minimum of truckSize and numberOfBoxes (taking as many boxes as possible without exceeding truckSize).
5. Add the product of the minimum value and numberOfUnitsPerBox to the totalUnits.
6. Decrease truckSize by the number of boxes we have taken.
7. If truckSize becomes 0, break the loop as we can't add any more boxes.
8. Return the totalUnits value, which is the maximum total number of units that can be put on the truck.


# Minimum Number of Operations to Make String Sorted

- slug: minimum-number-of-operations-to-make-string-sorted
- difficulty: Hard

You are given a string `s` (**0-indexed**). You are asked to perform the following operation on `s` until you get a sorted string:

1.  Find **the largest index** `i` such that `1 <= i < s.length` and `s[i] < s[i - 1]`.
2.  Find **the largest index** `j` such that `i <= j < s.length` and `s[k] < s[i - 1]` for all the possible values of `k` in the range `[i, j]` inclusive.
3.  Swap the two characters at indices `i - 1` and `j`.
4.  Reverse the suffix starting at index `i`.

Return _the number of operations needed to make the string sorted._ Since the answer can be too large, return it **modulo** `109 + 7`.

**Example 1:**

**Input:** s =  "cba "
**Output:** 5
**Explanation:** The simulation goes as follows:
Operation 1: i=2, j=2. Swap s\[1\] and s\[2\] to get s= "cab ", then reverse the suffix starting at 2. Now, s= "cab ".
Operation 2: i=1, j=2. Swap s\[0\] and s\[2\] to get s= "bac ", then reverse the suffix starting at 1. Now, s= "bca ".
Operation 3: i=2, j=2. Swap s\[1\] and s\[2\] to get s= "bac ", then reverse the suffix starting at 2. Now, s= "bac ".
Operation 4: i=1, j=1. Swap s\[0\] and s\[1\] to get s= "abc ", then reverse the suffix starting at 1. Now, s= "acb ".
Operation 5: i=2, j=2. Swap s\[1\] and s\[2\] to get s= "abc ", then reverse the suffix starting at 2. Now, s= "abc ".

**Example 2:**

**Input:** s =  "aabaa "
**Output:** 2
**Explanation:** The simulation goes as follows:
Operation 1: i=3, j=4. Swap s\[2\] and s\[4\] to get s= "aaaab ", then reverse the substring starting at 3. Now, s= "aaaba ".
Operation 2: i=4, j=4. Swap s\[3\] and s\[4\] to get s= "aaaab ", then reverse the substring starting at 4. Now, s= "aaaab ".

**Constraints:**

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

## A solution in Java

```java
import java.util.HashMap;

public int countPairs(int[] deliciousness) {
    final int MOD = (int) (1e9 + 7);
    HashMap<Integer, Integer> hashMap = new HashMap<>();
    int maxVal = 0;
    for (int val : deliciousness) {
        maxVal = Math.max(maxVal, val);
    }
    int maxSum = maxVal * 2;

    int count = 0;
    for (int val : deliciousness) {
        for (int sum = 1; sum <= maxSum; sum <<= 1) {
            count = (count + hashMap.getOrDefault(sum - val, 0)) % MOD;
        }
        hashMap.put(val, hashMap.getOrDefault(val, 0) + 1);
    }

    return count;
}
```
1. Initialize a hashmap for storing the frequency of deliciousness values.
2. Find the max value in the deliciousness array and calculate the max sum as twice the max value.
3. Initialize a variable to store the count of good meal pairs.
4. Iterate through the deliciousness array, for each value:
   a. Iterate with powers of two less than or equal to max sum.
   b. If the hashmap contains the power of two minus the current value, increment the count by the frequency of such value in the hashmap. Don't forget to modulo the count by 1e9 + 7.
   c. Update the hashmap by incrementing the frequency of the current value.
5. After iterating through the deliciousness array, return the count of good meal pairs.

## A solution in C++

```cpp
#include <unordered_map>

int countPairs(vector<int>& deliciousness) {
    const int MOD = 1e9 + 7;
    unordered_map<int, int> hashMap;
    int maxVal = *max_element(deliciousness.begin(), deliciousness.end());
    int maxSum = maxVal * 2;

    int count = 0;
    for (int val : deliciousness) {
        for (int sum = 1; sum <= maxSum; sum <<= 1) {
            count = (count + hashMap[sum - val]) % MOD;
        }
        hashMap[val]++;
    }

    return count;
}
```
1. Initialize a hashmap for storing the frequency of deliciousness values.
2. Find the max value in the deliciousness array and calculate the max sum as twice the max value.
3. Initialize a variable to store the count of good meal pairs.
4. Iterate through the deliciousness array, for each value:
   a. Iterate with powers of two less than or equal to max sum.
   b. If the hashmap contains the power of two minus the current value, increment the count by the frequency of such value in the hashmap. Don't forget to modulo the count by 1e9 + 7.
   c. Update the hashmap by incrementing the frequency of the current value.
5. After iterating through the deliciousness array, return the count of good meal pairs.

## A solution in Python

```python
from collections import defaultdict

def countPairs(deliciousness):
    MOD = 10**9 + 7
    hashMap = defaultdict(int)
    maxVal = max(deliciousness)
    maxSum = maxVal * 2

    count = 0
    for val in deliciousness:
        for sum in (1 << i for i in range(22)):
            count = (count + hashMap[sum - val]) % MOD
        hashMap[val] += 1

    return count
```
1. Initialize a hashmap for storing the frequency of deliciousness values.
2. Find the max value in the deliciousness array and calculate the max sum as twice the max value.
3. Initialize a variable to store the count of good meal pairs.
4. Iterate through the deliciousness array, for each value:
   a. Iterate with powers of two less than or equal to max sum.
   b. If the hashmap contains the power of two minus the current value, increment the count by the frequency of such value in the hashmap. Don't forget to modulo the count by 1e9 + 7.
   c. Update the hashmap by incrementing the frequency of the current value.
5. After iterating through the deliciousness array, return the count of good meal pairs.

## A solution in Javascript

```javascript
function countPairs(deliciousness) {
    const MOD = 1e9 + 7;
    const hashMap = new Map();
    let maxVal = 0;
    for (const val of deliciousness) {
        maxVal = Math.max(maxVal, val);
    }
    const maxSum = maxVal * 2;

    let count = 0;
    for (const val of deliciousness) {
        for (let sum = 1; sum <= maxSum; sum <<= 1) {
            count = (count + (hashMap.get(sum - val) || 0)) % MOD;
        }
        hashMap.set(val, (hashMap.get(val) || 0) + 1);
    }

    return count;
}
```
1. Initialize a hashmap for storing the frequency of deliciousness values.
2. Find the max value in the deliciousness array and calculate the max sum as twice the max value.
3. Initialize a variable to store the count of good meal pairs.
4. Iterate through the deliciousness array, for each value:
   a. Iterate with powers of two less than or equal to max sum.
   b. If the hashmap contains the power of two minus the current value, increment the count by the frequency of such value in the hashmap. Don't forget to modulo the count by 1e9 + 7.
   c. Update the hashmap by incrementing the frequency of the current value.
5. After iterating through the deliciousness array, return the count of good meal pairs.


# Check if the Sentence Is Pangram

- slug: check-if-the-sentence-is-pangram
- difficulty: Easy

A **pangram** is a sentence where every letter of the English alphabet appears at least once.

Given a string `sentence` containing only lowercase English letters, return `true` _if_ `sentence` _is a **pangram**, or_ `false` _otherwise._

**Example 1:**

**Input:** sentence =  "thequickbrownfoxjumpsoverthelazydog "
**Output:** true
**Explanation:** sentence contains at least one of every letter of the English alphabet.

**Example 2:**

**Input:** sentence =  "leetcode "
**Output:** false

**Constraints:**

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

## A solution in Java

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

public int minOperations(int[] target, int[] arr) {
    Map<Integer, Integer> indexMap = new HashMap<>();
    for (int i = 0; i < target.length; ++i) {
        indexMap.put(target[i], i);
    }

    int[] lis = new int[arr.length];
    int lisSize = 0;
    for (int num : arr) {
        if (indexMap.containsKey(num)) {
            int pos = Arrays.binarySearch(lis, 0, lisSize, indexMap.get(num));
            if (pos < 0) {
                pos = -(pos + 1);
            }
            lis[pos] = indexMap.get(num);
            if (pos == lisSize) {
                lisSize++;
            }
        }
    }

    return target.length - lisSize;
}
```
The algorithm first creates a mapping of the target integers to their index positions. This mapping will later be used to determine if a number in `arr` is in the target sequence and its relative order. It then initializes an empty list called `lis` (Longest Increasing Subsequence) and iterates through `arr`.

For each number `num` in `arr`, if it's also in the target, we check if that number can be appended to the end of `lis`. If not, it replaces the first number in `lis` that is greater than or equal to it to maintain the sorted order. This is done using `lowerBound` (C++, JavaScript) or `bisect_left` (Python) or `Arrays.binarySearch` (Java) functions - all of which perform binary search to find the position at which the new number should be inserted.

Finally, the algorithm returns the difference between the lengths of the target sequence and `lis`, which represents the minimum number of operations needed to make `target` a subsequence of `arr`.

## A solution in C++

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

int minOperations(std::vector<int>& target, std::vector<int>& arr) {
    std::unordered_map<int, int> index_map;
    for (int i = 0; i < target.size(); ++i) {
        index_map[target[i]] = i;
    }

    std::vector<int> lis;
    for (int num : arr) {
        if (index_map.count(num)) {
            int pos = std::lower_bound(lis.begin(), lis.end(), index_map[num]) - lis.begin();
            if (pos == lis.size()) {
                lis.push_back(index_map[num]);
            } else {
                lis[pos] = index_map[num];
            }
        }
    }

    return target.size() - lis.size();
}
```
The algorithm first creates a mapping of the target integers to their index positions. This mapping will later be used to determine if a number in `arr` is in the target sequence and its relative order. It then initializes an empty list called `lis` (Longest Increasing Subsequence) and iterates through `arr`.

For each number `num` in `arr`, if it's also in the target, we check if that number can be appended to the end of `lis`. If not, it replaces the first number in `lis` that is greater than or equal to it to maintain the sorted order. This is done using `lowerBound` (C++, JavaScript) or `bisect_left` (Python) or `Arrays.binarySearch` (Java) functions - all of which perform binary search to find the position at which the new number should be inserted.

Finally, the algorithm returns the difference between the lengths of the target sequence and `lis`, which represents the minimum number of operations needed to make `target` a subsequence of `arr`.

## A solution in Python

```python
from bisect import bisect_left

def min_operations(target, arr):
    index_map = {num: i for i, num in enumerate(target)}

    lis = []
    for num in arr:
        if num in index_map:
            pos = bisect_left(lis, index_map[num])
            if pos == len(lis):
                lis.append(index_map[num])
            else:
                lis[pos] = index_map[num]

    return len(target) - len(lis)
```
The algorithm first creates a mapping of the target integers to their index positions. This mapping will later be used to determine if a number in `arr` is in the target sequence and its relative order. It then initializes an empty list called `lis` (Longest Increasing Subsequence) and iterates through `arr`.

For each number `num` in `arr`, if it's also in the target, we check if that number can be appended to the end of `lis`. If not, it replaces the first number in `lis` that is greater than or equal to it to maintain the sorted order. This is done using `lowerBound` (C++, JavaScript) or `bisect_left` (Python) or `Arrays.binarySearch` (Java) functions - all of which perform binary search to find the position at which the new number should be inserted.

Finally, the algorithm returns the difference between the lengths of the target sequence and `lis`, which represents the minimum number of operations needed to make `target` a subsequence of `arr`.

## A solution in Javascript

```javascript
function minOperations(target, arr) {
    const indexMap = new Map();

    for (let i = 0; i < target.length; ++i) {
        indexMap.set(target[i], i);
    }

    const lis = [];
    for (const num of arr) {
        if (indexMap.has(num)) {
            const pos = lowerBound(lis, indexMap.get(num));
            if (pos === lis.length) {
                lis.push(indexMap.get(num));
            } else {
                lis[pos] = indexMap.get(num);
            }
        }
    }

    return target.length - lis.length;
}

function lowerBound(arr, target) {
    let low = 0;
    let high = arr.length;

    while (low < high) {
        const mid = Math.floor((low + high) / 2);
        if (arr[mid] < target) {
            low = mid + 1;
        } else {
            high = mid;
        }
    }

    return low;
}
```
The algorithm first creates a mapping of the target integers to their index positions. This mapping will later be used to determine if a number in `arr` is in the target sequence and its relative order. It then initializes an empty list called `lis` (Longest Increasing Subsequence) and iterates through `arr`.

For each number `num` in `arr`, if it's also in the target, we check if that number can be appended to the end of `lis`. If not, it replaces the first number in `lis` that is greater than or equal to it to maintain the sorted order. This is done using `lowerBound` (C++, JavaScript) or `bisect_left` (Python) or `Arrays.binarySearch` (Java) functions - all of which perform binary search to find the position at which the new number should be inserted.

Finally, the algorithm returns the difference between the lengths of the target sequence and `lis`, which represents the minimum number of operations needed to make `target` a subsequence of `arr`.


# Maximum Ice Cream Bars

- slug: maximum-ice-cream-bars
- difficulty: Medium

It is a sweltering summer day, and a boy wants to buy some ice cream bars.

At the store, there are `n` ice cream bars. You are given an array `costs` of length `n`, where `costs[i]` is the price of the `ith` ice cream bar in coins. The boy initially has `coins` coins to spend, and he wants to buy as many ice cream bars as possible.

**Note:** The boy can buy the ice cream bars in any order.

Return _the **maximum** number of ice cream bars the boy can buy with_ `coins` _coins._

You must solve the problem by counting sort.

**Example 1:**

**Input:** costs = \[1,3,2,4,1\], coins = 7
**Output:** 4
**Explanation:** The boy can buy ice cream bars at indices 0,1,2,4 for a total price of 1 + 3 + 2 + 1 = 7.

**Example 2:**

**Input:** costs = \[10,6,8,7,7,8\], coins = 5
**Output:** 0
**Explanation:** The boy cannot afford any of the ice cream bars.

**Example 3:**

**Input:** costs = \[1,6,3,1,2,5\], coins = 20
**Output:** 6
**Explanation:** The boy can buy all the ice cream bars for a total price of 1 + 6 + 3 + 1 + 2 + 5 = 18.

**Constraints:**

*   `costs.length == n`
*   `1 <= n <= 105`
*   `1 <= costs[i] <= 105`
*   `1 <= coins <= 108`

## A solution in Java

```java
public int largestAltitude(int[] gain) {
    int max_altitude = 0, current_altitude = 0;
    for (int i = 0; i < gain.length; i++) {
        current_altitude += gain[i];
        max_altitude = Math.max(max_altitude, current_altitude);
    }
    return max_altitude;
}
```
The algorithm consists of iterating through the input `gain` array and keeping track of the current altitude and the maximum altitude reached:

1. Initialize `max_altitude` and `current_altitude` variables to 0.
2. For each element in the `gain` array, add the gain value to the `current_altitude`.
3. Update the `max_altitude` if the `current_altitude` is greater than the `max_altitude`.
4. Return the `max_altitude` after the loop.

This approach has a time complexity of O(n), where n is the length of the input array `gain`.

## A solution in C++

```cpp
int largestAltitude(vector<int>& gain) {
    int max_altitude = 0, current_altitude = 0;
    for (int i = 0; i < gain.size(); ++i) {
        current_altitude += gain[i];
        max_altitude = max(max_altitude, current_altitude);
    }
    return max_altitude;
}
```
The algorithm consists of iterating through the input `gain` array and keeping track of the current altitude and the maximum altitude reached:

1. Initialize `max_altitude` and `current_altitude` variables to 0.
2. For each element in the `gain` array, add the gain value to the `current_altitude`.
3. Update the `max_altitude` if the `current_altitude` is greater than the `max_altitude`.
4. Return the `max_altitude` after the loop.

This approach has a time complexity of O(n), where n is the length of the input array `gain`.

## A solution in Python

```python
def largestAltitude(gain):
    max_altitude, current_altitude = 0, 0
    for i in gain:
        current_altitude += i
        max_altitude = max(max_altitude, current_altitude)
    return max_altitude
```
The algorithm consists of iterating through the input `gain` array and keeping track of the current altitude and the maximum altitude reached:

1. Initialize `max_altitude` and `current_altitude` variables to 0.
2. For each element in the `gain` array, add the gain value to the `current_altitude`.
3. Update the `max_altitude` if the `current_altitude` is greater than the `max_altitude`.
4. Return the `max_altitude` after the loop.

This approach has a time complexity of O(n), where n is the length of the input array `gain`.

## A solution in Javascript

```javascript
function largestAltitude(gain) {
    let max_altitude = 0, current_altitude = 0;
    for (let i = 0; i < gain.length; i++) {
        current_altitude += gain[i];
        max_altitude = Math.max(max_altitude, current_altitude);
    }
    return max_altitude;
}
```
The algorithm consists of iterating through the input `gain` array and keeping track of the current altitude and the maximum altitude reached:

1. Initialize `max_altitude` and `current_altitude` variables to 0.
2. For each element in the `gain` array, add the gain value to the `current_altitude`.
3. Update the `max_altitude` if the `current_altitude` is greater than the `max_altitude`.
4. Return the `max_altitude` after the loop.

This approach has a time complexity of O(n), where n is the length of the input array `gain`.


# Single-Threaded CPU

- slug: single-threaded-cpu
- difficulty: Medium

You are given `n` tasks labeled from `0` to `n - 1` represented by a 2D integer array `tasks`, where `tasks[i] = [enqueueTimei, processingTimei]` means that the `ith` task will be available to process at `enqueueTimei` and will take `processingTimei` to finish processing.

You have a single-threaded CPU that can process **at most one** task at a time and will act in the following way:

*   If the CPU is idle and there are no available tasks to process, the CPU remains idle.
*   If the CPU is idle and there are available tasks, the CPU will choose the one with the **shortest processing time**. If multiple tasks have the same shortest processing time, it will choose the task with the smallest index.
*   Once a task is started, the CPU will **process the entire task** without stopping.
*   The CPU can finish a task then start a new one instantly.

Return _the order in which the CPU will process the tasks._

**Example 1:**

**Input:** tasks = \[\[1,2\],\[2,4\],\[3,2\],\[4,1\]\]
**Output:** \[0,2,3,1\]
**Explanation:** The events go as follows:
- At time = 1, task 0 is available to process. Available tasks = {0}.
- Also at time = 1, the idle CPU starts processing task 0. Available tasks = {}.
- At time = 2, task 1 is available to process. Available tasks = {1}.
- At time = 3, task 2 is available to process. Available tasks = {1, 2}.
- Also at time = 3, the CPU finishes task 0 and starts processing task 2 as it is the shortest. Available tasks = {1}.
- At time = 4, task 3 is available to process. Available tasks = {1, 3}.
- At time = 5, the CPU finishes task 2 and starts processing task 3 as it is the shortest. Available tasks = {1}.
- At time = 6, the CPU finishes task 3 and starts processing task 1. Available tasks = {}.
- At time = 10, the CPU finishes task 1 and becomes idle.

**Example 2:**

**Input:** tasks = \[\[7,10\],\[7,12\],\[7,5\],\[7,4\],\[7,2\]\]
**Output:** \[4,3,2,0,1\]
**Explanation****:** The events go as follows:
- At time = 7, all the tasks become available. Available tasks = {0,1,2,3,4}.
- Also at time = 7, the idle CPU starts processing task 4. Available tasks = {0,1,2,3}.
- At time = 9, the CPU finishes task 4 and starts processing task 3. Available tasks = {0,1,2}.
- At time = 13, the CPU finishes task 3 and starts processing task 2. Available tasks = {0,1}.
- At time = 18, the CPU finishes task 2 and starts processing task 0. Available tasks = {1}.
- At time = 28, the CPU finishes task 0 and starts processing task 1. Available tasks = {}.
- At time = 40, the CPU finishes task 1 and becomes idle.

**Constraints:**

*   `tasks.length == n`
*   `1 <= n <= 105`
*   `1 <= enqueueTimei, processingTimei <= 109`

## A solution in Java

```java
import java.util.*;

class Solution {
    public int minimumTeachings(int n, int[][] languages, int[][] friendships) {
        Map<Integer, Set<Integer>> languageUsers = new HashMap<>();
        Set<Integer> unconnectedUsers = new HashSet<>();

        for (int[] friendship : friendships) {
            int u = friendship[0], v = friendship[1];
            boolean canCommunicate = false;

            for (int lang : languages[u - 1]) {
                if (Arrays.stream(languages[v - 1]).anyMatch(x -> x == lang)) {
                    canCommunicate = true;
                    break;
                }
            }

            if (!canCommunicate) {
                unconnectedUsers.add(u);
                unconnectedUsers.add(v);
            }
        }

        int res = unconnectedUsers.size();
        for (int i = 1; i <= n; ++i) {
            int cnt = 0;
            for (int user : unconnectedUsers) {
                if (Arrays.stream(languages[user - 1]).noneMatch(x -> x == i)) {
                    cnt++;
                }
            }
            res = Math.min(res, cnt);
        }

        return res;
    }
}
```
1. Initialize two data structures: a dictionary `language_users` to store the users for each language and a set `unconnected_users` to store users who cannot communicate with each other.
2. Iterate through the `friendships` array, and for each pair of users (u, v), check if they can communicate (common language). If they cannot, add both users to the `unconnected_users` set.
3. Initialize the result `res` with the size of the `unconnected_users` set.
4. Iterate through all languages from 1 to n, and for each language, count the number of users who don't know that language in the `unconnected_users` set. Update the result with the minimum count found.
5. Return the result.

This algorithm finds the minimum number of users that need to be taught a language to ensure all friends can communicate with each other.

## A solution in C++

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

int minimumTeachings(int n, std::vector<std::vector<int>>& languages, std::vector<std::vector<int>>& friendships) {
    std::unordered_map<int, std::unordered_set<int>> language_users;
    std::unordered_set<int> unconnected_users;

    for (const auto& friendship : friendships) {
        int u = friendship[0], v = friendship[1];
        bool canCommunicate = false;

        for (int lang : languages[u - 1]) {
            if (languages[v-1].find(lang) != languages[v-1].end()) {
                canCommunicate = true;
                break;
            }
        }

        if (!canCommunicate) {
            unconnected_users.insert(u);
            unconnected_users.insert(v);
        }
    }

    int res = unconnected_users.size();
    for (int i = 1; i <= n; ++i) {
        int cnt = 0;
        for (int user : unconnected_users) {
            if (languages[user - 1].find(i) == languages[user - 1].end()) {
                cnt++;
            }
        }
        res = std::min(res, cnt);
    }

    return res;
}
```
1. Initialize two data structures: a dictionary `language_users` to store the users for each language and a set `unconnected_users` to store users who cannot communicate with each other.
2. Iterate through the `friendships` array, and for each pair of users (u, v), check if they can communicate (common language). If they cannot, add both users to the `unconnected_users` set.
3. Initialize the result `res` with the size of the `unconnected_users` set.
4. Iterate through all languages from 1 to n, and for each language, count the number of users who don't know that language in the `unconnected_users` set. Update the result with the minimum count found.
5. Return the result.

This algorithm finds the minimum number of users that need to be taught a language to ensure all friends can communicate with each other.

## A solution in Python

```python
def minimum_teachings(n, languages, friendships):
    language_users = {}
    unconnected_users = set()

    for u, v in friendships:
        can_communicate = any(lang in languages[v-1] for lang in languages[u-1])
        if not can_communicate:
            unconnected_users.add(u)
            unconnected_users.add(v)

    res = len(unconnected_users)
    for i in range(1, n+1):
        cnt = sum(i not in languages[user-1] for user in unconnected_users)
        res = min(res, cnt)

    return res
```
1. Initialize two data structures: a dictionary `language_users` to store the users for each language and a set `unconnected_users` to store users who cannot communicate with each other.
2. Iterate through the `friendships` array, and for each pair of users (u, v), check if they can communicate (common language). If they cannot, add both users to the `unconnected_users` set.
3. Initialize the result `res` with the size of the `unconnected_users` set.
4. Iterate through all languages from 1 to n, and for each language, count the number of users who don't know that language in the `unconnected_users` set. Update the result with the minimum count found.
5. Return the result.

This algorithm finds the minimum number of users that need to be taught a language to ensure all friends can communicate with each other.

## A solution in Javascript

```javascript
function minimumTeachings(n, languages, friendships) {
    const languageUsers = {};
    const unconnectedUsers = new Set();

    friendsLoop: for (const [u, v] of friendships) {
        canCommunicate = false;

        for (const lang of languages[u - 1]) {
            if (languages[v - 1].includes(lang)) {
                canCommunicate = true;
                continue friendsLoop;
            }
        }

        if (!canCommunicate) {
            unconnectedUsers.add(u);
            unconnectedUsers.add(v);
        }
    }

    let res = unconnectedUsers.size;
    for (let i = 1; i <= n; ++i) {
        let cnt = 0;
        for (const user of unconnectedUsers) {
            if (!languages[user - 1].includes(i)) {
                cnt++;
            }
        }
        res = Math.min(res, cnt);
    }

    return res;
}
```
1. Initialize two data structures: a dictionary `language_users` to store the users for each language and a set `unconnected_users` to store users who cannot communicate with each other.
2. Iterate through the `friendships` array, and for each pair of users (u, v), check if they can communicate (common language). If they cannot, add both users to the `unconnected_users` set.
3. Initialize the result `res` with the size of the `unconnected_users` set.
4. Iterate through all languages from 1 to n, and for each language, count the number of users who don't know that language in the `unconnected_users` set. Update the result with the minimum count found.
5. Return the result.

This algorithm finds the minimum number of users that need to be taught a language to ensure all friends can communicate with each other.


# Find XOR Sum of All Pairs Bitwise AND

- slug: find-xor-sum-of-all-pairs-bitwise-and
- difficulty: Hard

The **XOR sum** of a list is the bitwise `XOR` of all its elements. If the list only contains one element, then its **XOR sum** will be equal to this element.

*   For example, the **XOR sum** of `[1,2,3,4]` is equal to `1 XOR 2 XOR 3 XOR 4 = 4`, and the **XOR sum** of `[3]` is equal to `3`.

You are given two **0-indexed** arrays `arr1` and `arr2` that consist only of non-negative integers.

Consider the list containing the result of `arr1[i] AND arr2[j]` (bitwise `AND`) for every `(i, j)` pair where `0 <= i < arr1.length` and `0 <= j < arr2.length`.

Return _the **XOR sum** of the aforementioned list_.

**Example 1:**

**Input:** arr1 = \[1,2,3\], arr2 = \[6,5\]
**Output:** 0
**Explanation:** The list = \[1 AND 6, 1 AND 5, 2 AND 6, 2 AND 5, 3 AND 6, 3 AND 5\] = \[0,1,2,0,2,1\].
The XOR sum = 0 XOR 1 XOR 2 XOR 0 XOR 2 XOR 1 = 0.

**Example 2:**

**Input:** arr1 = \[12\], arr2 = \[4\]
**Output:** 4
**Explanation:** The list = \[12 AND 4\] = \[4\]. The XOR sum = 4.

**Constraints:**

*   `1 <= arr1.length, arr2.length <= 105`
*   `0 <= arr1[i], arr2[j] <= 109`

## A solution in Java

```java
public int[] decode(int[] encoded) {
    int n = encoded.length + 1;
    int total_xor = 0;
    for (int i = 1; i <= n; ++i) {
        total_xor ^= i;
    }
    int encoded_xor = 0;
    for (int i = 1; i < n - 1; i += 2) {
        encoded_xor ^= encoded[i];
    }
    int[] perm = new int[n];
    perm[0] = total_xor ^ encoded_xor;
    for (int i = 1; i < n; ++i) {
        perm[i] = perm[i - 1] ^ encoded[i - 1];
    }
    return perm;
}
```
1. Calculate the XOR of all integers from 1 to n (inclusive), and store it in the `total_xor` variable.
2. Calculate the XOR of all elements of the encoded array with odd indices (starting from index 1), and store it in the `encoded_xor` variable.
3. The first element of the perm array is calculated by XOR'ing `total_xor` and `encoded_xor`.
4. Loop through the range 1 to n-1 (inclusive) and calculate the rest of the perm array elements using the following formula: `perm[i] = perm[i - 1] ^ encoded[i - 1]`.
5. Return the reconstructed perm array.

## A solution in C++

```cpp
#include <vector>

std::vector<int> decode(std::vector<int>& encoded) {
    int n = encoded.size() + 1;
    int total_xor = 0;
    for (int i = 1; i <= n; ++i) {
        total_xor ^= i;
    }
    int encoded_xor = 0;
    for (int i = 1; i < n - 1; i += 2) {
        encoded_xor ^= encoded[i];
    }
    std::vector<int> perm(n);
    perm[0] = total_xor ^ encoded_xor;
    for (int i = 1; i < n; ++i) {
        perm[i] = perm[i - 1] ^ encoded[i - 1];
    }
    return perm;
}
```
1. Calculate the XOR of all integers from 1 to n (inclusive), and store it in the `total_xor` variable.
2. Calculate the XOR of all elements of the encoded array with odd indices (starting from index 1), and store it in the `encoded_xor` variable.
3. The first element of the perm array is calculated by XOR'ing `total_xor` and `encoded_xor`.
4. Loop through the range 1 to n-1 (inclusive) and calculate the rest of the perm array elements using the following formula: `perm[i] = perm[i - 1] ^ encoded[i - 1]`.
5. Return the reconstructed perm array.

## A solution in Python

```python
def decode(encoded):
    n = len(encoded) + 1
    total_xor = 0
    for i in range(1, n + 1):
        total_xor ^= i
    encoded_xor = 0
    for i in range(1, n - 1, 2):
        encoded_xor ^= encoded[i]
    perm = [total_xor ^ encoded_xor]
    for i in range(1, n):
        perm.append(perm[-1] ^ encoded[i - 1])
    return perm
```
1. Calculate the XOR of all integers from 1 to n (inclusive), and store it in the `total_xor` variable.
2. Calculate the XOR of all elements of the encoded array with odd indices (starting from index 1), and store it in the `encoded_xor` variable.
3. The first element of the perm array is calculated by XOR'ing `total_xor` and `encoded_xor`.
4. Loop through the range 1 to n-1 (inclusive) and calculate the rest of the perm array elements using the following formula: `perm[i] = perm[i - 1] ^ encoded[i - 1]`.
5. Return the reconstructed perm array.

## A solution in Javascript

```javascript
function decode(encoded) {
    const n = encoded.length + 1;
    let total_xor = 0;
    for (let i = 1; i <= n; ++i) {
        total_xor ^= i;
    }
    let encoded_xor = 0;
    for (let i = 1; i < n - 1; i += 2) {
        encoded_xor ^= encoded[i];
    }
    const perm = [total_xor ^ encoded_xor];
    for (let i = 1; i < n; ++i) {
        perm.push(perm[i - 1] ^ encoded[i - 1]);
    }
    return perm;
}
```
1. Calculate the XOR of all integers from 1 to n (inclusive), and store it in the `total_xor` variable.
2. Calculate the XOR of all elements of the encoded array with odd indices (starting from index 1), and store it in the `encoded_xor` variable.
3. The first element of the perm array is calculated by XOR'ing `total_xor` and `encoded_xor`.
4. Loop through the range 1 to n-1 (inclusive) and calculate the rest of the perm array elements using the following formula: `perm[i] = perm[i - 1] ^ encoded[i - 1]`.
5. Return the reconstructed perm array.


# Remove Duplicates From an Unsorted Linked List

- slug: remove-duplicates-from-an-unsorted-linked-list
- difficulty: Medium

Given the `head` of a linked list, find all the values that appear **more than once** in the list and delete the nodes that have any of those values.

Return _the linked list after the deletions._

**Example 1:**

**Input:** head = \[1,2,3,2\]
**Output:** \[1,3\]
**Explanation:** 2 appears twice in the linked list, so all 2's should be deleted. After deleting all 2's, we are left with \[1,3\].

**Example 2:**

**Input:** head = \[2,1,1,2\]
**Output:** \[\]
**Explanation:** 2 and 1 both appear twice. All the elements should be deleted.

**Example 3:**

**Input:** head = \[3,2,2,1,3,2,4\]
**Output:** \[1,4\]
**Explanation:** 3 appears twice and 2 appears three times. After deleting all 3's and 2's, we are left with \[1,4\].

**Constraints:**

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

## A solution in Java

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

public class Solution {
    static final int MOD = 1000000007;

    public static ArrayList<Integer> productWays(int[][] queries) {
        ArrayList<Integer> res = new ArrayList<>();
        for (int[] q : queries) {
            int n = q[0], k = q[1];

            List<Integer> pf = new ArrayList<>();
            Map<Integer, Integer> pm = new HashMap<>();
            for (int i = 2; i * i <= k; ++i) {
                int cnt = 0;
                while (k % i == 0) {
                    cnt++;
                    k /= i;
                }
                if (cnt != 0) {
                    pf.add(cnt);
                    pm.put(cnt, pm.getOrDefault(cnt, 0) + 1);
                }
            }

            if (k > 1) {
                pm.put(k, pm.getOrDefault(k, 0) + 1);
                pf.add(1);
            }

            long ans = 1;
            for (int p : pf) {
                ans = (ans * (p * (n - 1) + 1)) % MOD;
            }

            res.add((int) ans);
        }
        return res;
    }
}
```
1. For each query, find the prime factors of number k.
2. Store the counts of each prime factor in an array and a map.
3. Initialize the answer for the current query to 1.
4. Iterate through the array of prime factor counts and multiply the answer with the result of each count multiplied by n-1 and added 1. Take the modulo (1e9 + 7) in each step.
5. Append the answer for the current query to the result list and return the result list.

## A solution in C++

```cpp
#include <vector>
#include <map>
#include <cmath>

using namespace std;

const int MOD = 1e9 + 7;

vector<int> productWays(vector<vector<int>>& queries) {
    vector<int> res;
    for (auto& q : queries) {
        int n = q[0], k = q[1];

        vector<int> pf;
        map<int, int> pm;
        for (int i = 2; i * i <= k; ++i) {
            int cnt = 0;
            while (k % i == 0) {
                cnt++;
                k /= i;
            }
            if (cnt) {
                pf.push_back(cnt);
                pm[cnt]++;
            }
        }

        if (k > 1) {
            pm[k]++;
            pf.push_back(1);
        }

        long long ans = 1;
        for (int p : pf) {
            ans = (ans * (p * (n - 1) + 1)) % MOD;
        }

        res.push_back(ans);
    }
    return res;
}
```
1. For each query, find the prime factors of number k.
2. Store the counts of each prime factor in an array and a map.
3. Initialize the answer for the current query to 1.
4. Iterate through the array of prime factor counts and multiply the answer with the result of each count multiplied by n-1 and added 1. Take the modulo (1e9 + 7) in each step.
5. Append the answer for the current query to the result list and return the result list.

## A solution in Python

```python
from collections import defaultdict
from typing import List

MOD = 10**9 + 7

def product_ways(queries: List[List[int]]) -> List[int]:
    res = []
    for n, k in queries:
        pf = []
        pm = defaultdict(int)

        i = 2
        while i * i <= k:
            cnt = 0
            while k % i == 0:
                cnt += 1
                k //= i
            if cnt:
                pf.append(cnt)
                pm[cnt] += 1
            i += 1

        if k > 1:
            pm[k] += 1
            pf.append(1)

        ans = 1
        for p in pf:
            ans = (ans * (p * (n - 1) + 1)) % MOD

        res.append(ans)
    return res
```
1. For each query, find the prime factors of number k.
2. Store the counts of each prime factor in an array and a map.
3. Initialize the answer for the current query to 1.
4. Iterate through the array of prime factor counts and multiply the answer with the result of each count multiplied by n-1 and added 1. Take the modulo (1e9 + 7) in each step.
5. Append the answer for the current query to the result list and return the result list.

## A solution in Javascript

```javascript
const MOD = 1e9 + 7;

function productWays(queries) {
    const res = [];
    for (const [n, k] of queries) {
        const pf = [];
        const pm = {};

        for (let i = 2; i * i <= k; i++) {
            let cnt = 0;
            let kMutable = k;
            while (kMutable % i === 0) {
                cnt++;
                kMutable /= i;
            }
            if (cnt !== 0) {
                pf.push(cnt);
                if (!pm[cnt]) pm[cnt] = 0;
                pm[cnt]++;
            }
        }

        if (k > 1) {
            if (!pm[k]) pm[k] = 0;
            pm[k]++;
            pf.push(1);
        }

        let ans = 1;
        for (const p of pf) {
            ans = (ans * (p * (n - 1) + 1)) % MOD;
        }

        res.push(ans);
    }
    return res;
}
```
1. For each query, find the prime factors of number k.
2. Store the counts of each prime factor in an array and a map.
3. Initialize the answer for the current query to 1.
4. Iterate through the array of prime factor counts and multiply the answer with the result of each count multiplied by n-1 and added 1. Take the modulo (1e9 + 7) in each step.
5. Append the answer for the current query to the result list and return the result list.


# Sum of Digits in Base K

- slug: sum-of-digits-in-base-k
- difficulty: Easy

Given an integer `n` (in base `10`) and a base `k`, return _the **sum** of the digits of_ `n` _**after** converting_ `n` _from base_ `10` _to base_ `k`.

After converting, each digit should be interpreted as a base `10` number, and the sum should be returned in base `10`.

**Example 1:**

**Input:** n = 34, k = 6
**Output:** 9
**Explanation:** 34 (base 10) expressed in base 6 is 54. 5 + 4 = 9.

**Example 2:**

**Input:** n = 10, k = 10
**Output:** 1
**Explanation:** n is already in base 10. 1 + 0 = 1.

**Constraints:**

*   `1 <= n <= 100`
*   `2 <= k <= 10`

## A solution in Java

```java
public int sumBase(int n, int k) {
    int sum = 0;
    while (n > 0) {
        sum += n % k;
        n /= k;
    }
    return sum;
}
```
The algorithm is straightforward for converting a number from base 10 to base k and summing its digits. We use a while loop to repeatedly divide the number n by k, until n becomes 0. In each iteration, we add the remainder (n % k) to the sum, and update n by dividing it by k and taking the floor of the result. In the end, we return the sum.

## A solution in C++

```cpp
int sumBase(int n, int k) {
    int sum = 0;
    while (n > 0) {
        sum += n % k;
        n /= k;
    }
    return sum;
}
```
The algorithm is straightforward for converting a number from base 10 to base k and summing its digits. We use a while loop to repeatedly divide the number n by k, until n becomes 0. In each iteration, we add the remainder (n % k) to the sum, and update n by dividing it by k and taking the floor of the result. In the end, we return the sum.

## A solution in Python

```python
def sum_base(n: int, k: int) -> int:
    s = 0
    while n:
        s += n % k
        n //= k
    return s
```
The algorithm is straightforward for converting a number from base 10 to base k and summing its digits. We use a while loop to repeatedly divide the number n by k, until n becomes 0. In each iteration, we add the remainder (n % k) to the sum, and update n by dividing it by k and taking the floor of the result. In the end, we return the sum.

## A solution in Javascript

```javascript
function sumBase(n, k) {
    let sum = 0;
    while (n > 0) {
        sum += n % k;
        n = Math.floor(n / k);
    }
    return sum;
}
```
The algorithm is straightforward for converting a number from base 10 to base k and summing its digits. We use a while loop to repeatedly divide the number n by k, until n becomes 0. In each iteration, we add the remainder (n % k) to the sum, and update n by dividing it by k and taking the floor of the result. In the end, we return the sum.


# Frequency of the Most Frequent Element

- slug: frequency-of-the-most-frequent-element
- difficulty: Medium

The **frequency** of an element is the number of times it occurs in an array.

You are given an integer array `nums` and an integer `k`. In one operation, you can choose an index of `nums` and increment the element at that index by `1`.

Return _the **maximum possible frequency** of an element after performing **at most**_ `k` _operations_.

**Example 1:**

**Input:** nums = \[1,2,4\], k = 5
**Output:** 3
**Explanation:** Increment the first element three times and the second element two times to make nums = \[4,4,4\].
4 has a frequency of 3.

**Example 2:**

**Input:** nums = \[1,4,8,13\], k = 5
**Output:** 2
**Explanation:** There are multiple optimal solutions:
- Increment the first element three times to make nums = \[4,4,8,13\]. 4 has a frequency of 2.
- Increment the second element four times to make nums = \[1,8,8,13\]. 8 has a frequency of 2.
- Increment the third element five times to make nums = \[1,4,13,13\]. 13 has a frequency of 2.

**Example 3:**

**Input:** nums = \[3,9,6\], k = 2
**Output:** 1

**Constraints:**

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

## A solution in Java

```java
public int maxFrequency(int[] nums, int k) {
    Arrays.sort(nums);
    int n = nums.length, i = 0;
    long sum = 0;
    int max_freq = 0;

    for (int j = 0; j < n; j++) {
        sum += nums[j];
        while (sum + k < (long) nums[j] * (j - i + 1)) {
            sum -= nums[i++];
        }
        max_freq = Math.max(max_freq, j - i + 1);
    }

    return max_freq;
}
```
1. Sort the input array `nums`.
2. Initialize variables `n` as the length of `nums`, `i` as 0, `sum` as 0, and `max_freq` as 0.
3. Iterate through the sorted array with index `j`.
   a. Add each element to the `sum`.
   b. In a while loop, if `sum + k` is less than `nums[j] * (j - i + 1)`, subtract `nums[i]` from `sum`, and increment `i`.
   c. Update the `max_freq` by taking the maximum of the current `max_freq` and `j - i + 1`.
4. Return the final `max_freq` as the answer.

## A solution in C++

```cpp
int maxFrequency(vector<int>& nums, int k) {
    sort(nums.begin(), nums.end());
    int n = nums.size(), i = 0;
    long long sum = 0;
    int max_freq = 0;

    for (int j = 0; j < n; j++) {
        sum += nums[j];
        while (sum + k < static_cast<long long>(nums[j]) * (j - i + 1)) {
            sum -= nums[i++];
        }
        max_freq = max(max_freq, j - i + 1);
    }

    return max_freq;
}
```
1. Sort the input array `nums`.
2. Initialize variables `n` as the length of `nums`, `i` as 0, `sum` as 0, and `max_freq` as 0.
3. Iterate through the sorted array with index `j`.
   a. Add each element to the `sum`.
   b. In a while loop, if `sum + k` is less than `nums[j] * (j - i + 1)`, subtract `nums[i]` from `sum`, and increment `i`.
   c. Update the `max_freq` by taking the maximum of the current `max_freq` and `j - i + 1`.
4. Return the final `max_freq` as the answer.

## A solution in Python

```python
def maxFrequency(nums: List[int], k: int) -> int:
    nums.sort()
    n, i, s, max_freq = len(nums), 0, 0, 0

    for j in range(n):
        s += nums[j]
        while s + k < nums[j] * (j - i + 1):
            s -= nums[i]
            i += 1
        max_freq = max(max_freq, j - i + 1)

    return max_freq
```
1. Sort the input array `nums`.
2. Initialize variables `n` as the length of `nums`, `i` as 0, `sum` as 0, and `max_freq` as 0.
3. Iterate through the sorted array with index `j`.
   a. Add each element to the `sum`.
   b. In a while loop, if `sum + k` is less than `nums[j] * (j - i + 1)`, subtract `nums[i]` from `sum`, and increment `i`.
   c. Update the `max_freq` by taking the maximum of the current `max_freq` and `j - i + 1`.
4. Return the final `max_freq` as the answer.

## A solution in Javascript

```javascript
function maxFrequency(nums, k) {
    nums.sort((a, b) => a - b);
    let n = nums.length, i = 0;
    let sum = 0;
    let max_freq = 0;

    for (let j = 0; j < n; j++) {
        sum += nums[j];
        while (sum + k < nums[j] * (j - i + 1)) {
            sum -= nums[i++];
        }
        max_freq = Math.max(max_freq, j - i + 1);
    }

    return max_freq;
}
```
1. Sort the input array `nums`.
2. Initialize variables `n` as the length of `nums`, `i` as 0, `sum` as 0, and `max_freq` as 0.
3. Iterate through the sorted array with index `j`.
   a. Add each element to the `sum`.
   b. In a while loop, if `sum + k` is less than `nums[j] * (j - i + 1)`, subtract `nums[i]` from `sum`, and increment `i`.
   c. Update the `max_freq` by taking the maximum of the current `max_freq` and `j - i + 1`.
4. Return the final `max_freq` as the answer.


# Longest Substring Of All Vowels in Order

- slug: longest-substring-of-all-vowels-in-order
- difficulty: Medium

A string is considered **beautiful** if it satisfies the following conditions:

*   Each of the 5 English vowels (`'a'`, `'e'`, `'i'`, `'o'`, `'u'`) must appear **at least once** in it.
*   The letters must be sorted in **alphabetical order** (i.e. all `'a'`s before `'e'`s, all `'e'`s before `'i'`s, etc.).

For example, strings `"aeiou "` and `"aaaaaaeiiiioou "` are considered **beautiful**, but `"uaeio "`, `"aeoiu "`, and `"aaaeeeooo "` are **not beautiful**.

Given a string `word` consisting of English vowels, return _the **length of the longest beautiful substring** of_ `word`_. If no such substring exists, return_ `0`.

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

**Example 1:**

**Input:** word =  "aeiaaioaaaaeiiiiouuuooaauuaeiu "
**Output:** 13
**Explanation:** The longest beautiful substring in word is  "aaaaeiiiiouuu " of length 13.

**Example 2:**

**Input:** word =  "aeeeiiiioooauuuaeiou "
**Output:** 5
**Explanation:** The longest beautiful substring in word is  "aeiou " of length 5.

**Example 3:**

**Input:** word =  "a "
**Output:** 0
**Explanation:** There is no beautiful substring, so return 0.

**Constraints:**

*   `1 <= word.length <= 5 * 105`
*   `word` consists of characters `'a'`, `'e'`, `'i'`, `'o'`, and `'u'`.

## A solution in Java

```java
public int[] decode(int[] encoded, int first) {
    int[] arr = new int[encoded.length + 1];
    arr[0] = first;
    for (int i = 0; i < encoded.length; i++) {
        arr[i + 1] = arr[i] ^ encoded[i];
    }
    return arr;
}
```
The algorithm is quite straightforward. Initialize the original array (arr) with the first element given. Then, for every encoded element, we calculate the arr element by using the XOR operation between the previous arr element and the current encoded element. Iterate through the encoded array until you've calculated all arr elements. Finally, return the original array.

This algorithm follows the property of XOR, which is A ^ B = C means A = B ^ C and B = A ^ C. Since encoded[i] = arr[i] XOR arr[i+1], we can find arr[i+1] by doing encoded[i] XOR arr[i].

## A solution in C++

```cpp
#include <vector>

std::vector<int> decode(std::vector<int>& encoded, int first) {
    std::vector<int> arr(encoded.size() + 1);
    arr[0] = first;
    for (int i = 0; i < encoded.size(); i++) {
        arr[i + 1] = arr[i] ^ encoded[i];
    }
    return arr;
}
```
The algorithm is quite straightforward. Initialize the original array (arr) with the first element given. Then, for every encoded element, we calculate the arr element by using the XOR operation between the previous arr element and the current encoded element. Iterate through the encoded array until you've calculated all arr elements. Finally, return the original array.

This algorithm follows the property of XOR, which is A ^ B = C means A = B ^ C and B = A ^ C. Since encoded[i] = arr[i] XOR arr[i+1], we can find arr[i+1] by doing encoded[i] XOR arr[i].

## A solution in Python

```python
def decode(encoded, first):
    arr = [first]
    for num in encoded:
        arr.append(arr[-1] ^ num)
    return arr
```
The algorithm is quite straightforward. Initialize the original array (arr) with the first element given. Then, for every encoded element, we calculate the arr element by using the XOR operation between the previous arr element and the current encoded element. Iterate through the encoded array until you've calculated all arr elements. Finally, return the original array.

This algorithm follows the property of XOR, which is A ^ B = C means A = B ^ C and B = A ^ C. Since encoded[i] = arr[i] XOR arr[i+1], we can find arr[i+1] by doing encoded[i] XOR arr[i].

## A solution in Javascript

```javascript
function decode(encoded, first) {
    const arr = [first];
    for (let i = 0; i < encoded.length; i++) {
        arr.push(arr[i] ^ encoded[i]);
    }
    return arr;
}
```
The algorithm is quite straightforward. Initialize the original array (arr) with the first element given. Then, for every encoded element, we calculate the arr element by using the XOR operation between the previous arr element and the current encoded element. Iterate through the encoded array until you've calculated all arr elements. Finally, return the original array.

This algorithm follows the property of XOR, which is A ^ B = C means A = B ^ C and B = A ^ C. Since encoded[i] = arr[i] XOR arr[i+1], we can find arr[i+1] by doing encoded[i] XOR arr[i].


# Maximum Building Height

- slug: maximum-building-height
- difficulty: Hard

You want to build `n` new buildings in a city. The new buildings will be built in a line and are labeled from `1` to `n`.

However, there are city restrictions on the heights of the new buildings:

*   The height of each building must be a non-negative integer.
*   The height of the first building **must** be `0`.
*   The height difference between any two adjacent buildings **cannot exceed** `1`.

Additionally, there are city restrictions on the maximum height of specific buildings. These restrictions are given as a 2D integer array `restrictions` where `restrictions[i] = [idi, maxHeighti]` indicates that building `idi` must have a height **less than or equal to** `maxHeighti`.

It is guaranteed that each building will appear **at most once** in `restrictions`, and building `1` will **not** be in `restrictions`.

Return _the **maximum possible height** of the **tallest** building_.

**Example 1:**

**Input:** n = 5, restrictions = \[\[2,1\],\[4,1\]\]
**Output:** 2
**Explanation:** The green area in the image indicates the maximum allowed height for each building.
We can build the buildings with heights \[0,1,2,1,2\], and the tallest building has a height of 2.

**Example 2:**

**Input:** n = 6, restrictions = \[\]
**Output:** 5
**Explanation:** The green area in the image indicates the maximum allowed height for each building.
We can build the buildings with heights \[0,1,2,3,4,5\], and the tallest building has a height of 5.

**Example 3:**

**Input:** n = 10, restrictions = \[\[5,3\],\[2,5\],\[7,4\],\[10,3\]\]
**Output:** 5
**Explanation:** The green area in the image indicates the maximum allowed height for each building.
We can build the buildings with heights \[0,1,2,3,3,4,4,5,4,3\], and the tallest building has a height of 5.

**Constraints:**

*   `2 <= n <= 109`
*   `0 <= restrictions.length <= min(n - 1, 105)`
*   `2 <= idi <= n`
*   `idi` is **unique**.
*   `0 <= maxHeighti <= 109`

## A solution in Java

```java
import java.util.*;

class Solution {
    private void dfs(int node, int[] visited, Map<Integer, List<Integer>> graph, List<Integer> group) {
        if (visited[node] == 1) return;
        visited[node] = 1;
        group.add(node);
        for (int neighbor : graph.get(node)) dfs(neighbor, visited, graph, group);
    }

    public int minimumHammingDistance(int[] source, int[] target, int[][] allowedSwaps) {
        int n = source.length;
        Map<Integer, List<Integer>> graph = new HashMap<>();
        for (int[] swap : allowedSwaps) {
            graph.computeIfAbsent(swap[0], k -> new ArrayList<>()).add(swap[1]);
            graph.computeIfAbsent(swap[1], k -> new ArrayList<>()).add(swap[0]);
        }

        int res = 0;
        int[] visited = new int[n];
        for (int i = 0; i < n; ++i) {
            if (visited[i] == 0) {
                List<Integer> group = new ArrayList<>();
                dfs(i, visited, graph, group);
                Map<Integer, Integer> count = new HashMap<>();

                for (int node : group) count.put(source[node], count.getOrDefault(source[node], 0) + 1);
                for (int node : group) if (count.getOrDefault(target[node], 0) > 0) {
                    res++;
                    count.put(target[node], count.get(target[node]) - 1);
                }
            }
        }

        return n - res;
    }
}
```
1. We build an adjacency list graph from the allowed swap pairs, so that we can traverse it later.
2. We traverse the graph with a depth-first-search function (dfs) to find connected components.
3. For each connected component, we count the occurrences of each value in the source array and store it in a dictionary.
4. We iterate through the target array for the same connected component and decrement the count of target values in the dictionary. If the count is greater than 0, it means there is a match, and we increase the result by 1.
5. Finally, we return the difference between the length of the arrays and the matched pairs count to compute the minimum Hamming distance.

## A solution in C++

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

using namespace std;

void dfs(int node, vector<int>& visited, unordered_map<int, vector<int>>& graph, vector<int>& group) {
    if (visited[node]) return;
    visited[node] = 1;
    group.push_back(node);
    for (int neighbor : graph[node]) dfs(neighbor, visited, graph, group);
}

int minimumHammingDistance(vector<int>& source, vector<int>& target, vector<vector<int>>& allowedSwaps) {
    int n = source.size();
    unordered_map<int, vector<int>> graph;
    for (auto& swap : allowedSwaps) {
        graph[swap[0]].push_back(swap[1]);
        graph[swap[1]].push_back(swap[0]);
    }

    int res = 0;
    vector<int> visited(n, 0);
    for (int i = 0; i < n; ++i) {
        if (!visited[i]) {
            vector<int> group;
            dfs(i, visited, graph, group);
            unordered_map<int, int> count;

            for (int node : group) count[source[node]]++;
            for (int node : group) if (count[target[node]]-- > 0) res++;
        }
    }

    return n - res;
}
```
1. We build an adjacency list graph from the allowed swap pairs, so that we can traverse it later.
2. We traverse the graph with a depth-first-search function (dfs) to find connected components.
3. For each connected component, we count the occurrences of each value in the source array and store it in a dictionary.
4. We iterate through the target array for the same connected component and decrement the count of target values in the dictionary. If the count is greater than 0, it means there is a match, and we increase the result by 1.
5. Finally, we return the difference between the length of the arrays and the matched pairs count to compute the minimum Hamming distance.

## A solution in Python

```python
from collections import defaultdict

def dfs(node, visited, graph, group):
    if visited[node]:
        return
    visited[node] = 1
    group.append(node)
    for neighbor in graph[node]:
        dfs(neighbor, visited, graph, group)

def minimumHammingDistance(source, target, allowedSwaps):
    n = len(source)
    graph = defaultdict(list)
    for a, b in allowedSwaps:
        graph[a].append(b)
        graph[b].append(a)

    res = 0
    visited = [0] * n
    for i in range(n):
        if not visited[i]:
            group = []
            dfs(i, visited, graph, group)
            count = defaultdict(int)

            for node in group:
                count[source[node]] += 1
            for node in group:
                if count[target[node]] > 0:
                    res += 1
                    count[target[node]] -= 1

    return n - res
```
1. We build an adjacency list graph from the allowed swap pairs, so that we can traverse it later.
2. We traverse the graph with a depth-first-search function (dfs) to find connected components.
3. For each connected component, we count the occurrences of each value in the source array and store it in a dictionary.
4. We iterate through the target array for the same connected component and decrement the count of target values in the dictionary. If the count is greater than 0, it means there is a match, and we increase the result by 1.
5. Finally, we return the difference between the length of the arrays and the matched pairs count to compute the minimum Hamming distance.

## A solution in Javascript

```javascript
function minimumHammingDistance(source, target, allowedSwaps) {
    const n = source.length;
    const graph = new Map();

    for (const [a, b] of allowedSwaps) {
        if (!graph.has(a)) graph.set(a, []);
        if (!graph.has(b)) graph.set(b, []);
        graph.get(a).push(b);
        graph.get(b).push(a);
    }

    function dfs(node, visited, group) {
        if (visited[node]) return;
        visited[node] = 1;
        group.push(node);
        for (const neighbor of (graph.get(node) || [])) dfs(neighbor, visited, group);
    }

    let res = 0;
    const visited = new Array(n).fill(0);
    for (let i = 0; i < n; ++i) {
        if (!visited[i]) {
            const group = [];
            dfs(i, visited, group);
            const count = new Map();

            for (const node of group) count.set(source[node], (count.get(source[node]) || 0) + 1);
            for (const node of group) {
                if (count.get(target[node]) > 0) {
                    res++;
                    count.set(target[node], count.get(target[node]) - 1);
                }
            }
        }
    }

    return n - res;
}
```
1. We build an adjacency list graph from the allowed swap pairs, so that we can traverse it later.
2. We traverse the graph with a depth-first-search function (dfs) to find connected components.
3. For each connected component, we count the occurrences of each value in the source array and store it in a dictionary.
4. We iterate through the target array for the same connected component and decrement the count of target values in the dictionary. If the count is greater than 0, it means there is a match, and we increase the result by 1.
5. Finally, we return the difference between the length of the arrays and the matched pairs count to compute the minimum Hamming distance.


# Next Palindrome Using Same Digits

- slug: next-palindrome-using-same-digits
- difficulty: Hard

You are given a numeric string `num`, representing a very large **palindrome**.

Return _the **smallest palindrome larger than**_ `num` _that can be created by rearranging its digits. If no such palindrome exists, return an empty string_ `" "`.

A **palindrome** is a number that reads the same backward as forward.

**Example 1:**

**Input:** num =  "1221 "
**Output:**  "2112 "
**Explanation:** The next palindrome larger than  "1221 " is  "2112 ".

**Example 2:**

**Input:** num =  "32123 "
**Output:**  " "
**Explanation:** No palindromes larger than  "32123 " can be made by rearranging the digits.

**Example 3:**

**Input:** num =  "45544554 "
**Output:**  "54455445 "
**Explanation:** The next palindrome larger than  "45544554 " is  "54455445 ".

**Constraints:**

*   `1 <= num.length <= 105`
*   `num` is a **palindrome**.

## A solution in Java

```java
import java.util.Arrays;

public class Solution {
    public String nextPalindrome(String num) {
        int n = num.length();
        char[] firstHalf = num.substring(0, (n + 1) / 2).toCharArray();
        if (!nextPermutation(firstHalf)) return "";

        String secondHalf = new StringBuilder(String.valueOf(firstHalf)).reverse().toString();
        if (n % 2 == 1) secondHalf = secondHalf.substring(1);
        return String.valueOf(firstHalf) + secondHalf;
    }

    private boolean nextPermutation(char[] array) {
        int n = array.length;
        int k = n - 2;
        while (k >= 0 && array[k] >= array[k + 1]) k--;

        if (k == -1) return false;

        int l = n - 1;
        while (array[l] <= array[k]) l--;

        char temp = array[k];
        array[k] = array[l];
        array[l] = temp;

        int left = k + 1, right = n - 1;
        while (left < right) {
            temp = array[left];
            array[left++] = array[right];
            array[right--] = temp;
        }

        return true;
    }
}
```
The idea here is to generate the next possible larger palindrome by just manipulating the first half of the input string (since it's already a palindrome). We first extract the first half of the input string. For odd lengths, the middle character will be included in the first half as well.

Next, we generate the next permutation of the first half in lexicographically increasing order (hence it is guaranteed to be greater). If there's no such permutation, we return an empty string. For Python, we generate all possible permutations, convert them back to strings and return the smallest possible greater one. Note that it may not be the most efficient way for Python.

For the other half, we simply reverse the first half, and skip the middle character if the input length is odd.

Finally, we concatenate both halves and return the resulting string. If there's no next greater palindrome, the function returns an empty string.

## A solution in C++

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

string nextPalindrome(string num) {
    int n = num.size();
    string firstHalf = num.substr(0, (n + 1) / 2);
    next_permutation(firstHalf.begin(), firstHalf.end());

    if (firstHalf > num.substr(0, (n + 1) / 2)) {
        string secondHalf = firstHalf;
        reverse(secondHalf.begin(), secondHalf.end());
        if (n % 2 == 1) secondHalf = secondHalf.substr(1);
        return firstHalf + secondHalf;
    }

    return "";
}
```
The idea here is to generate the next possible larger palindrome by just manipulating the first half of the input string (since it's already a palindrome). We first extract the first half of the input string. For odd lengths, the middle character will be included in the first half as well.

Next, we generate the next permutation of the first half in lexicographically increasing order (hence it is guaranteed to be greater). If there's no such permutation, we return an empty string. For Python, we generate all possible permutations, convert them back to strings and return the smallest possible greater one. Note that it may not be the most efficient way for Python.

For the other half, we simply reverse the first half, and skip the middle character if the input length is odd.

Finally, we concatenate both halves and return the resulting string. If there's no next greater palindrome, the function returns an empty string.

## A solution in Python

```python
from itertools import permutations

def nextPalindrome(num: str) -> str:
    n = len(num)
    first_half = num[:(n + 1) // 2]
    candidates = sorted(set(int("".join(p)) for p in permutations(first_half)))

    for c in candidates:
        c_str = str(c)
        second_half = c_str[::-1]
        if n % 2 == 1: second_half = second_half[1:]
        candidate_str = c_str + second_half

        if candidate_str > num:
            return candidate_str

    return ""
```
The idea here is to generate the next possible larger palindrome by just manipulating the first half of the input string (since it's already a palindrome). We first extract the first half of the input string. For odd lengths, the middle character will be included in the first half as well.

Next, we generate the next permutation of the first half in lexicographically increasing order (hence it is guaranteed to be greater). If there's no such permutation, we return an empty string. For Python, we generate all possible permutations, convert them back to strings and return the smallest possible greater one. Note that it may not be the most efficient way for Python.

For the other half, we simply reverse the first half, and skip the middle character if the input length is odd.

Finally, we concatenate both halves and return the resulting string. If there's no next greater palindrome, the function returns an empty string.

## A solution in Javascript

```javascript
function nextPermutation(array) {
    let n = array.length;
    let k = n - 2;
    while (k >= 0 && array[k] >= array[k + 1]) k--;

    if (k === -1) return false;

    let l = n - 1;
    while (array[l] <= array[k]) l--;

    [array[k], array[l]] = [array[l], array[k]];

    let left = k + 1, right = n - 1;
    while (left < right) {
        [array[left], array[right]] = [array[right], array[left]];
        left++;
        right--;
    }

    return true;
}

function nextPalindrome(num) {
    let n = num.length;
    let firstHalf = num.slice(0, (n + 1) / 2).split('');
    if (!nextPermutation(firstHalf)) return "";

    let secondHalf = firstHalf.slice().reverse();
    if (n % 2 === 1) secondHalf.shift();
    return firstHalf.join('') + secondHalf.join('');
}
```
The idea here is to generate the next possible larger palindrome by just manipulating the first half of the input string (since it's already a palindrome). We first extract the first half of the input string. For odd lengths, the middle character will be included in the first half as well.

Next, we generate the next permutation of the first half in lexicographically increasing order (hence it is guaranteed to be greater). If there's no such permutation, we return an empty string. For Python, we generate all possible permutations, convert them back to strings and return the smallest possible greater one. Note that it may not be the most efficient way for Python.

For the other half, we simply reverse the first half, and skip the middle character if the input length is odd.

Finally, we concatenate both halves and return the resulting string. If there's no next greater palindrome, the function returns an empty string.