# Closest Fair Integer

- slug: closest-fair-integer
- difficulty: Medium

You are given a **positive** integer `n`.

We call an integer `k` fair if the number of **even** digits in `k` is equal to the number of **odd** digits in it.

Return _the **smallest** fair integer that is **greater than or equal** to_ `n`.

**Example 1:**

**Input:** n = 2
**Output:** 10
**Explanation:** The smallest fair integer that is greater than or equal to 2 is 10.
10 is fair because it has an equal number of even and odd digits (one odd digit and one even digit).

**Example 2:**

**Input:** n = 403
**Output:** 1001
**Explanation:** The smallest fair integer that is greater than or equal to 403 is 1001.
1001 is fair because it has an equal number of even and odd digits (two odd digits and two even digits).

**Constraints:**

*   `1 <= n <= 109`

## A solution in Java

```java
public int smallestFairNumber(int n) {
    while (true) {
        int k = n;
        int even = 0, odd = 0;
        while (k > 0) {
            k % 2 == 0 ? even++ : odd++;
            k /= 10;
        }
        if (even == odd) return n;
        n++;
    }
}
```
The algorithm starts from the given number `n` and check if it is fair or not. A fair number `k` is the one where the count of even digits is equal to the count of odd digits.

To check if a number is fair, we count the even and odd digits of the number `k` using a while loop. In each iteration, we check if the last digit of `k` is even or odd, increment the respective counter, and update `k` by removing the last digit. If the count of even and odd digits is equal, return the number `n`.

If the given number `n` is not fair, we increment `n` and repeat the process until we find a fair number.

This algorithm has a linear time complexity (in the worst case) as we need to find the subsequent fair numbers one by one until we find the smallest fair number satisfying the constraints.

## A solution in C++

```cpp
int smallestFairNumber(int n) {
    while (true) {
        int k = n;
        int even = 0, odd = 0;
        while (k > 0) {
            k % 2 == 0 ? even++ : odd++;
            k /= 10;
        }
        if (even == odd) return n;
        n++;
    }
}
```
The algorithm starts from the given number `n` and check if it is fair or not. A fair number `k` is the one where the count of even digits is equal to the count of odd digits.

To check if a number is fair, we count the even and odd digits of the number `k` using a while loop. In each iteration, we check if the last digit of `k` is even or odd, increment the respective counter, and update `k` by removing the last digit. If the count of even and odd digits is equal, return the number `n`.

If the given number `n` is not fair, we increment `n` and repeat the process until we find a fair number.

This algorithm has a linear time complexity (in the worst case) as we need to find the subsequent fair numbers one by one until we find the smallest fair number satisfying the constraints.

## A solution in Python

```python
def smallest_fair_number(n):
    while True:
        k = n
        even = 0
        odd = 0
        while k > 0:
            if k % 2 == 0:
                even += 1
            else:
                odd += 1
            k //= 10
        if even == odd:
            return n
        n += 1
```
The algorithm starts from the given number `n` and check if it is fair or not. A fair number `k` is the one where the count of even digits is equal to the count of odd digits.

To check if a number is fair, we count the even and odd digits of the number `k` using a while loop. In each iteration, we check if the last digit of `k` is even or odd, increment the respective counter, and update `k` by removing the last digit. If the count of even and odd digits is equal, return the number `n`.

If the given number `n` is not fair, we increment `n` and repeat the process until we find a fair number.

This algorithm has a linear time complexity (in the worst case) as we need to find the subsequent fair numbers one by one until we find the smallest fair number satisfying the constraints.

## A solution in Javascript

```javascript
function smallestFairNumber(n) {
    while (true) {
        let k = n;
        let even = 0, odd = 0;
        while (k > 0) {
            k % 2 === 0 ? even++ : odd++;
            k = Math.floor(k / 10);
        }
        if (even === odd) return n;
        n++;
    }
}
```
The algorithm starts from the given number `n` and check if it is fair or not. A fair number `k` is the one where the count of even digits is equal to the count of odd digits.

To check if a number is fair, we count the even and odd digits of the number `k` using a while loop. In each iteration, we check if the last digit of `k` is even or odd, increment the respective counter, and update `k` by removing the last digit. If the count of even and odd digits is equal, return the number `n`.

If the given number `n` is not fair, we increment `n` and repeat the process until we find a fair number.

This algorithm has a linear time complexity (in the worst case) as we need to find the subsequent fair numbers one by one until we find the smallest fair number satisfying the constraints.


# Sort the People

- slug: sort-the-people
- difficulty: Easy

You are given an array of strings `names`, and an array `heights` that consists of **distinct** positive integers. Both arrays are of length `n`.

For each index `i`, `names[i]` and `heights[i]` denote the name and height of the `ith` person.

Return `names` _sorted in **descending** order by the people's heights_.

**Example 1:**

**Input:** names = \[ "Mary ", "John ", "Emma "\], heights = \[180,165,170\]
**Output:** \[ "Mary ", "Emma ", "John "\]
**Explanation:** Mary is the tallest, followed by Emma and John.

**Example 2:**

**Input:** names = \[ "Alice ", "Bob ", "Bob "\], heights = \[155,185,150\]
**Output:** \[ "Bob ", "Alice ", "Bob "\]
**Explanation:** The first Bob is the tallest, followed by Alice and the second Bob.

**Constraints:**

*   `n == names.length == heights.length`
*   `1 <= n <= 103`
*   `1 <= names[i].length <= 20`
*   `1 <= heights[i] <= 105`
*   `names[i]` consists of lower and upper case English letters.
*   All the values of `heights` are distinct.

## A solution in Java

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

public List<String> sortNamesByHeight(String[] names, int[] heights) {
    List<Pair> nameHeightPairs = new ArrayList<>();

    for(int i = 0; i < names.length; i++) {
        nameHeightPairs.add(new Pair(heights[i], names[i]));
    }

    nameHeightPairs.sort((a, b) -> b.height - a.height);

    List<String> sortedNames = new ArrayList<>();
    for(Pair pair : nameHeightPairs) {
        sortedNames.add(pair.name);
    }

    return sortedNames;
}

class Pair {
    int height;
    String name;

    public Pair(int height, String name) {
        this.height = height;
        this.name = name;
    }
}
```
The algorithm starts by iterating through both input arrays (`names` and `heights`) to create an array ('name_height_pairs') of pairs (in other languages, objects with `height` and `name` properties) containing the heights and corresponding names.

Next, the array of pairs is sorted in descending order (highest to lowest) based on the height values.

Finally, a new array (`sorted_names`) is created containing only the names from the sorted pairs.

This process ensures that the names in the final array are sorted in descending order by the people's heights.

## A solution in C++

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

std::vector<std::string> sortNamesByHeight(std::vector<std::string>& names, std::vector<int>& heights) {
    std::vector<std::pair<int, std::string>> name_height_pairs;

    for(int i = 0; i < names.size(); i++) {
        name_height_pairs.push_back(std::make_pair(heights[i], names[i]));
    }

    std::sort(name_height_pairs.rbegin(), name_height_pairs.rend());

    std::vector<std::string> sorted_names;
    for(auto& pair : name_height_pairs) {
        sorted_names.push_back(pair.second);
    }

    return sorted_names;
}
```
The algorithm starts by iterating through both input arrays (`names` and `heights`) to create an array ('name_height_pairs') of pairs (in other languages, objects with `height` and `name` properties) containing the heights and corresponding names.

Next, the array of pairs is sorted in descending order (highest to lowest) based on the height values.

Finally, a new array (`sorted_names`) is created containing only the names from the sorted pairs.

This process ensures that the names in the final array are sorted in descending order by the people's heights.

## A solution in Python

```python
def sort_names_by_height(names, heights):
    name_height_pairs = sorted(zip(heights, names), reverse=True)
    sorted_names = [pair[1] for pair in name_height_pairs]
    return sorted_names
```
The algorithm starts by iterating through both input arrays (`names` and `heights`) to create an array ('name_height_pairs') of pairs (in other languages, objects with `height` and `name` properties) containing the heights and corresponding names.

Next, the array of pairs is sorted in descending order (highest to lowest) based on the height values.

Finally, a new array (`sorted_names`) is created containing only the names from the sorted pairs.

This process ensures that the names in the final array are sorted in descending order by the people's heights.

## A solution in Javascript

```javascript
function sortNamesByHeight(names, heights) {
    let nameHeightPairs = [];

    for(let i = 0; i < names.length; i++) {
        nameHeightPairs.push({name: names[i], height: heights[i]});
    }

    nameHeightPairs.sort((a, b) => b.height - a.height);

    let sortedNames = nameHeightPairs.map(pair => pair.name);

    return sortedNames;
}
```
The algorithm starts by iterating through both input arrays (`names` and `heights`) to create an array ('name_height_pairs') of pairs (in other languages, objects with `height` and `name` properties) containing the heights and corresponding names.

Next, the array of pairs is sorted in descending order (highest to lowest) based on the height values.

Finally, a new array (`sorted_names`) is created containing only the names from the sorted pairs.

This process ensures that the names in the final array are sorted in descending order by the people's heights.


# Longest Subarray With Maximum Bitwise AND

- slug: longest-subarray-with-maximum-bitwise-and
- difficulty: Medium

You are given an integer array `nums` of size `n`.

Consider a **non-empty** subarray from `nums` that has the **maximum** possible **bitwise AND**.

*   In other words, let `k` be the maximum value of the bitwise AND of **any** subarray of `nums`. Then, only subarrays with a bitwise AND equal to `k` should be considered.

Return _the length of the **longest** such subarray_.

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

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

**Example 1:**

**Input:** nums = \[1,2,3,3,2,2\]
**Output:** 2
**Explanation:**
The maximum possible bitwise AND of a subarray is 3.
The longest subarray with that value is \[3,3\], so we return 2.

**Example 2:**

**Input:** nums = \[1,2,3,4\]
**Output:** 1
**Explanation:**
The maximum possible bitwise AND of a subarray is 4.
The longest subarray with that value is \[4\], so we return 1.

**Constraints:**

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

## A solution in Java

```java
public int longestSubarray(int[] nums) {
    int max_and = 0;
    for (int i = 0; i < nums.length; i++) {
        int temp_and = nums[i];
        for (int j = i + 1; j < nums.length; j++) {
            temp_and &= nums[j];
            max_and = Math.max(max_and, temp_and);
        }
    }

    int longest_subarray = 0, current_length = 0;
    for (int i = 0; i < nums.length; i++) {
        int temp_and = nums[i];
        current_length = (temp_and == max_and) ? 1 : 0;
        for (int j = i + 1; j < nums.length; j++) {
            temp_and &= nums[j];
            if (temp_and == max_and) {
                current_length++;
            } else {
                break;
            }
        }
        longest_subarray = Math.max(longest_subarray, current_length);
    }
    return longest_subarray;
}
```
The algorithm first calculates the maximum possible bitwise AND for the given input. Then, it calculates the length of the longest subarray with that value. For each element, the algorithm checks if its bitwise AND with the next elements equals the maximum possible bitwise AND. If yes, the length of the current subarray is incremented, else the iteration for the current element is terminated. After comparing the length of each subarray, the algorithm returns the length of the longest such subarray.

## A solution in C++

```cpp
int longestSubarray(vector<int>& nums) {
    int max_and = 0;
    for (int i = 0; i < nums.size(); i++) {
        int temp_and = nums[i];
        for (int j = i + 1; j < nums.size(); j++) {
            temp_and &= nums[j];
            max_and = max(max_and, temp_and);
        }
    }

    int longest_subarray = 0, current_length = 0;
    for (int i = 0; i < nums.size(); i++) {
        int temp_and = nums[i];
        current_length = (temp_and == max_and) ? 1 : 0;
        for (int j = i + 1; j < nums.size(); j++) {
            temp_and &= nums[j];
            if (temp_and == max_and) {
                current_length++;
            } else {
                break;
            }
        }
        longest_subarray = max(longest_subarray, current_length);
    }
    return longest_subarray;
}
```
The algorithm first calculates the maximum possible bitwise AND for the given input. Then, it calculates the length of the longest subarray with that value. For each element, the algorithm checks if its bitwise AND with the next elements equals the maximum possible bitwise AND. If yes, the length of the current subarray is incremented, else the iteration for the current element is terminated. After comparing the length of each subarray, the algorithm returns the length of the longest such subarray.

## A solution in Python

```python
def longestSubarray(nums):
    max_and = 0
    for i in range(len(nums)):
        temp_and = nums[i]
        for j in range(i + 1, len(nums)):
            temp_and &= nums[j]
            max_and = max(max_and, temp_and)

    longest_subarray = 0
    current_length = 0
    for i in range(len(nums)):
        temp_and = nums[i]
        current_length = 1 if temp_and == max_and else 0
        for j in range(i + 1, len(nums)):
            temp_and &= nums[j];
            if temp_and == max_and:
                current_length += 1
            else:
                break
        longest_subarray = max(longest_subarray, current_length)
    return longest_subarray
```
The algorithm first calculates the maximum possible bitwise AND for the given input. Then, it calculates the length of the longest subarray with that value. For each element, the algorithm checks if its bitwise AND with the next elements equals the maximum possible bitwise AND. If yes, the length of the current subarray is incremented, else the iteration for the current element is terminated. After comparing the length of each subarray, the algorithm returns the length of the longest such subarray.

## A solution in Javascript

```javascript
function longestSubarray(nums) {
    let max_and = 0;
    for (let i = 0; i < nums.length; i++) {
        let temp_and = nums[i];
        for (let j = i + 1; j < nums.length; j++) {
            temp_and &= nums[j];
            max_and = Math.max(max_and, temp_and);
        }
    }

    let longest_subarray = 0;
    let current_length = 0;
    for (let i = 0; i < nums.length; i++) {
        let temp_and = nums[i];
        current_length = (temp_and === max_and) ? 1 : 0;
        for (let j = i + 1; j < nums.length; j++) {
            temp_and &= nums[j];
            if (temp_and === max_and) {
                current_length++;
            } else {
                break;
            }
        }
        longest_subarray = Math.max(longest_subarray, current_length);
    }
    return longest_subarray;
}
```
The algorithm first calculates the maximum possible bitwise AND for the given input. Then, it calculates the length of the longest subarray with that value. For each element, the algorithm checks if its bitwise AND with the next elements equals the maximum possible bitwise AND. If yes, the length of the current subarray is incremented, else the iteration for the current element is terminated. After comparing the length of each subarray, the algorithm returns the length of the longest such subarray.


# Find All Good Indices

- slug: find-all-good-indices
- difficulty: Medium

You are given a **0-indexed** integer array `nums` of size `n` and a positive integer `k`.

We call an index `i` in the range `k <= i < n - k` **good** if the following conditions are satisfied:

*   The `k` elements that are just **before** the index `i` are in **non-increasing** order.
*   The `k` elements that are just **after** the index `i` are in **non-decreasing** order.

Return _an array of all good indices sorted in **increasing** order_.

**Example 1:**

**Input:** nums = \[2,1,1,1,3,4,1\], k = 2
**Output:** \[2,3\]
**Explanation:** There are two good indices in the array:
- Index 2. The subarray \[2,1\] is in non-increasing order, and the subarray \[1,3\] is in non-decreasing order.
- Index 3. The subarray \[1,1\] is in non-increasing order, and the subarray \[3,4\] is in non-decreasing order.
Note that the index 4 is not good because \[4,1\] is not non-decreasing.

**Example 2:**

**Input:** nums = \[2,1,1,2\], k = 2
**Output:** \[\]
**Explanation:** There are no good indices in this array.

**Constraints:**

*   `n == nums.length`
*   `3 <= n <= 105`
*   `1 <= nums[i] <= 106`
*   `1 <= k <= n / 2`

## A solution in Java

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

public List<Integer> findGoodIndices(int[] nums, int k) {
    List<Integer> goodIndices = new ArrayList<>();
    for (int i = k; i < nums.length - k; i++) {
        boolean leftNonInc = true;
        boolean rightNonDec = true;

        for (int j = 0; j < k - 1; j++) {
            if (nums[i - j - 1] < nums[i - j - 2]) {
                leftNonInc = false;
                break;
            }
        }

        for (int j = 0; j < k - 1; j++) {
            if (nums[i + j + 1] < nums[i + j + 2]) {
                rightNonDec = false;
                break;
            }
        }

        if (leftNonInc && rightNonDec) {
            goodIndices.add(i);
        }
    }
    return goodIndices;
}
```
We start by iterating over the elements in the given input range `[k, n - k)`, then check if the `k` elements before each index are in non-increasing order and the `k` elements after each index are in non-decreasing order. If the condition is satisfied for an index, we add it to the `good_indices` array. Upon completion, we return the array of good indices.

## A solution in C++

```cpp
#include <vector>

std::vector<int> findGoodIndices(const std::vector<int>& nums, int k) {
    std::vector<int> good_indices;
    for(int i = k; i < nums.size() - k; ++i) {
        bool left_non_inc = true;
        bool right_non_dec = true;

        for(int j = 0; j < k - 1; ++j) {
            if (nums[i - j - 1] < nums[i - j - 2]) {
                left_non_inc = false;
                break;
            }
        }

        for(int j = 0; j < k - 1; ++j) {
            if (nums[i + j + 1] < nums[i + j + 2]) {
                right_non_dec = false;
                break;
            }
        }

        if (left_non_inc && right_non_dec) {
            good_indices.push_back(i);
        }
    }
    return good_indices;
}
```
We start by iterating over the elements in the given input range `[k, n - k)`, then check if the `k` elements before each index are in non-increasing order and the `k` elements after each index are in non-decreasing order. If the condition is satisfied for an index, we add it to the `good_indices` array. Upon completion, we return the array of good indices.

## A solution in Python

```python
def find_good_indices(nums, k):
    good_indices = []
    for i in range(k, len(nums) - k):
        left_non_inc = all(nums[i - j - 1] >= nums[i - j - 2] for j in range(k - 1))
        right_non_dec = all(nums[i + j + 1] >= nums[i + j + 2] for j in range(k - 1))

        if left_non_inc and right_non_dec:
            good_indices.append(i)

    return good_indices
```
We start by iterating over the elements in the given input range `[k, n - k)`, then check if the `k` elements before each index are in non-increasing order and the `k` elements after each index are in non-decreasing order. If the condition is satisfied for an index, we add it to the `good_indices` array. Upon completion, we return the array of good indices.

## A solution in Javascript

```js
function findGoodIndices(nums, k) {
    const goodIndices = [];
    for (let i = k; i < nums.length - k; i++) {
        let leftNonInc = true;
        let rightNonDec = true;

        for (let j = 0; j < k - 1; j++) {
            if (nums[i - j - 1] < nums[i - j - 2]) {
                leftNonInc = false;
                break;
            }
        }

        for (let j = 0; j < k - 1; j++) {
            if (nums[i + j + 1] < nums[i + j + 2]) {
                rightNonDec = false;
                break;
            }
        }

        if (leftNonInc && rightNonDec) {
            goodIndices.push(i);
        }
    }
    return goodIndices;
}
```
We start by iterating over the elements in the given input range `[k, n - k)`, then check if the `k` elements before each index are in non-increasing order and the `k` elements after each index are in non-decreasing order. If the condition is satisfied for an index, we add it to the `good_indices` array. Upon completion, we return the array of good indices.


# Number of Good Paths

- slug: number-of-good-paths
- difficulty: Hard

There is a tree (i.e. a connected, undirected graph with no cycles) consisting of `n` nodes numbered from `0` to `n - 1` and exactly `n - 1` edges.

You are given a **0-indexed** integer array `vals` of length `n` where `vals[i]` denotes the value of the `ith` node. You are also given a 2D integer array `edges` where `edges[i] = [ai, bi]` denotes that there exists an **undirected** edge connecting nodes `ai` and `bi`.

A **good path** is a simple path that satisfies the following conditions:

1.  The starting node and the ending node have the **same** value.
2.  All nodes between the starting node and the ending node have values **less than or equal to** the starting node (i.e. the starting node's value should be the maximum value along the path).

Return _the number of distinct good paths_.

Note that a path and its reverse are counted as the **same** path. For example, `0 -> 1` is considered to be the same as `1 -> 0`. A single node is also considered as a valid path.

**Example 1:**

**Input:** vals = \[1,3,2,1,3\], edges = \[\[0,1\],\[0,2\],\[2,3\],\[2,4\]\]
**Output:** 6
**Explanation:** There are 5 good paths consisting of a single node.
There is 1 additional good path: 1 -> 0 -> 2 -> 4.
(The reverse path 4 -> 2 -> 0 -> 1 is treated as the same as 1 -> 0 -> 2 -> 4.)
Note that 0 -> 2 -> 3 is not a good path because vals\[2\] > vals\[0\].

**Example 2:**

**Input:** vals = \[1,1,2,2,3\], edges = \[\[0,1\],\[1,2\],\[2,3\],\[2,4\]\]
**Output:** 7
**Explanation:** There are 5 good paths consisting of a single node.
There are 2 additional good paths: 0 -> 1 and 2 -> 3.

**Example 3:**

**Input:** vals = \[1\], edges = \[\]
**Output:** 1
**Explanation:** The tree consists of only one node, so there is one good path.

**Constraints:**

*   `n == vals.length`
*   `1 <= n <= 3 * 104`
*   `0 <= vals[i] <= 105`
*   `edges.length == n - 1`
*   `edges[i].length == 2`
*   `0 <= ai, bi < n`
*   `ai != bi`
*   `edges` represents a valid tree.

## A solution in Java

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

public class GoodPaths {
    public static void dfs(int node, int parent, List<List<Integer>> adj, int[] vals, int curMax, int[] count) {
        if (vals[node] >= curMax) {
            if (vals[node] > curMax) {
                count[0]++;
                curMax = vals[node];
            }
            for (int next : adj.get(node)) {
                if (next != parent) {
                    dfs(next, node, adj, vals, curMax, count);
                }
            }
        }
    }

    public static int numberOfGoodPaths(int[] vals, int[][] edges) {
        int n = vals.length;
        List<List<Integer>> adj = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            adj.add(new ArrayList<>());
        }
        for (int[] edge : edges) {
            adj.get(edge[0]).add(edge[1]);
            adj.get(edge[1]).add(edge[0]);
        }
        int[] count = {0};
        for (int i = 0; i < n; i++) {
            dfs(i, -1, adj, vals, -1, count);
        }
        return count[0];
    }
}
```
The problem can be solved with a Depth-First Search (DFS) traversal of the tree.

1. Create an adjacency list from the given edges. The adjacency list will represent the tree graph with connections between nodes.
2. Perform DFS on each node, passing its value, the current max value on the path, and a count variable.
3. In the DFS function:
   - If the current node's value is greater than or equal to the current max value, do the following:
     - If the current node's value is greater than the current max value, increment the count and update the current max value.
     - Continue the DFS traversal by calling the DFS function for each of the node's children (except the parent node).
4. Return the count variable for the total number of good paths.

The time complexity of this solution is O(n^2), where n is the number of nodes. This is because in the worst case, the DFS traversal may need to visit every other node from the starting node.

## A solution in C++

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

void dfs(int node, int parent, const vector<vector<int>>& adj, const vector<int>& vals, int curMax, int& count) {
    if (vals[node] >= curMax) {
        if (vals[node] > curMax) {
            count++;
            curMax = vals[node];
        }
        for (int next : adj[node]) {
            if (next != parent) {
                dfs(next, node, adj, vals, curMax, count);
            }
        }
    }
}

int NumberOfGoodPaths(const vector<int>& vals, const vector<vector<int>>& edges) {
    int n = vals.size();
    vector<vector<int>> adj(n);
    for (const auto& edge : edges) {
        adj[edge[0]].push_back(edge[1]);
        adj[edge[1]].push_back(edge[0]);
    }
    int count = 0;
    for (int i = 0; i < n; i++) {
        dfs(i, -1, adj, vals, -1, count);
    }
    return count;
}
```
The problem can be solved with a Depth-First Search (DFS) traversal of the tree.

1. Create an adjacency list from the given edges. The adjacency list will represent the tree graph with connections between nodes.
2. Perform DFS on each node, passing its value, the current max value on the path, and a count variable.
3. In the DFS function:
   - If the current node's value is greater than or equal to the current max value, do the following:
     - If the current node's value is greater than the current max value, increment the count and update the current max value.
     - Continue the DFS traversal by calling the DFS function for each of the node's children (except the parent node).
4. Return the count variable for the total number of good paths.

The time complexity of this solution is O(n^2), where n is the number of nodes. This is because in the worst case, the DFS traversal may need to visit every other node from the starting node.

## A solution in Python

```python
from collections import defaultdict

def dfs(node, parent, adj, vals, cur_max, count):
    if vals[node] >= cur_max:
        if vals[node] > cur_max:
            count[0] += 1
            cur_max = vals[node]
        for next in adj[node]:
            if next != parent:
                dfs(next, node, adj, vals, cur_max, count)

def number_of_good_paths(vals, edges):
    n = len(vals)
    adj = defaultdict(list)
    for edge in edges:
        adj[edge[0]].append(edge[1])
        adj[edge[1]].append(edge[0])
    count = [0]
    for i in range(n):
        dfs(i, -1, adj, vals, -1, count)
    return count[0]
```
The problem can be solved with a Depth-First Search (DFS) traversal of the tree.

1. Create an adjacency list from the given edges. The adjacency list will represent the tree graph with connections between nodes.
2. Perform DFS on each node, passing its value, the current max value on the path, and a count variable.
3. In the DFS function:
   - If the current node's value is greater than or equal to the current max value, do the following:
     - If the current node's value is greater than the current max value, increment the count and update the current max value.
     - Continue the DFS traversal by calling the DFS function for each of the node's children (except the parent node).
4. Return the count variable for the total number of good paths.

The time complexity of this solution is O(n^2), where n is the number of nodes. This is because in the worst case, the DFS traversal may need to visit every other node from the starting node.

## A solution in Javascript

```javascript
function dfs(node, parent, adj, vals, curMax, count) {
    if (vals[node] >= curMax) {
        if (vals[node] > curMax) {
            count[0]++;
            curMax = vals[node];
        }
        for (const next of adj[node]) {
            if (next !== parent) {
                dfs(next, node, adj, vals, curMax, count);
            }
        }
    }
}

function numberOfGoodPaths(vals, edges) {
    const n = vals.length;
    const adj = Array(n).fill(null).map(() => []);
    for (const edge of edges) {
        adj[edge[0]].push(edge[1]);
        adj[edge[1]].push(edge[0]);
    }
    const count = [0];
    for (let i = 0; i < n; i++) {
        dfs(i, -1, adj, vals, -1, count);
    }
    return count[0];
}
```
The problem can be solved with a Depth-First Search (DFS) traversal of the tree.

1. Create an adjacency list from the given edges. The adjacency list will represent the tree graph with connections between nodes.
2. Perform DFS on each node, passing its value, the current max value on the path, and a count variable.
3. In the DFS function:
   - If the current node's value is greater than or equal to the current max value, do the following:
     - If the current node's value is greater than the current max value, increment the count and update the current max value.
     - Continue the DFS traversal by calling the DFS function for each of the node's children (except the parent node).
4. Return the count variable for the total number of good paths.

The time complexity of this solution is O(n^2), where n is the number of nodes. This is because in the worst case, the DFS traversal may need to visit every other node from the starting node.


# Merge Operations to Turn Array Into a Palindrome

- slug: merge-operations-to-turn-array-into-a-palindrome
- difficulty: Medium

You are given an array `nums` consisting of **positive** integers.

You can perform the following operation on the array **any** number of times:

*   Choose any two **adjacent** elements and **replace** them with their **sum**.
    *   For example, if `nums = [1,2,3,1]`, you can apply one operation to make it `[1,5,1]`.

Return _the **minimum** number of operations needed to turn the array into a **palindrome**_.

**Example 1:**

**Input:** nums = \[4,3,2,1,2,3,1\]
**Output:** 2
**Explanation:** We can turn the array into a palindrome in 2 operations as follows:
- Apply the operation on the fourth and fifth element of the array, nums becomes equal to \[4,3,2,**3**,3,1\].
- Apply the operation on the fifth and sixth element of the array, nums becomes equal to \[4,3,2,3,**4**\].
The array \[4,3,2,3,4\] is a palindrome.
It can be shown that 2 is the minimum number of operations needed.

**Example 2:**

**Input:** nums = \[1,2,3,4\]
**Output:** 3
**Explanation:** We do the operation 3 times in any position, we obtain the array \[10\] at the end which is a palindrome.

**Constraints:**

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

## A solution in Java

```java
public int minOperations(int[] nums) {
    int n = nums.length;
    int i = 0, j = n - 1;
    int operations = 0;

    while (i < j) {
        if (nums[i] == nums[j]) {
            i++;
            j--;
        } else if (nums[i] < nums[j]) {
            nums[i + 1] += nums[i];
            i++;
            operations++;
        } else {
            nums[j - 1] += nums[j];
            j--;
            operations++;
        }
    }
    return operations;
}
```
The algorithm uses two pointers, `i` and `j`, initializing them to the start and end of the array, respectively. It then enters a loop, moving these pointers inwards and comparing the values in the array at these indices. If the values are equal, the pointers are moved inwards without performing any operation. If the values are not equal, an operation is performed to make the smaller value equal to the larger one. The loop continues until the pointers cross each other. The number of operations performed is returned as the result.

The algorithm has a complexity of O(n) as it iterates through the input array once.

## A solution in C++

```cpp
int minOperations(vector<int>& nums) {
    int n = nums.size();
    int i = 0, j = n - 1;
    int operations = 0;

    while (i < j) {
        if (nums[i] == nums[j]) {
            i++;
            j--;
        } else if (nums[i] < nums[j]) {
            nums[i + 1] += nums[i];
            i++;
            operations++;
        } else {
            nums[j - 1] += nums[j];
            j--;
            operations++;
        }
    }
    return operations;
}
```
The algorithm uses two pointers, `i` and `j`, initializing them to the start and end of the array, respectively. It then enters a loop, moving these pointers inwards and comparing the values in the array at these indices. If the values are equal, the pointers are moved inwards without performing any operation. If the values are not equal, an operation is performed to make the smaller value equal to the larger one. The loop continues until the pointers cross each other. The number of operations performed is returned as the result.

The algorithm has a complexity of O(n) as it iterates through the input array once.

## A solution in Python

```python
def minOperations(nums):
    n = len(nums)
    i, j = 0, n - 1
    operations = 0

    while i < j:
        if nums[i] == nums[j]:
            i += 1
            j -= 1
        elif nums[i] < nums[j]:
            nums[i + 1] += nums[i]
            i += 1
            operations += 1
        else:
            nums[j - 1] += nums[j]
            j -= 1
            operations += 1

    return operations
```
The algorithm uses two pointers, `i` and `j`, initializing them to the start and end of the array, respectively. It then enters a loop, moving these pointers inwards and comparing the values in the array at these indices. If the values are equal, the pointers are moved inwards without performing any operation. If the values are not equal, an operation is performed to make the smaller value equal to the larger one. The loop continues until the pointers cross each other. The number of operations performed is returned as the result.

The algorithm has a complexity of O(n) as it iterates through the input array once.

## A solution in Javascript

```javascript
function minOperations(nums) {
    const n = nums.length;
    let i = 0, j = n - 1;
    let operations = 0;

    while (i < j) {
        if (nums[i] === nums[j]) {
            i++;
            j--;
        } else if (nums[i] < nums[j]) {
            nums[i + 1] += nums[i];
            i++;
            operations++;
        } else {
            nums[j - 1] += nums[j];
            j--;
            operations++;
        }
    }
    return operations;
}
```
The algorithm uses two pointers, `i` and `j`, initializing them to the start and end of the array, respectively. It then enters a loop, moving these pointers inwards and comparing the values in the array at these indices. If the values are equal, the pointers are moved inwards without performing any operation. If the values are not equal, an operation is performed to make the smaller value equal to the larger one. The loop continues until the pointers cross each other. The number of operations performed is returned as the result.

The algorithm has a complexity of O(n) as it iterates through the input array once.


# Remove Letter To Equalize Frequency

- slug: remove-letter-to-equalize-frequency
- difficulty: Easy

You are given a **0-indexed** string `word`, consisting of lowercase English letters. You need to select **one** index and **remove** the letter at that index from `word` so that the **frequency** of every letter present in `word` is equal.

Return `true` _if it is possible to remove one letter so that the frequency of all letters in_ `word` _are equal, and_ `false` _otherwise_.

**Note:**

*   The **frequency** of a letter `x` is the number of times it occurs in the string.
*   You **must** remove exactly one letter and cannot chose to do nothing.

**Example 1:**

**Input:** word =  "abcc "
**Output:** true
**Explanation:** Select index 3 and delete it: word becomes  "abc " and each character has a frequency of 1.

**Example 2:**

**Input:** word =  "aazz "
**Output:** false
**Explanation:** We must delete a character, so either the frequency of  "a " is 1 and the frequency of  "z " is 2, or vice versa. It is impossible to make all present letters have equal frequency.

**Constraints:**

*   `2 <= word.length <= 100`
*   `word` consists of lowercase English letters only.

## A solution in Java

```java
import java.util.HashMap;

public boolean canEqualFrequency(String word) {
    HashMap<Character, Integer> freq = new HashMap<>();
    for (char c : word.toCharArray()) {
        freq.put(c, freq.getOrDefault(c, 0) + 1);
    }

    HashMap<Integer, Integer> count_freq = new HashMap<>();
    for (int f : freq.values()) {
        count_freq.put(f, count_freq.getOrDefault(f, 0) + 1);
    }

    if (count_freq.size() != 2) {
        return false;
    }

    int a = (int) count_freq.keySet().toArray()[0];
    int acount = count_freq.get(a);
    int b = (int) count_freq.keySet().toArray()[1];
    int bcount = count_freq.get(b);

    return (acount == 1 && (a - 1 == b || a == 1)) || (bcount == 1 && (b - 1 == a || b == 1));
}
```
1. First, we create a frequency map `freq` that counts the frequency of each character in the given `word`.
2. Then, we create another map `count_freq` that counts the frequencies of the values in the `freq` map.
3. If the size of `count_freq` is not 2, return false since we must remove exactly one character.
4. If the size of `count_freq` is 2, we iterate through the items of the `count_freq` map.
5. We check if the map contains a single entry with frequency 1 and either the other frequency is one less than the single entry frequency or it is 1.
6. If either of the above two conditions is met, we can remove one character so that the remaining letters have equal frequencies. In this case, we return `true`. Otherwise, we return `false`.

## A solution in C++

```cpp
#include <unordered_map>

bool canEqualFrequency(std::string word) {
    std::unordered_map<char, int> freq;
    for (char c : word) {
        freq[c]++;
    }

    std::unordered_map<int, int> count_freq;
    for (auto &[c, f] : freq) {
        count_freq[f]++;
    }

    if (count_freq.size() != 2) {
        return false;
    }

    auto it = count_freq.begin();
    auto &[a, acount] = *it;
    it++;
    auto &[b, bcount] = *it;

    return (acount == 1 && (a - 1 == b || a == 1)) || (bcount == 1 && (b - 1 == a || b == 1));
}
```
1. First, we create a frequency map `freq` that counts the frequency of each character in the given `word`.
2. Then, we create another map `count_freq` that counts the frequencies of the values in the `freq` map.
3. If the size of `count_freq` is not 2, return false since we must remove exactly one character.
4. If the size of `count_freq` is 2, we iterate through the items of the `count_freq` map.
5. We check if the map contains a single entry with frequency 1 and either the other frequency is one less than the single entry frequency or it is 1.
6. If either of the above two conditions is met, we can remove one character so that the remaining letters have equal frequencies. In this case, we return `true`. Otherwise, we return `false`.

## A solution in Python

```python
def can_equal_frequency(word: str) -> bool:
    freq = {}
    for c in word:
        freq[c] = freq.get(c, 0) + 1

    count_freq = {}
    for f in freq.values():
        count_freq[f] = count_freq.get(f, 0) + 1

    if len(count_freq) != 2:
        return False

    a, acount = next(iter(count_freq.items()))
    b, bcount = next(reversed(list(count_freq.items())))

    return (acount == 1 and (a - 1 == b or a == 1)) or (bcount == 1 and (b - 1 == a or b == 1))
```
1. First, we create a frequency map `freq` that counts the frequency of each character in the given `word`.
2. Then, we create another map `count_freq` that counts the frequencies of the values in the `freq` map.
3. If the size of `count_freq` is not 2, return false since we must remove exactly one character.
4. If the size of `count_freq` is 2, we iterate through the items of the `count_freq` map.
5. We check if the map contains a single entry with frequency 1 and either the other frequency is one less than the single entry frequency or it is 1.
6. If either of the above two conditions is met, we can remove one character so that the remaining letters have equal frequencies. In this case, we return `true`. Otherwise, we return `false`.

## A solution in Javascript

```javascript
function canEqualFrequency(word) {
    const freq = new Map();
    for (const c of word) {
        freq.set(c, (freq.get(c) || 0) + 1);
    }

    const count_freq = new Map();
    for (const f of freq.values()) {
        count_freq.set(f, (count_freq.get(f) || 0) + 1);
    }

    if (count_freq.size != 2) {
        return false;
    }

    const [[a, acount], [b, bcount]] = count_freq.entries();

    return (acount === 1 && (a - 1 === b || a === 1)) || (bcount === 1 && (b - 1 === a || b === 1));
}
```
1. First, we create a frequency map `freq` that counts the frequency of each character in the given `word`.
2. Then, we create another map `count_freq` that counts the frequencies of the values in the `freq` map.
3. If the size of `count_freq` is not 2, return false since we must remove exactly one character.
4. If the size of `count_freq` is 2, we iterate through the items of the `count_freq` map.
5. We check if the map contains a single entry with frequency 1 and either the other frequency is one less than the single entry frequency or it is 1.
6. If either of the above two conditions is met, we can remove one character so that the remaining letters have equal frequencies. In this case, we return `true`. Otherwise, we return `false`.


# Longest Uploaded Prefix

- slug: longest-uploaded-prefix
- difficulty: Medium

You are given a stream of `n` videos, each represented by a **distinct** number from `1` to `n` that you need to "upload " to a server. You need to implement a data structure that calculates the length of the **longest uploaded prefix** at various points in the upload process.

We consider `i` to be an uploaded prefix if all videos in the range `1` to `i` (**inclusive**) have been uploaded to the server. The longest uploaded prefix is the **maximum** value of `i` that satisfies this definition.

Implement the `LUPrefix` class:

*   `LUPrefix(int n)` Initializes the object for a stream of `n` videos.
*   `void upload(int video)` Uploads `video` to the server.
*   `int longest()` Returns the length of the **longest uploaded prefix** defined above.

**Example 1:**

**Input**
\[ "LUPrefix ",  "upload ",  "longest ",  "upload ",  "longest ",  "upload ",  "longest "\]
\[\[4\], \[3\], \[\], \[1\], \[\], \[2\], \[\]\]
**Output**
\[null, null, 0, null, 1, null, 3\]

**Explanation**
LUPrefix server = new LUPrefix(4);   // Initialize a stream of 4 videos.
server.upload(3);                    // Upload video 3.
server.longest();                    // Since video 1 has not been uploaded yet, there is no prefix.
                                     // So, we return 0.
server.upload(1);                    // Upload video 1.
server.longest();                    // The prefix \[1\] is the longest uploaded prefix, so we return 1.
server.upload(2);                    // Upload video 2.
server.longest();                    // The prefix \[1,2,3\] is the longest uploaded prefix, so we return 3.

**Constraints:**

*   `1 <= n <= 105`
*   `1 <= video <= n`
*   All values of `video` are **distinct**.
*   At most `2 * 105` calls **in total** will be made to `upload` and `longest`.
*   At least one call will be made to `longest`.

## A solution in Java

```java
class LUPrefix {
    private int maxPrefixLength, nextVideo;
    private boolean[] uploaded;

    public LUPrefix(int n) {
        maxPrefixLength = 0;
        nextVideo = 1;
        uploaded = new boolean[n + 1];
    }

    public void upload(int video) {
        uploaded[video] = true;
        if (video == nextVideo) {
            while (uploaded[nextVideo]) nextVideo++;
        }
    }

    public int longest() {
        return nextVideo - 1;
    }
}
```
The data structure keeps track of the next video that should be uploaded in `next_video`. It also maintains an array or vector `uploaded` of size `n+1`. Each index corresponds to whether the video at that index has been uploaded or not. When a new video is uploaded to the server, the corresponding boolean flag in the array is set to `true`. If the uploaded video's index matches the expected next video, `next_video` is updated while the other videos in the contiguous sequence are also marked as uploaded. The length of the longest uploaded prefix is equal to the value of `next_video` minus `1`.

## A solution in C++

```cpp
class LUPrefix {
public:
    LUPrefix(int n) : max_prefix_length(0), next_video(1), uploaded(n + 1, false) {}

    void upload(int video) {
        uploaded[video] = true;
        if (video == next_video) {
            while (uploaded[next_video]) ++next_video;
        }
    }

    int longest() {
        return next_video - 1;
    }

private:
    int max_prefix_length, next_video;
    std::vector<bool> uploaded;
};
```
The data structure keeps track of the next video that should be uploaded in `next_video`. It also maintains an array or vector `uploaded` of size `n+1`. Each index corresponds to whether the video at that index has been uploaded or not. When a new video is uploaded to the server, the corresponding boolean flag in the array is set to `true`. If the uploaded video's index matches the expected next video, `next_video` is updated while the other videos in the contiguous sequence are also marked as uploaded. The length of the longest uploaded prefix is equal to the value of `next_video` minus `1`.

## A solution in Python

```python
class LUPrefix:
    def __init__(self, n: int):
        self.max_prefix_length = 0
        self.next_video = 1
        self.uploaded = [False] * (n + 1)

    def upload(self, video: int) -> None:
        self.uploaded[video] = True
        if video == self.next_video:
            while self.uploaded[self.next_video]:
                self.next_video += 1

    def longest(self) -> int:
        return self.next_video - 1
```
The data structure keeps track of the next video that should be uploaded in `next_video`. It also maintains an array or vector `uploaded` of size `n+1`. Each index corresponds to whether the video at that index has been uploaded or not. When a new video is uploaded to the server, the corresponding boolean flag in the array is set to `true`. If the uploaded video's index matches the expected next video, `next_video` is updated while the other videos in the contiguous sequence are also marked as uploaded. The length of the longest uploaded prefix is equal to the value of `next_video` minus `1`.

## A solution in Javascript

```javascript
class LUPrefix {
    constructor(n) {
        this.maxPrefixLength = 0;
        this.nextVideo = 1;
        this.uploaded = new Array(n + 1).fill(false);
    }

    upload(video) {
        this.uploaded[video] = true;
        if (video === this.nextVideo) {
            while (this.uploaded[this.nextVideo]) this.nextVideo++;
        }
    }

    longest() {
        return this.nextVideo - 1;
    }
}
```
The data structure keeps track of the next video that should be uploaded in `next_video`. It also maintains an array or vector `uploaded` of size `n+1`. Each index corresponds to whether the video at that index has been uploaded or not. When a new video is uploaded to the server, the corresponding boolean flag in the array is set to `true`. If the uploaded video's index matches the expected next video, `next_video` is updated while the other videos in the contiguous sequence are also marked as uploaded. The length of the longest uploaded prefix is equal to the value of `next_video` minus `1`.


# Bitwise XOR of All Pairings

- slug: bitwise-xor-of-all-pairings
- difficulty: Medium

You are given two **0-indexed** arrays, `nums1` and `nums2`, consisting of non-negative integers. There exists another array, `nums3`, which contains the bitwise XOR of **all pairings** of integers between `nums1` and `nums2` (every integer in `nums1` is paired with every integer in `nums2` **exactly once**).

Return _the **bitwise XOR** of all integers in_ `nums3`.

**Example 1:**

**Input:** nums1 = \[2,1,3\], nums2 = \[10,2,5,0\]
**Output:** 13
**Explanation:**
A possible nums3 array is \[8,0,7,2,11,3,4,1,9,1,6,3\].
The bitwise XOR of all these numbers is 13, so we return 13.

**Example 2:**

**Input:** nums1 = \[1,2\], nums2 = \[3,4\]
**Output:** 0
**Explanation:**
All possible pairs of bitwise XORs are nums1\[0\] ^ nums2\[0\], nums1\[0\] ^ nums2\[1\], nums1\[1\] ^ nums2\[0\],
and nums1\[1\] ^ nums2\[1\].
Thus, one possible nums3 array is \[2,5,1,6\].
2 ^ 5 ^ 1 ^ 6 = 0, so we return 0.

**Constraints:**

*   `1 <= nums1.length, nums2.length <= 105`
*   `0 <= nums1[i], nums2[j] <= 109`

## A solution in Java

```java
public int getXOR(int[] nums1, int[] nums2) {
    int xor_result = 0;
    for (int num1 : nums1) {
        for (int num2 : nums2) {
            xor_result ^= (num1 ^ num2);
        }
    }
    return xor_result;
}
```
The algorithm iterates over each integer in `nums1` and each integer in `nums2`, and computes the XOR of their pair. The XOR result of this pair is then XORed with the overall XOR result variable `xor_result`. This loop computes the XOR result of all pairs at the end. Since the XOR operation is commutative and associative, the order of the operations and pairs does not matter.

## A solution in C++

```cpp
int getXOR(vector<int>& nums1, vector<int>& nums2) {
    int xor_result = 0;
    for (int num1 : nums1) {
        for (int num2 : nums2) {
            xor_result ^= (num1 ^ num2);
        }
    }
    return xor_result;
}
```
The algorithm iterates over each integer in `nums1` and each integer in `nums2`, and computes the XOR of their pair. The XOR result of this pair is then XORed with the overall XOR result variable `xor_result`. This loop computes the XOR result of all pairs at the end. Since the XOR operation is commutative and associative, the order of the operations and pairs does not matter.

## A solution in Python

```python
def get_xor(nums1, nums2):
    xor_result = 0
    for num1 in nums1:
        for num2 in nums2:
            xor_result ^= (num1 ^ num2)
    return xor_result
```
The algorithm iterates over each integer in `nums1` and each integer in `nums2`, and computes the XOR of their pair. The XOR result of this pair is then XORed with the overall XOR result variable `xor_result`. This loop computes the XOR result of all pairs at the end. Since the XOR operation is commutative and associative, the order of the operations and pairs does not matter.

## A solution in Javascript

```javascript
function getXOR(nums1, nums2) {
    let xor_result = 0;
    for (let num1 of nums1) {
        for (let num2 of nums2) {
            xor_result ^= (num1 ^ num2);
        }
    }
    return xor_result;
}
```
The algorithm iterates over each integer in `nums1` and each integer in `nums2`, and computes the XOR of their pair. The XOR result of this pair is then XORed with the overall XOR result variable `xor_result`. This loop computes the XOR result of all pairs at the end. Since the XOR operation is commutative and associative, the order of the operations and pairs does not matter.


# Number of Pairs Satisfying Inequality

- slug: number-of-pairs-satisfying-inequality
- difficulty: Hard

You are given two **0-indexed** integer arrays `nums1` and `nums2`, each of size `n`, and an integer `diff`. Find the number of **pairs** `(i, j)` such that:

*   `0 <= i < j <= n - 1` **and**
*   `nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff`.

Return _the **number of pairs** that satisfy the conditions._

**Example 1:**

**Input:** nums1 = \[3,2,5\], nums2 = \[2,2,1\], diff = 1
**Output:** 3
**Explanation:**
There are 3 pairs that satisfy the conditions:
1. i = 0, j = 1: 3 - 2 <= 2 - 2 + 1. Since i < j and 1 <= 1, this pair satisfies the conditions.
2. i = 0, j = 2: 3 - 5 <= 2 - 1 + 1. Since i < j and -2 <= 2, this pair satisfies the conditions.
3. i = 1, j = 2: 2 - 5 <= 2 - 1 + 1. Since i < j and -3 <= 2, this pair satisfies the conditions.
Therefore, we return 3.

**Example 2:**

**Input:** nums1 = \[3,-1\], nums2 = \[-2,2\], diff = -1
**Output:** 0
**Explanation:**
Since there does not exist any pair that satisfies the conditions, we return 0.

**Constraints:**

*   `n == nums1.length == nums2.length`
*   `2 <= n <= 105`
*   `-104 <= nums1[i], nums2[i] <= 104`
*   `-104 <= diff <= 104`

## A solution in Java

```java
public int countPairs(int[] nums1, int[] nums2, int diff) {
    int n = nums1.length, count = 0;
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if (nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff) {
                count++;
            }
        }
    }
    return count;
}
```
The algorithm uses a nested loop to iterate through all possible pairs `(i, j)` such that `0 <= i < j <= n - 1`. For each pair, it compares the difference in elements in `nums1` and `nums2` to check if it satisfies the given condition `nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff`. If the condition is satisfied, increment the count. In the end, return the count which holds the number of pairs that satisfy the conditions.

## A solution in C++

```cpp
int countPairs(const vector<int>& nums1, const vector<int>& nums2, int diff) {
    int n = nums1.size(), count = 0;
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if (nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff) {
                count++;
            }
        }
    }
    return count;
}
```
The algorithm uses a nested loop to iterate through all possible pairs `(i, j)` such that `0 <= i < j <= n - 1`. For each pair, it compares the difference in elements in `nums1` and `nums2` to check if it satisfies the given condition `nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff`. If the condition is satisfied, increment the count. In the end, return the count which holds the number of pairs that satisfy the conditions.

## A solution in Python

```python
def count_pairs(nums1, nums2, diff):
    n = len(nums1)
    count = 0
    for i in range(n):
        for j in range(i + 1, n):
            if nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff:
                count += 1
    return count
```
The algorithm uses a nested loop to iterate through all possible pairs `(i, j)` such that `0 <= i < j <= n - 1`. For each pair, it compares the difference in elements in `nums1` and `nums2` to check if it satisfies the given condition `nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff`. If the condition is satisfied, increment the count. In the end, return the count which holds the number of pairs that satisfy the conditions.

## A solution in Javascript

```javascript
function countPairs(nums1, nums2, diff) {
    let n = nums1.length, count = 0;
    for (let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++) {
            if (nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff) {
                count++;
            }
        }
    }
    return count;
}
```
The algorithm uses a nested loop to iterate through all possible pairs `(i, j)` such that `0 <= i < j <= n - 1`. For each pair, it compares the difference in elements in `nums1` and `nums2` to check if it satisfies the given condition `nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff`. If the condition is satisfied, increment the count. In the end, return the count which holds the number of pairs that satisfy the conditions.


# Number of Common Factors

- slug: number-of-common-factors
- difficulty: Easy

Given two positive integers `a` and `b`, return _the number of **common** factors of_ `a` _and_ `b`.

An integer `x` is a **common factor** of `a` and `b` if `x` divides both `a` and `b`.

**Example 1:**

**Input:** a = 12, b = 6
**Output:** 4
**Explanation:** The common factors of 12 and 6 are 1, 2, 3, 6.

**Example 2:**

**Input:** a = 25, b = 30
**Output:** 2
**Explanation:** The common factors of 25 and 30 are 1, 5.

**Constraints:**

*   `1 <= a, b <= 1000`

## A solution in Java

```java
public int commonFactors(int a, int b) {
    int gcd = gcd(a, b);
    int count = 0;
    for (int i = 1; i * i <= gcd; i++) {
        if (gcd % i == 0) {
            count++;
            if (i * i != gcd)
                count++;
        }
    }
    return count;
}

private int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}
```
1. First, we calculate the greatest common divisor (GCD) of the input integers `a` and `b` using the Euclidean algorithm.
2. Next, we initialize a `count` variable to store the number of common factors.
3. Then, we iterate through the numbers from 1 to the square root of the GCD.
   - For each number `i` that is a factor of the GCD, we increment the `count`.
   - If the square of `i` is not equal to the GCD, we increment the `count` again because there is another factor, which is `gcd // i`.
4. Finally, we return the `count`.

## A solution in C++

```cpp
int commonFactors(int a, int b) {
    int gcd = std::__gcd(a, b);
    int count = 0;
    for (int i = 1; i * i <= gcd; i++) {
        if (gcd % i == 0) {
            count++;
            if (i * i != gcd)
                count++;
        }
    }
    return count;
}
```
1. First, we calculate the greatest common divisor (GCD) of the input integers `a` and `b` using the Euclidean algorithm.
2. Next, we initialize a `count` variable to store the number of common factors.
3. Then, we iterate through the numbers from 1 to the square root of the GCD.
   - For each number `i` that is a factor of the GCD, we increment the `count`.
   - If the square of `i` is not equal to the GCD, we increment the `count` again because there is another factor, which is `gcd // i`.
4. Finally, we return the `count`.

## A solution in Python

```python
def common_factors(a: int, b: int) -> int:
    from math import gcd

    g = gcd(a, b)
    count = 0
    for i in range(1, int(g**0.5) + 1):
        if g % i == 0:
            count += 1
            if i * i != g:
                count += 1
    return count
```
1. First, we calculate the greatest common divisor (GCD) of the input integers `a` and `b` using the Euclidean algorithm.
2. Next, we initialize a `count` variable to store the number of common factors.
3. Then, we iterate through the numbers from 1 to the square root of the GCD.
   - For each number `i` that is a factor of the GCD, we increment the `count`.
   - If the square of `i` is not equal to the GCD, we increment the `count` again because there is another factor, which is `gcd // i`.
4. Finally, we return the `count`.

## A solution in Javascript

```javascript
function commonFactors(a, b) {
    let gcd = (a, b) => b === 0 ? a : gcd(b, a % b);
    let g = gcd(a, b);
    let count = 0;
    for (let i = 1; i * i <= g; i++) {
        if (g % i === 0) {
            count++;
            if (i * i !== g)
                count++;
        }
    }
    return count;
}
```
1. First, we calculate the greatest common divisor (GCD) of the input integers `a` and `b` using the Euclidean algorithm.
2. Next, we initialize a `count` variable to store the number of common factors.
3. Then, we iterate through the numbers from 1 to the square root of the GCD.
   - For each number `i` that is a factor of the GCD, we increment the `count`.
   - If the square of `i` is not equal to the GCD, we increment the `count` again because there is another factor, which is `gcd // i`.
4. Finally, we return the `count`.


# Maximum Sum of an Hourglass

- slug: maximum-sum-of-an-hourglass
- difficulty: Medium

You are given an `m x n` integer matrix `grid`.

We define an **hourglass** as a part of the matrix with the following form:

Return _the **maximum** sum of the elements of an hourglass_.

**Note** that an hourglass cannot be rotated and must be entirely contained within the matrix.

**Example 1:**

**Input:** grid = \[\[6,2,1,3\],\[4,2,1,5\],\[9,2,8,7\],\[4,1,2,9\]\]
**Output:** 30
**Explanation:** The cells shown above represent the hourglass with the maximum sum: 6 + 2 + 1 + 2 + 9 + 2 + 8 = 30.

**Example 2:**

**Input:** grid = \[\[1,2,3\],\[4,5,6\],\[7,8,9\]\]
**Output:** 35
**Explanation:** There is only one hourglass in the matrix, with the sum: 1 + 2 + 3 + 5 + 7 + 8 + 9 = 35.

**Constraints:**

*   `m == grid.length`
*   `n == grid[i].length`
*   `3 <= m, n <= 150`
*   `0 <= grid[i][j] <= 106`

## A solution in Java

```java
public int maxHourglassSum(int[][] grid) {
    int m = grid.length, n = grid[0].length;
    int maxSum = Integer.MIN_VALUE;
    for(int i = 1; i < m - 1; ++i) {
        for(int j = 1; j < n - 1; ++j) {
            int sum = grid[i-1][j-1] + grid[i-1][j] + grid[i-1][j+1]
                      + grid[i][j]
                      + grid[i+1][j-1] + grid[i+1][j] + grid[i+1][j+1];
            maxSum = Math.max(maxSum, sum);
        }
    }
    return maxSum;
}
```
The problem requires us to find the maximum sum of hourglasses in the given grid.

We first find the dimensions of the grid, m and n. We initialize maxSum as the smallest integer value possible (-inf for Python).

Since the hourglass shape should be entirely contained within the grid, we start our traversal from (1,1), i.e., one cell shifted right and down from the top-left corner of the grid, continuing until (m-2, n-2). Both these indices are included in the traversal.

In the nested for loop, we calculate the hourglass sum for each cell by adding the values of its hourglass pattern: three cells horizontally from the cell above it, the cell itself, and three cells horizontally from the cell below it. We then compare the calculated sum with the current maxSum, keeping the larger value as the new maxSum.

Finally, we return the maxSum after traversing the entire grid.

## A solution in C++

```cpp
int maxHourglassSum(vector<vector<int>>& grid) {
    int m = grid.size(), n = grid[0].size();
    int maxSum = INT_MIN;
    for(int i = 1; i < m - 1; ++i) {
        for(int j = 1; j < n - 1; ++j) {
            int sum = grid[i-1][j-1] + grid[i-1][j] + grid[i-1][j+1]
                      + grid[i][j]
                      + grid[i+1][j-1] + grid[i+1][j] + grid[i+1][j+1];
            maxSum = max(maxSum, sum);
        }
    }
    return maxSum;
}
```
The problem requires us to find the maximum sum of hourglasses in the given grid.

We first find the dimensions of the grid, m and n. We initialize maxSum as the smallest integer value possible (-inf for Python).

Since the hourglass shape should be entirely contained within the grid, we start our traversal from (1,1), i.e., one cell shifted right and down from the top-left corner of the grid, continuing until (m-2, n-2). Both these indices are included in the traversal.

In the nested for loop, we calculate the hourglass sum for each cell by adding the values of its hourglass pattern: three cells horizontally from the cell above it, the cell itself, and three cells horizontally from the cell below it. We then compare the calculated sum with the current maxSum, keeping the larger value as the new maxSum.

Finally, we return the maxSum after traversing the entire grid.

## A solution in Python

```python
def max_hourglass_sum(grid):
    m, n = len(grid), len(grid[0])
    max_sum = float('-inf')
    for i in range(1, m - 1):
        for j in range(1, n - 1):
            sum = grid[i-1][j-1] + grid[i-1][j] + grid[i-1][j+1] \
                  + grid[i][j] \
                  + grid[i+1][j-1] + grid[i+1][j] + grid[i+1][j+1]
            max_sum = max(max_sum, sum)
    return max_sum
```
The problem requires us to find the maximum sum of hourglasses in the given grid.

We first find the dimensions of the grid, m and n. We initialize maxSum as the smallest integer value possible (-inf for Python).

Since the hourglass shape should be entirely contained within the grid, we start our traversal from (1,1), i.e., one cell shifted right and down from the top-left corner of the grid, continuing until (m-2, n-2). Both these indices are included in the traversal.

In the nested for loop, we calculate the hourglass sum for each cell by adding the values of its hourglass pattern: three cells horizontally from the cell above it, the cell itself, and three cells horizontally from the cell below it. We then compare the calculated sum with the current maxSum, keeping the larger value as the new maxSum.

Finally, we return the maxSum after traversing the entire grid.

## A solution in Javascript

```javascript
function maxHourglassSum(grid) {
    let m = grid.length, n = grid[0].length;
    let maxSum = -Infinity;
    for(let i = 1; i < m - 1; ++i) {
        for(let j = 1; j < n - 1; ++j) {
            let sum = grid[i-1][j-1] + grid[i-1][j] + grid[i-1][j+1]
                      + grid[i][j]
                      + grid[i+1][j-1] + grid[i+1][j] + grid[i+1][j+1];
            maxSum = Math.max(maxSum, sum);
        }
    }
    return maxSum;
}
```
The problem requires us to find the maximum sum of hourglasses in the given grid.

We first find the dimensions of the grid, m and n. We initialize maxSum as the smallest integer value possible (-inf for Python).

Since the hourglass shape should be entirely contained within the grid, we start our traversal from (1,1), i.e., one cell shifted right and down from the top-left corner of the grid, continuing until (m-2, n-2). Both these indices are included in the traversal.

In the nested for loop, we calculate the hourglass sum for each cell by adding the values of its hourglass pattern: three cells horizontally from the cell above it, the cell itself, and three cells horizontally from the cell below it. We then compare the calculated sum with the current maxSum, keeping the larger value as the new maxSum.

Finally, we return the maxSum after traversing the entire grid.


# Minimize XOR

- slug: minimize-xor
- difficulty: Medium

Given two positive integers `num1` and `num2`, find the positive integer `x` such that:

*   `x` has the same number of set bits as `num2`, and
*   The value `x XOR num1` is **minimal**.

Note that `XOR` is the bitwise XOR operation.

Return _the integer_ `x`. The test cases are generated such that `x` is **uniquely determined**.

The number of **set bits** of an integer is the number of `1`'s in its binary representation.

**Example 1:**

**Input:** num1 = 3, num2 = 5
**Output:** 3
**Explanation:**
The binary representations of num1 and num2 are 0011 and 0101, respectively.
The integer **3** has the same number of set bits as num2, and the value `3 XOR 3 = 0` is minimal.

**Example 2:**

**Input:** num1 = 1, num2 = 12
**Output:** 3
**Explanation:**
The binary representations of num1 and num2 are 0001 and 1100, respectively.
The integer **3** has the same number of set bits as num2, and the value `3 XOR 1 = 2` is minimal.

**Constraints:**

*   `1 <= num1, num2 <= 109`

## A solution in Java

```java
public int minSetXor(int num1, int num2) {
    int set_count = Integer.bitCount(num2);
    int x = 0;
    for (int i = 0; set_count > 0 && i < 32; i++) {
        if ((num2 >> i) & 1) {
            x |= (1 << i);
            set_count--;
        }
    }
    return x ^ num1;
}
```
The algorithm counts the number of set bits in num2, then iterates through each bit position in num2, adding the bit at that position to the integer x if it's set. The loop stops when the number of set bits specified in num2 is reached or all 32 bit positions are checked. Finally, the XOR of the generated x and num1 is calculated and returned as the minimal XOR value.

## A solution in C++

```cpp
int minSetXor(int num1, int num2) {
    int set_count = __builtin_popcount(num2);
    int x = 0;
    for (int i = 0; set_count > 0 && i < 32; i++) {
        if ((num2 >> i) & 1) {
            x |= (1 << i);
            set_count--;
        }
    }
    return x ^ num1;
}
```
The algorithm counts the number of set bits in num2, then iterates through each bit position in num2, adding the bit at that position to the integer x if it's set. The loop stops when the number of set bits specified in num2 is reached or all 32 bit positions are checked. Finally, the XOR of the generated x and num1 is calculated and returned as the minimal XOR value.

## A solution in Python

```python
def minSetXor(num1: int, num2: int) -> int:
    set_count = bin(num2).count('1')
    x = 0
    for i in range(32):
        if set_count <= 0:
            break
        if num2 & (1 << i):
            x |= (1 << i)
            set_count -= 1
    return x ^ num1
```
The algorithm counts the number of set bits in num2, then iterates through each bit position in num2, adding the bit at that position to the integer x if it's set. The loop stops when the number of set bits specified in num2 is reached or all 32 bit positions are checked. Finally, the XOR of the generated x and num1 is calculated and returned as the minimal XOR value.

## A solution in Javascript

```javascript
function minSetXor(num1, num2) {
    let set_count = num2.toString(2).split('1').length - 1;
    let x = 0;
    for (let i = 0; set_count > 0 && i < 32; i++) {
        if ((num2 >> i) & 1) {
            x |= (1 << i);
            set_count--;
        }
    }
    return x ^ num1;
}
```
The algorithm counts the number of set bits in num2, then iterates through each bit position in num2, adding the bit at that position to the integer x if it's set. The loop stops when the number of set bits specified in num2 is reached or all 32 bit positions are checked. Finally, the XOR of the generated x and num1 is calculated and returned as the minimal XOR value.


# Maximum Deletions on a String

- slug: maximum-deletions-on-a-string
- difficulty: Hard

You are given a string `s` consisting of only lowercase English letters. In one operation, you can:

*   Delete **the entire string** `s`, or
*   Delete the **first** `i` letters of `s` if the first `i` letters of `s` are **equal** to the following `i` letters in `s`, for any `i` in the range `1 <= i <= s.length / 2`.

For example, if `s = "ababc "`, then in one operation, you could delete the first two letters of `s` to get `"abc "`, since the first two letters of `s` and the following two letters of `s` are both equal to `"ab "`.

Return _the **maximum** number of operations needed to delete all of_ `s`.

**Example 1:**

**Input:** s =  "abcabcdabc "
**Output:** 2
**Explanation:**
- Delete the first 3 letters ( "abc ") since the next 3 letters are equal. Now, s =  "abcdabc ".
- Delete all the letters.
We used 2 operations so return 2. It can be proven that 2 is the maximum number of operations needed.
Note that in the second operation we cannot delete  "abc " again because the next occurrence of  "abc " does not happen in the next 3 letters.

**Example 2:**

**Input:** s =  "aaabaab "
**Output:** 4
**Explanation:**
- Delete the first letter ( "a ") since the next letter is equal. Now, s =  "aabaab ".
- Delete the first 3 letters ( "aab ") since the next 3 letters are equal. Now, s =  "aab ".
- Delete the first letter ( "a ") since the next letter is equal. Now, s =  "ab ".
- Delete all the letters.
We used 4 operations so return 4. It can be proven that 4 is the maximum number of operations needed.

**Example 3:**

**Input:** s =  "aaaaa "
**Output:** 5
**Explanation:** In each operation, we can delete the first letter of s.

**Constraints:**

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

## A solution in Java

```java
public int maxOperations(String s) {
    int count = 0;
    while (!s.isEmpty()) {
        for (int i = s.length() / 2; i > 0; i--) {
            if (s.substring(0, i).equals(s.substring(i, 2 * i))) {
                s = s.substring(i);
                count++;
                break;
            } else if (i == 1) {
                s = s.substring(1);
                count++;
            }
        }
    }
    return count;
}
```
The algorithm repeatedly performs the delete operation until the input string `s` becomes empty. In each iteration, the algorithm checks if the first `i` letters are equal to the following `i` letters in `s`. If it finds such `i`, it erases the first `i` letters and increments the `count`. Else, it erases the first letter and increments the `count` if no such `i` is found in the previous step.

The time complexity of the algorithm is O(n^2) where n is the length of the input string `s`.

## A solution in C++

```cpp
int maxOperations(std::string s) {
    int count = 0;
    while (!s.empty()) {
        for (int i = s.length() / 2; i > 0; i--) {
            if (s.substr(0, i) == s.substr(i, i)) {
                s.erase(0, i);
                count++;
                break;
            } else if (i == 1) {
                s.erase(0, 1);
                count++;
            }
        }
    }
    return count;
}
```
The algorithm repeatedly performs the delete operation until the input string `s` becomes empty. In each iteration, the algorithm checks if the first `i` letters are equal to the following `i` letters in `s`. If it finds such `i`, it erases the first `i` letters and increments the `count`. Else, it erases the first letter and increments the `count` if no such `i` is found in the previous step.

The time complexity of the algorithm is O(n^2) where n is the length of the input string `s`.

## A solution in Python

```python
def maxOperations(s: str) -> int:
    count = 0
    while s:
        for i in range(len(s) // 2, 0, -1):
            if s[:i] == s[i:2*i]:
                s = s[i:]
                count += 1
                break
            elif i == 1:
                s = s[1:]
                count += 1
    return count
```
The algorithm repeatedly performs the delete operation until the input string `s` becomes empty. In each iteration, the algorithm checks if the first `i` letters are equal to the following `i` letters in `s`. If it finds such `i`, it erases the first `i` letters and increments the `count`. Else, it erases the first letter and increments the `count` if no such `i` is found in the previous step.

The time complexity of the algorithm is O(n^2) where n is the length of the input string `s`.

## A solution in Javascript

```javascript
function maxOperations(s) {
    let count = 0;
    while (s.length > 0) {
        for (let i = Math.floor(s.length / 2); i > 0; i--) {
            if (s.slice(0, i) === s.slice(i, 2 * i)) {
                s = s.slice(i);
                count++;
                break;
            } else if (i === 1) {
                s = s.slice(1);
                count++;
            }
        }
    }
    return count;
}
```
The algorithm repeatedly performs the delete operation until the input string `s` becomes empty. In each iteration, the algorithm checks if the first `i` letters are equal to the following `i` letters in `s`. If it finds such `i`, it erases the first `i` letters and increments the `count`. Else, it erases the first letter and increments the `count` if no such `i` is found in the previous step.

The time complexity of the algorithm is O(n^2) where n is the length of the input string `s`.


# Maximize Total Tastiness of Purchased Fruits

- slug: maximize-total-tastiness-of-purchased-fruits
- difficulty: Medium

You are given two non-negative integer arrays `price` and `tastiness`, both arrays have the same length `n`. You are also given two non-negative integers `maxAmount` and `maxCoupons`.

For every integer `i` in range `[0, n - 1]`:

*   `price[i]` describes the price of `ith` fruit.
*   `tastiness[i]` describes the tastiness of `ith` fruit.

You want to purchase some fruits such that total tastiness is maximized and the total price does not exceed `maxAmount`.

Additionally, you can use a coupon to purchase fruit for **half of its price** (rounded down to the closest integer). You can use at most `maxCoupons` of such coupons.

Return _the maximum total tastiness that can be purchased_.

**Note that:**

*   You can purchase each fruit at most once.
*   You can use coupons on some fruit at most once.

**Example 1:**

**Input:** price = \[10,20,20\], tastiness = \[5,8,8\], maxAmount = 20, maxCoupons = 1
**Output:** 13
**Explanation:** It is possible to make total tastiness 13 in following way:
- Buy first fruit without coupon, so that total price = 0 + 10 and total tastiness = 0 + 5.
- Buy second fruit with coupon, so that total price = 10 + 10 and total tastiness = 5 + 8.
- Do not buy third fruit, so that total price = 20 and total tastiness = 13.
It can be proven that 13 is the maximum total tastiness that can be obtained.

**Example 2:**

**Input:** price = \[10,15,7\], tastiness = \[5,8,20\], maxAmount = 10, maxCoupons = 2
**Output:** 28
**Explanation:** It is possible to make total tastiness 20 in following way:
- Do not buy first fruit, so that total price = 0 and total tastiness = 0.
- Buy second fruit with coupon, so that total price = 0 + 7 and total tastiness = 0 + 8.
- Buy third fruit with coupon, so that total price = 7 + 3 and total tastiness = 8 + 20.
It can be proven that 28 is the maximum total tastiness that can be obtained.

**Constraints:**

*   `n == price.length == tastiness.length`
*   `1 <= n <= 100`
*   `0 <= price[i], tastiness[i], maxAmount <= 1000`
*   `0 <= maxCoupons <= 5`

## A solution in Java

```java
public int maxTastiness(int[] price, int[] tastiness, int maxAmount, int maxCoupons) {
    int n = price.length;
    int[][][] dp = new int[n + 1][maxAmount + 1][maxCoupons + 1];

    for (int i = 1; i <= n; i++) {
        int fruit_price = price[i - 1];
        int fruit_tastiness = tastiness[i - 1];
        int half_fruit_price = fruit_price / 2;

        for (int j = 0; j <= maxAmount; j++) {
            for (int k = 0; k <= maxCoupons; k++) {
                dp[i][j][k] = dp[i - 1][j][k];
                if (j >= fruit_price) {
                    dp[i][j][k] = Math.max(dp[i][j][k], dp[i - 1][j - fruit_price][k] + fruit_tastiness);
                }
                if (k > 0 && j >= half_fruit_price) {
                    dp[i][j][k] = Math.max(dp[i][j][k], dp[i - 1][j - half_fruit_price][k - 1] + fruit_tastiness);
                }
            }
        }
    }

    return dp[n][maxAmount][maxCoupons];
}
```
We solve the problem using dynamic programming. Our state is represented by three dimensions:

1. The index of the current fruit (0-based)
2. The current amount spent
3. The number of coupons used

The dp array is initialized as a 3D array filled with zeros. Then, we iterate through the fruits, updating the dp array based on whether we buy the current fruit or not, and whether we use a coupon to buy it.

For each fruit, we iterate through all possible amounts spent and all possible numbers of coupons used. We have three cases to consider when updating the dp array:

1. We do not buy the current fruit: `dp[i][j][k] = dp[i - 1][j][k]`
2. We buy the current fruit without a coupon: If `j >= fruit_price`, `dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - fruit_price][k] + fruit_tastiness)`
3. We buy the current fruit with a coupon: If `k > 0 && j >= half_fruit_price`, `dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - half_fruit_price][k - 1] + fruit_tastiness)`

After iterating through all the fruits, amounts, and coupons, the maximum tastiness that can be obtained is stored in `dp[n][maxAmount][maxCoupons]`.

## A solution in C++

```cpp
int maxTastiness(vector<int>& price, vector<int>& tastiness, int maxAmount, int maxCoupons) {
    int n = price.size();
    vector<vector<vector<int>>> dp(n + 1, vector<vector<int>>(maxAmount + 1, vector<int>(maxCoupons + 1, 0)));

    for (int i = 1; i <= n; i++) {
        int fruit_price = price[i - 1];
        int fruit_tastiness = tastiness[i - 1];
        int half_fruit_price = fruit_price / 2;

        for (int j = 0; j <= maxAmount; j++) {
            for (int k = 0; k <= maxCoupons; k++) {
                dp[i][j][k] = dp[i - 1][j][k];
                if (j >= fruit_price) {
                    dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - fruit_price][k] + fruit_tastiness);
                }
                if (k > 0 && j >= half_fruit_price) {
                    dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - half_fruit_price][k - 1] + fruit_tastiness);
                }
            }
        }
    }

    return dp[n][maxAmount][maxCoupons];
}
```
We solve the problem using dynamic programming. Our state is represented by three dimensions:

1. The index of the current fruit (0-based)
2. The current amount spent
3. The number of coupons used

The dp array is initialized as a 3D array filled with zeros. Then, we iterate through the fruits, updating the dp array based on whether we buy the current fruit or not, and whether we use a coupon to buy it.

For each fruit, we iterate through all possible amounts spent and all possible numbers of coupons used. We have three cases to consider when updating the dp array:

1. We do not buy the current fruit: `dp[i][j][k] = dp[i - 1][j][k]`
2. We buy the current fruit without a coupon: If `j >= fruit_price`, `dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - fruit_price][k] + fruit_tastiness)`
3. We buy the current fruit with a coupon: If `k > 0 && j >= half_fruit_price`, `dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - half_fruit_price][k - 1] + fruit_tastiness)`

After iterating through all the fruits, amounts, and coupons, the maximum tastiness that can be obtained is stored in `dp[n][maxAmount][maxCoupons]`.

## A solution in Python

```python
def maxTastiness(price, tastiness, maxAmount, maxCoupons):
    n = len(price)
    dp = [[[0] * (maxCoupons + 1) for _ in range(maxAmount + 1)] for _ in range(n + 1)]

    for i in range(1, n + 1):
        fruit_price = price[i - 1]
        fruit_tastiness = tastiness[i - 1]
        half_fruit_price = fruit_price // 2

        for j in range(maxAmount + 1):
            for k in range(maxCoupons + 1):
                dp[i][j][k] = dp[i - 1][j][k]
                if j >= fruit_price:
                    dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - fruit_price][k] + fruit_tastiness)
                if k > 0 and j >= half_fruit_price:
                    dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - half_fruit_price][k - 1] + fruit_tastiness)

    return dp[n][maxAmount][maxCoupons]
```
We solve the problem using dynamic programming. Our state is represented by three dimensions:

1. The index of the current fruit (0-based)
2. The current amount spent
3. The number of coupons used

The dp array is initialized as a 3D array filled with zeros. Then, we iterate through the fruits, updating the dp array based on whether we buy the current fruit or not, and whether we use a coupon to buy it.

For each fruit, we iterate through all possible amounts spent and all possible numbers of coupons used. We have three cases to consider when updating the dp array:

1. We do not buy the current fruit: `dp[i][j][k] = dp[i - 1][j][k]`
2. We buy the current fruit without a coupon: If `j >= fruit_price`, `dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - fruit_price][k] + fruit_tastiness)`
3. We buy the current fruit with a coupon: If `k > 0 && j >= half_fruit_price`, `dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - half_fruit_price][k - 1] + fruit_tastiness)`

After iterating through all the fruits, amounts, and coupons, the maximum tastiness that can be obtained is stored in `dp[n][maxAmount][maxCoupons]`.

## A solution in Javascript

```javascript
function maxTastiness(price, tastiness, maxAmount, maxCoupons) {
    const n = price.length;
    const dp = new Array(n + 1).fill(0).map(() => new Array(maxAmount + 1).fill(0).map(() => new Array(maxCoupons + 1).fill(0)));

    for (let i = 1; i <= n; i++) {
        const fruit_price = price[i - 1];
        const fruit_tastiness = tastiness[i - 1];
        const half_fruit_price = Math.floor(fruit_price / 2);

        for (let j = 0; j <= maxAmount; j++) {
            for (let k = 0; k <= maxCoupons; k++) {
                dp[i][j][k] = dp[i - 1][j][k];
                if (j >= fruit_price) {
                    dp[i][j][k] = Math.max(dp[i][j][k], dp[i - 1][j - fruit_price][k] + fruit_tastiness);
                }
                if (k > 0 && j >= half_fruit_price) {
                    dp[i][j][k] = Math.max(dp[i][j][k], dp[i - 1][j - half_fruit_price][k - 1] + fruit_tastiness);
                }
            }
        }
    }

    return dp[n][maxAmount][maxCoupons];
}
```
We solve the problem using dynamic programming. Our state is represented by three dimensions:

1. The index of the current fruit (0-based)
2. The current amount spent
3. The number of coupons used

The dp array is initialized as a 3D array filled with zeros. Then, we iterate through the fruits, updating the dp array based on whether we buy the current fruit or not, and whether we use a coupon to buy it.

For each fruit, we iterate through all possible amounts spent and all possible numbers of coupons used. We have three cases to consider when updating the dp array:

1. We do not buy the current fruit: `dp[i][j][k] = dp[i - 1][j][k]`
2. We buy the current fruit without a coupon: If `j >= fruit_price`, `dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - fruit_price][k] + fruit_tastiness)`
3. We buy the current fruit with a coupon: If `k > 0 && j >= half_fruit_price`, `dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - half_fruit_price][k - 1] + fruit_tastiness)`

After iterating through all the fruits, amounts, and coupons, the maximum tastiness that can be obtained is stored in `dp[n][maxAmount][maxCoupons]`.


# The Employee That Worked on the Longest Task

- slug: the-employee-that-worked-on-the-longest-task
- difficulty: Easy

There are `n` employees, each with a unique id from `0` to `n - 1`.

You are given a 2D integer array `logs` where `logs[i] = [idi, leaveTimei]` where:

*   `idi` is the id of the employee that worked on the `ith` task, and
*   `leaveTimei` is the time at which the employee finished the `ith` task. All the values `leaveTimei` are **unique**.

Note that the `ith` task starts the moment right after the `(i - 1)th` task ends, and the `0th` task starts at time `0`.

Return _the id of the employee that worked the task with the longest time._ If there is a tie between two or more employees, return _the **smallest** id among them_.

**Example 1:**

**Input:** n = 10, logs = \[\[0,3\],\[2,5\],\[0,9\],\[1,15\]\]
**Output:** 1
**Explanation:**
Task 0 started at 0 and ended at 3 with 3 units of times.
Task 1 started at 3 and ended at 5 with 2 units of times.
Task 2 started at 5 and ended at 9 with 4 units of times.
Task 3 started at 9 and ended at 15 with 6 units of times.
The task with the longest time is task 3 and the employee with id 1 is the one that worked on it, so we return 1.

**Example 2:**

**Input:** n = 26, logs = \[\[1,1\],\[3,7\],\[2,12\],\[7,17\]\]
**Output:** 3
**Explanation:**
Task 0 started at 0 and ended at 1 with 1 unit of times.
Task 1 started at 1 and ended at 7 with 6 units of times.
Task 2 started at 7 and ended at 12 with 5 units of times.
Task 3 started at 12 and ended at 17 with 5 units of times.
The tasks with the longest time is task 1. The employees that worked on it is 3, so we return 3.

**Example 3:**

**Input:** n = 2, logs = \[\[0,10\],\[1,20\]\]
**Output:** 0
**Explanation:**
Task 0 started at 0 and ended at 10 with 10 units of times.
Task 1 started at 10 and ended at 20 with 10 units of times.
The tasks with the longest time are tasks 0 and 1. The employees that worked on them are 0 and 1, so we return the smallest id 0.

**Constraints:**

*   `2 <= n <= 500`
*   `1 <= logs.length <= 500`
*   `logs[i].length == 2`
*   `0 <= idi <= n - 1`
*   `1 <= leaveTimei <= 500`
*   `idi != idi+1`
*   `leaveTimei` are sorted in a strictly increasing order.

## A solution in Java

```java
public int workerWithLongestTask(int n, int[][] logs) {
    int result = 0;
    int max_time = logs[0][1] - 0;

    for (int i = 1; i < logs.length; ++i) {
        int time = logs[i][1] - logs[i-1][1];
        if (time > max_time) {
            max_time = time;
            result = logs[i][0];
        }
    }
    return result;
}
```
The algorithm iterates through the array `logs` one task at a time. For each task, the algorithm computes the time it took to complete the task by subtracting the leave time of the previous task from the leave time of the current task. We initialize the `max_time` with the first task duration and set the `result` to the ID of the first task worker.

During iteration, if the computed time for the current task is greater than the `max_time`, the algorithm updates the `max_time` to the current task's time and selects the worker of the current task as `result`.

After iterating through all tasks, the algorithm returns the worker ID in `result`, which is the worker that worked the task with the longest time. If there is a tie, the algorithm will return the smallest ID among them since we only update the `result` when we find a strictly greater time.

## A solution in C++

```cpp
int workerWithLongestTask(int n, vector<vector<int>>& logs) {
    int result = 0;
    int max_time = logs[0][1] - 0;

    for (int i = 1; i < logs.size(); ++i) {
        int time = logs[i][1] - logs[i-1][1];
        if (time > max_time) {
            max_time = time;
            result = logs[i][0];
        }
    }
    return result;
}
```
The algorithm iterates through the array `logs` one task at a time. For each task, the algorithm computes the time it took to complete the task by subtracting the leave time of the previous task from the leave time of the current task. We initialize the `max_time` with the first task duration and set the `result` to the ID of the first task worker.

During iteration, if the computed time for the current task is greater than the `max_time`, the algorithm updates the `max_time` to the current task's time and selects the worker of the current task as `result`.

After iterating through all tasks, the algorithm returns the worker ID in `result`, which is the worker that worked the task with the longest time. If there is a tie, the algorithm will return the smallest ID among them since we only update the `result` when we find a strictly greater time.

## A solution in Python

```python
def worker_with_longest_task(n, logs):
    result = 0
    max_time = logs[0][1] - 0

    for i in range(1, len(logs)):
        time = logs[i][1] - logs[i-1][1]
        if time > max_time:
            max_time = time
            result = logs[i][0]

    return result
```
The algorithm iterates through the array `logs` one task at a time. For each task, the algorithm computes the time it took to complete the task by subtracting the leave time of the previous task from the leave time of the current task. We initialize the `max_time` with the first task duration and set the `result` to the ID of the first task worker.

During iteration, if the computed time for the current task is greater than the `max_time`, the algorithm updates the `max_time` to the current task's time and selects the worker of the current task as `result`.

After iterating through all tasks, the algorithm returns the worker ID in `result`, which is the worker that worked the task with the longest time. If there is a tie, the algorithm will return the smallest ID among them since we only update the `result` when we find a strictly greater time.

## A solution in Javascript

```javascript
function workerWithLongestTask(n, logs) {
    let result = 0;
    let max_time = logs[0][1] - 0;

    for (let i = 1; i < logs.length; ++i) {
        let time = logs[i][1] - logs[i-1][1];
        if (time > max_time) {
            max_time = time;
            result = logs[i][0];
        }
    }
    return result;
}
```
The algorithm iterates through the array `logs` one task at a time. For each task, the algorithm computes the time it took to complete the task by subtracting the leave time of the previous task from the leave time of the current task. We initialize the `max_time` with the first task duration and set the `result` to the ID of the first task worker.

During iteration, if the computed time for the current task is greater than the `max_time`, the algorithm updates the `max_time` to the current task's time and selects the worker of the current task as `result`.

After iterating through all tasks, the algorithm returns the worker ID in `result`, which is the worker that worked the task with the longest time. If there is a tie, the algorithm will return the smallest ID among them since we only update the `result` when we find a strictly greater time.


# Find The Original Array of Prefix Xor

- slug: find-the-original-array-of-prefix-xor
- difficulty: Medium

You are given an **integer** array `pref` of size `n`. Find and return _the array_ `arr` _of size_ `n` _that satisfies_:

*   `pref[i] = arr[0] ^ arr[1] ^ ... ^ arr[i]`.

Note that `^` denotes the **bitwise-xor** operation.

It can be proven that the answer is **unique**.

**Example 1:**

**Input:** pref = \[5,2,0,3,1\]
**Output:** \[5,7,2,3,2\]
**Explanation:** From the array \[5,7,2,3,2\] we have the following:
- pref\[0\] = 5.
- pref\[1\] = 5 ^ 7 = 2.
- pref\[2\] = 5 ^ 7 ^ 2 = 0.
- pref\[3\] = 5 ^ 7 ^ 2 ^ 3 = 3.
- pref\[4\] = 5 ^ 7 ^ 2 ^ 3 ^ 2 = 1.

**Example 2:**

**Input:** pref = \[13\]
**Output:** \[13\]
**Explanation:** We have pref\[0\] = arr\[0\] = 13.

**Constraints:**

*   `1 <= pref.length <= 105`
*   `0 <= pref[i] <= 106`

## A solution in Java

```java
public int[] findArray(int[] pref) {
    int[] arr = new int[pref.length];
    arr[0] = pref[0];
    for (int i = 1; i < pref.length; ++i) {
        arr[i] = pref[i] ^ pref[i - 1];
    }
    return arr;
}
```
The function first initializes the first element of the `arr` array to the first element of the input `pref` array. Then, for each remaining element in the `pref` array, the function calculates the corresponding `arr` element by XORing the current `pref` element with the previous `pref` element. This is based on the property of XOR, where `(a ^ b) ^ b == a`. After all elements in the `arr` array are calculated, the function returns the `arr` array.

## A solution in C++

```cpp
vector<int> findArray(vector<int>& pref) {
    vector<int> arr(pref.size());
    arr[0] = pref[0];
    for (int i = 1; i < pref.size(); ++i) {
        arr[i] = pref[i] ^ pref[i - 1];
    }
    return arr;
}
```
The function first initializes the first element of the `arr` array to the first element of the input `pref` array. Then, for each remaining element in the `pref` array, the function calculates the corresponding `arr` element by XORing the current `pref` element with the previous `pref` element. This is based on the property of XOR, where `(a ^ b) ^ b == a`. After all elements in the `arr` array are calculated, the function returns the `arr` array.

## A solution in Python

```python
def findArray(pref):
    arr = [pref[0]]
    for i in range(1, len(pref)):
        arr.append(pref[i] ^ pref[i - 1])
    return arr
```
The function first initializes the first element of the `arr` array to the first element of the input `pref` array. Then, for each remaining element in the `pref` array, the function calculates the corresponding `arr` element by XORing the current `pref` element with the previous `pref` element. This is based on the property of XOR, where `(a ^ b) ^ b == a`. After all elements in the `arr` array are calculated, the function returns the `arr` array.

## A solution in Javascript

```javascript
function findArray(pref) {
    const arr = new Array(pref.length);
    arr[0] = pref[0];
    for (let i = 1; i < pref.length; ++i) {
        arr[i] = pref[i] ^ pref[i - 1];
    }
    return arr;
}
```
The function first initializes the first element of the `arr` array to the first element of the input `pref` array. Then, for each remaining element in the `pref` array, the function calculates the corresponding `arr` element by XORing the current `pref` element with the previous `pref` element. This is based on the property of XOR, where `(a ^ b) ^ b == a`. After all elements in the `arr` array are calculated, the function returns the `arr` array.