# Maximize Grid Happiness

- slug: maximize-grid-happiness
- difficulty: Hard

You are given four integers, `m`, `n`, `introvertsCount`, and `extrovertsCount`. You have an `m x n` grid, and there are two types of people: introverts and extroverts. There are `introvertsCount` introverts and `extrovertsCount` extroverts.

You should decide how many people you want to live in the grid and assign each of them one grid cell. Note that you **do not** have to have all the people living in the grid.

The **happiness** of each person is calculated as follows:

*   Introverts **start** with `120` happiness and **lose** `30` happiness for each neighbor (introvert or extrovert).
*   Extroverts **start** with `40` happiness and **gain** `20` happiness for each neighbor (introvert or extrovert).

Neighbors live in the directly adjacent cells north, east, south, and west of a person's cell.

The **grid happiness** is the **sum** of each person's happiness. Return _the **maximum possible grid happiness**._

**Example 1:**

**Input:** m = 2, n = 3, introvertsCount = 1, extrovertsCount = 2
**Output:** 240
**Explanation:** Assume the grid is 1-indexed with coordinates (row, column).
We can put the introvert in cell (1,1) and put the extroverts in cells (1,3) and (2,3).
- Introvert at (1,1) happiness: 120 (starting happiness) - (0 \* 30) (0 neighbors) = 120
- Extrovert at (1,3) happiness: 40 (starting happiness) + (1 \* 20) (1 neighbor) = 60
- Extrovert at (2,3) happiness: 40 (starting happiness) + (1 \* 20) (1 neighbor) = 60
The grid happiness is 120 + 60 + 60 = 240.
The above figure shows the grid in this example with each person's happiness. The introvert stays in the light green cell while the extroverts live on the light purple cells.

**Example 2:**

**Input:** m = 3, n = 1, introvertsCount = 2, extrovertsCount = 1
**Output:** 260
**Explanation:** Place the two introverts in (1,1) and (3,1) and the extrovert at (2,1).
- Introvert at (1,1) happiness: 120 (starting happiness) - (1 \* 30) (1 neighbor) = 90
- Extrovert at (2,1) happiness: 40 (starting happiness) + (2 \* 20) (2 neighbors) = 80
- Introvert at (3,1) happiness: 120 (starting happiness) - (1 \* 30) (1 neighbor) = 90
The grid happiness is 90 + 80 + 90 = 260.

**Example 3:**

**Input:** m = 2, n = 2, introvertsCount = 4, extrovertsCount = 0
**Output:** 240

**Constraints:**

*   `1 <= m, n <= 5`
*   `0 <= introvertsCount, extrovertsCount <= min(m * n, 6)`

## A solution in Java

```java
import java.util.*;

public int maxSum(int[] nums1, int[] nums2) {
    int mod = 1000000007;
    int m = nums1.length, n = nums2.length;
    long[] dp1 = new long[m + 1], dp2 = new long[n + 1];
    int i = m - 1, j = n - 1;
    while (i >= 0 || j >= 0) {
        long a = i >= 0 ? dp1[i] + nums1[i] : Long.MIN_VALUE;
        long b = j >= 0 ? dp2[j] + nums2[j] : Long.MIN_VALUE;
        Set<Integer> seen = new HashSet<>();
        if (a > b) {
            dp1[i--] = a % mod;
            seen.add(nums1[i + 1]);
        } else {
            dp2[j--] = b % mod;
            seen.add(nums2[j + 1]);
        }
    }
    return (int) Math.max(dp1[0], dp2[0]) % mod;
}
```
The algorithm used to solve this problem is dynamic programming. We create two dp arrays, dp1 and dp2, for nums1 and nums2 respectively. We loop in reverse through both nums1 and nums2, and for each step, we calculate the current sum with the current nums1[i] or nums2[j]. We track the uniques values using the 'seen' set. We'll update the dp array with the maximum sum at each step. Finally, we return the maximum value of the two dp arrays modulo 10^9 + 7.

At each step, the time complexity is O(1), and we need to perform a total of m + n steps where m and n are the sizes of nums1 and nums2. So, the total time complexity is O(m+n).

## A solution in C++

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

int maxSum(vector<int>& nums1, vector<int>& nums2) {
    int mod = 1e9 + 7;
    int m = nums1.size(), n = nums2.size();
    long dp1[m + 1] = {0}, dp2[n + 1] = {0};
    int i = m - 1, j = n - 1;
    while (i >= 0 || j >= 0) {
        long a = i >= 0 ? dp1[i] + nums1[i] : LONG_MIN;
        long b = j >= 0 ? dp2[j] + nums2[j] : LONG_MIN;
        set<int> seen;
        if (a > b) {
            dp1[i--] = a % mod;
            seen.insert(nums1[i + 1]);
        } else {
            dp2[j--] = b % mod;
            seen.insert(nums2[j + 1]);
        }
    }
    return max(dp1[0], dp2[0]) % mod;
}
```
The algorithm used to solve this problem is dynamic programming. We create two dp arrays, dp1 and dp2, for nums1 and nums2 respectively. We loop in reverse through both nums1 and nums2, and for each step, we calculate the current sum with the current nums1[i] or nums2[j]. We track the uniques values using the 'seen' set. We'll update the dp array with the maximum sum at each step. Finally, we return the maximum value of the two dp arrays modulo 10^9 + 7.

At each step, the time complexity is O(1), and we need to perform a total of m + n steps where m and n are the sizes of nums1 and nums2. So, the total time complexity is O(m+n).

## A solution in Python

```python
def maxSum(nums1, nums2):
    mod = 10**9 + 7
    m, n = len(nums1), len(nums2)
    dp1, dp2 = [0] * (m + 1), [0] * (n + 1)
    i, j = m - 1, n - 1
    while i >= 0 or j >= 0:
        a = dp1[i] + nums1[i] if i >= 0 else float('-inf')
        b = dp2[j] + nums2[j] if j >= 0 else float('-inf')
        seen = set()
        if a > b:
            dp1[i] = a % mod
            i -= 1
            seen.add(nums1[i + 1])
        else:
            dp2[j] = b % mod
            j -= 1
            seen.add(nums2[j + 1])
    return max(dp1[0], dp2[0]) % mod
```
The algorithm used to solve this problem is dynamic programming. We create two dp arrays, dp1 and dp2, for nums1 and nums2 respectively. We loop in reverse through both nums1 and nums2, and for each step, we calculate the current sum with the current nums1[i] or nums2[j]. We track the uniques values using the 'seen' set. We'll update the dp array with the maximum sum at each step. Finally, we return the maximum value of the two dp arrays modulo 10^9 + 7.

At each step, the time complexity is O(1), and we need to perform a total of m + n steps where m and n are the sizes of nums1 and nums2. So, the total time complexity is O(m+n).

## A solution in Javascript

```javascript
function maxSum(nums1, nums2) {
    const mod = 1e9 + 7;
    const m = nums1.length, n = nums2.length;
    const dp1 = new Array(m + 1).fill(0), dp2 = new Array(n + 1).fill(0);
    let i = m - 1, j = n - 1;
    while (i >= 0 || j >= 0) {
        const a = i >= 0 ? dp1[i] + nums1[i] : Number.MIN_SAFE_INTEGER;
        const b = j >= 0 ? dp2[j] + nums2[j] : Number.MIN_SAFE_INTEGER;
        const seen = new Set();
        if (a > b) {
            dp1[i--] = a % mod;
            seen.add(nums1[i + 1]);
        } else {
            dp2[j--] = b % mod;
            seen.add(nums2[j + 1]);
        }
    }
    return Math.max(dp1[0], dp2[0]) % mod;
}
```
The algorithm used to solve this problem is dynamic programming. We create two dp arrays, dp1 and dp2, for nums1 and nums2 respectively. We loop in reverse through both nums1 and nums2, and for each step, we calculate the current sum with the current nums1[i] or nums2[j]. We track the uniques values using the 'seen' set. We'll update the dp array with the maximum sum at each step. Finally, we return the maximum value of the two dp arrays modulo 10^9 + 7.

At each step, the time complexity is O(1), and we need to perform a total of m + n steps where m and n are the sizes of nums1 and nums2. So, the total time complexity is O(m+n).


# Correct a Binary Tree

- slug: correct-a-binary-tree
- difficulty: Medium

You have a binary tree with a small defect. There is **exactly one** invalid node where its right child incorrectly points to another node at the **same depth** but to the **invalid node's right**.

Given the root of the binary tree with this defect, `root`, return _the root of the binary tree after **removing** this invalid node **and every node underneath it** (minus the node it incorrectly points to)._

**Custom testing:**

The test input is read as 3 lines:

*   `TreeNode root`
*   `int fromNode` (**not available to** `correctBinaryTree`)
*   `int toNode` (**not available to** `correctBinaryTree`)

After the binary tree rooted at `root` is parsed, the `TreeNode` with value of `fromNode` will have its right child pointer pointing to the `TreeNode` with a value of `toNode`. Then, `root` is passed to `correctBinaryTree`.

**Example 1:**

**Input:** root = \[1,2,3\], fromNode = 2, toNode = 3
**Output:** \[1,null,3\]
**Explanation:** The node with value 2 is invalid, so remove it.

**Example 2:**

**Input:** root = \[8,3,1,7,null,9,4,2,null,null,null,5,6\], fromNode = 7, toNode = 4
**Output:** \[8,3,1,null,null,9,4,null,null,5,6\]
**Explanation:** The node with value 7 is invalid, so remove it and the node underneath it, node 2.

**Constraints:**

*   The number of nodes in the tree is in the range `[3, 104]`.
*   `-109 <= Node.val <= 109`
*   All `Node.val` are **unique**.
*   `fromNode != toNode`
*   `fromNode` and `toNode` will exist in the tree and will be on the same depth.
*   `toNode` is to the **right** of `fromNode`.
*   `fromNode.right` is `null` in the initial tree from the test data.

## A solution in Java

```java
public String thousandSeparator(int n) {
    String result = Integer.toString(n);
    int count = 0;
    for (int i = result.length() - 1; i > 0; --i) {
        count++;
        if (count % 3 == 0) {
            result = result.substring(0, i) + "." + result.substring(i);
        }
    }
    return result;
}
```
The algorithm first converts the given integer `n` into a string format. We'll be iterating through the string in reverse order (from last to first character) to insert dots at the thousands positions.

We keep a count initialized to 0. During the iteration, we increment the count until it's divisible by 3 (meaning we reached a thousands position). At this point, we insert the dot in the string at position `i`. The insertion process is slightly different for each programming language, but the overall idea is the same.

After the iteration is complete, we return the modified string with dots as thousands separators. This solution works for each of the mentioned programming languages using similar logic and some language-specific syntax adjustments.

## A solution in C++

```cpp
#include <string>

std::string thousandSeparator(int n) {
    std::string result = std::to_string(n);
    int count = 0;
    for (int i = result.size() - 1; i > 0; --i) {
        count++;
        if (count % 3 == 0) {
            result.insert(i, ".");
        }
    }
    return result;
}
```
The algorithm first converts the given integer `n` into a string format. We'll be iterating through the string in reverse order (from last to first character) to insert dots at the thousands positions.

We keep a count initialized to 0. During the iteration, we increment the count until it's divisible by 3 (meaning we reached a thousands position). At this point, we insert the dot in the string at position `i`. The insertion process is slightly different for each programming language, but the overall idea is the same.

After the iteration is complete, we return the modified string with dots as thousands separators. This solution works for each of the mentioned programming languages using similar logic and some language-specific syntax adjustments.

## A solution in Python

```python
def thousand_separator(n: int) -> str:
    result = str(n)
    count = 0
    for i in range(len(result) - 1, 0, -1):
        count += 1
        if count % 3 == 0:
            result = result[:i] + '.' + result[i:]
    return result
```
The algorithm first converts the given integer `n` into a string format. We'll be iterating through the string in reverse order (from last to first character) to insert dots at the thousands positions.

We keep a count initialized to 0. During the iteration, we increment the count until it's divisible by 3 (meaning we reached a thousands position). At this point, we insert the dot in the string at position `i`. The insertion process is slightly different for each programming language, but the overall idea is the same.

After the iteration is complete, we return the modified string with dots as thousands separators. This solution works for each of the mentioned programming languages using similar logic and some language-specific syntax adjustments.

## A solution in Javascript

```javascript
function thousandSeparator(n) {
    let result = String(n);
    let count = 0;
    for (let i = result.length - 1; i > 0; --i) {
        count++;
        if (count % 3 === 0) {
            result = result.slice(0, i) + '.' + result.slice(i);
        }
    }
    return result;
}
```
The algorithm first converts the given integer `n` into a string format. We'll be iterating through the string in reverse order (from last to first character) to insert dots at the thousands positions.

We keep a count initialized to 0. During the iteration, we increment the count until it's divisible by 3 (meaning we reached a thousands position). At this point, we insert the dot in the string at position `i`. The insertion process is slightly different for each programming language, but the overall idea is the same.

After the iteration is complete, we return the modified string with dots as thousands separators. This solution works for each of the mentioned programming languages using similar logic and some language-specific syntax adjustments.


# Check If Two String Arrays are Equivalent

- slug: check-if-two-string-arrays-are-equivalent
- difficulty: Easy

Given two string arrays `word1` and `word2`, return `true` _if the two arrays **represent** the same string, and_ `false` _otherwise._

A string is **represented** by an array if the array elements concatenated **in order** forms the string.

**Example 1:**

**Input:** word1 = \[ "ab ",  "c "\], word2 = \[ "a ",  "bc "\]
**Output:** true
**Explanation:**
word1 represents string  "ab " +  "c " ->  "abc "
word2 represents string  "a " +  "bc " ->  "abc "
The strings are the same, so return true.

**Example 2:**

**Input:** word1 = \[ "a ",  "cb "\], word2 = \[ "ab ",  "c "\]
**Output:** false

**Example 3:**

**Input:** word1  = \[ "abc ",  "d ",  "defg "\], word2 = \[ "abcddefg "\]
**Output:** true

**Constraints:**

*   `1 <= word1.length, word2.length <= 103`
*   `1 <= word1[i].length, word2[i].length <= 103`
*   `1 <= sum(word1[i].length), sum(word2[i].length) <= 103`
*   `word1[i]` and `word2[i]` consist of lowercase letters.

## A solution in Java

```java
public int minNumOperations(int[] nums) {
    int result = 0;
    int[] highestBit = new int[32];
    for (int num : nums) {
        for (int j = 0; j < 32; j++) {
            if ((num & (1 << j)) != 0) {
                highestBit[j]++;
            }
        }
    }
    for (int count : highestBit) {
        result = Math.max(result, count);
    }
    return result + 31;
}
```
The algorithm starts by initializing a result variable to 0 and an array called highestBit of size 32 with all elements set to 0. Then, for each number in the input nums array, we perform bitwise operations to check if a specific bit is turned on (1). If so, we increment the corresponding element in the highestBit array by 1. After processing all the numbers in the input array, we loop through the highestBit array and update the result variable to the maximum value found plus 31. Finally, we return the result. The algorithm tries to find the highest bit set in any of the input numbers to determine the minimum number of calls needed to make nums from arr.

## A solution in C++

```cpp
int minNumOperations(vector<int>& nums) {
    int result = 0;
    int highestBit[32] = {0};
    for (int num : nums) {
        for (int j = 0; j < 32; ++j) {
            if (num & (1 << j)) {
                highestBit[j]++;
            }
        }
    }
    for (int count : highestBit) {
        result = max(result, count);
    }
    return result + 31;
}
```
The algorithm starts by initializing a result variable to 0 and an array called highestBit of size 32 with all elements set to 0. Then, for each number in the input nums array, we perform bitwise operations to check if a specific bit is turned on (1). If so, we increment the corresponding element in the highestBit array by 1. After processing all the numbers in the input array, we loop through the highestBit array and update the result variable to the maximum value found plus 31. Finally, we return the result. The algorithm tries to find the highest bit set in any of the input numbers to determine the minimum number of calls needed to make nums from arr.

## A solution in Python

```python
def min_num_operations(nums):
    result = 0
    highest_bit = [0] * 32
    for num in nums:
        for j in range(32):
            if num & (1 << j):
                highest_bit[j] += 1
    for count in highest_bit:
        result = max(result, count)
    return result + 31
```
The algorithm starts by initializing a result variable to 0 and an array called highestBit of size 32 with all elements set to 0. Then, for each number in the input nums array, we perform bitwise operations to check if a specific bit is turned on (1). If so, we increment the corresponding element in the highestBit array by 1. After processing all the numbers in the input array, we loop through the highestBit array and update the result variable to the maximum value found plus 31. Finally, we return the result. The algorithm tries to find the highest bit set in any of the input numbers to determine the minimum number of calls needed to make nums from arr.

## A solution in Javascript

```javascript
function minNumOperations(nums) {
    let result = 0;
    let highestBit = new Array(32).fill(0);
    for (let num of nums) {
        for (let j = 0; j < 32; ++j) {
            if (num & (1 << j)) {
                highestBit[j]++;
            }
        }
    }
    for (let count of highestBit) {
        result = Math.max(result, count);
    }
    return result + 31;
}
```
The algorithm starts by initializing a result variable to 0 and an array called highestBit of size 32 with all elements set to 0. Then, for each number in the input nums array, we perform bitwise operations to check if a specific bit is turned on (1). If so, we increment the corresponding element in the highestBit array by 1. After processing all the numbers in the input array, we loop through the highestBit array and update the result variable to the maximum value found plus 31. Finally, we return the result. The algorithm tries to find the highest bit set in any of the input numbers to determine the minimum number of calls needed to make nums from arr.


# Smallest String With A Given Numeric Value

- slug: smallest-string-with-a-given-numeric-value
- difficulty: Medium

The **numeric value** of a **lowercase character** is defined as its position `(1-indexed)` in the alphabet, so the numeric value of `a` is `1`, the numeric value of `b` is `2`, the numeric value of `c` is `3`, and so on.

The **numeric value** of a **string** consisting of lowercase characters is defined as the sum of its characters' numeric values. For example, the numeric value of the string `"abe "` is equal to `1 + 2 + 5 = 8`.

You are given two integers `n` and `k`. Return _the **lexicographically smallest string** with **length** equal to `n` and **numeric value** equal to `k`._

Note that a string `x` is lexicographically smaller than string `y` if `x` comes before `y` in dictionary order, that is, either `x` is a prefix of `y`, or if `i` is the first position such that `x[i] != y[i]`, then `x[i]` comes before `y[i]` in alphabetic order.

**Example 1:**

**Input:** n = 3, k = 27
**Output:**  "aay "
**Explanation:** The numeric value of the string is 1 + 1 + 25 = 27, and it is the smallest string with such a value and length equal to 3.

**Example 2:**

**Input:** n = 5, k = 73
**Output:**  "aaszz "

**Constraints:**

*   `1 <= n <= 105`
*   `n <= k <= 26 * n`

## A solution in Java

```java
public boolean containsCycle(char[][] grid) {
    for (int i = 0; i < grid.length; i++) {
        for (int j = 0; j < grid[0].length; j++) {
            if (dfs(grid, i, j, i, j, 0)) return true;
        }
    }
    return false;
}

private boolean dfs(char[][] grid, int x, int y, int startX, int startY, int depth) {
    if (x < 0 || y < 0 || x >= grid.length || y >= grid[0].length || grid[x][y] != grid[startX][startY])
        return false;

    grid[x][y] = '*';

    int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    for (int[] direction : directions) {
        int newX = x + direction[0];
        int newY = y + direction[1];

        if (newX == startX && newY == startY && depth >= 4) return true;

        if (dfs(grid, newX, newY, startX, startY, depth + 1)) return true;
    }

    grid[x][y] = grid[startX][startY];

    return false;
}
```
The algorithm uses a depth-first search (DFS) approach to find cycles in the given 2D grid. For each cell in the grid, we perform a DFS search on its adjacent cells with the same value, making sure not to revisit the cell we just came from. Since we are looking for cycles of length 4 or more, we keep track of the depth of the search. If we find a cycle of 4 or more cells, we return true. If no cycle is found, return false.

The main function `containsCycle` loops through every cell of the grid, and for each cell, it calls the DFS function. If the DFS function returns true at any point, we immediately return true from the main function, meaning a cycle has been found. Otherwise, we return false, indicating that there's no cycle in the given grid.

## A solution in C++

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

bool dfs(vector<vector<char>>& grid, int x, int y, int startX, int startY, int depth) {
    if (x < 0 || y < 0 || x >= grid.size() || y >= grid[0].size() || grid[x][y] != grid[startX][startY])
        return false;

    grid[x][y] = '*';

    static vector<vector<int>> directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    for (auto& direction : directions) {
        int newX = x + direction[0];
        int newY = y + direction[1];

        if (newX == startX && newY == startY && depth >= 4) return true;

        if (dfs(grid, newX, newY, startX, startY, depth + 1)) return true;
    }

    grid[x][y] = grid[startX][startY];

    return false;
}

bool containsCycle(vector<vector<char>>& grid) {
    for (int i = 0; i < grid.size(); ++i) {
        for (int j = 0; j < grid[0].size(); ++j) {
            if (dfs(grid, i, j, i, j, 0)) return true;
        }
    }
    return false;
}
```
The algorithm uses a depth-first search (DFS) approach to find cycles in the given 2D grid. For each cell in the grid, we perform a DFS search on its adjacent cells with the same value, making sure not to revisit the cell we just came from. Since we are looking for cycles of length 4 or more, we keep track of the depth of the search. If we find a cycle of 4 or more cells, we return true. If no cycle is found, return false.

The main function `containsCycle` loops through every cell of the grid, and for each cell, it calls the DFS function. If the DFS function returns true at any point, we immediately return true from the main function, meaning a cycle has been found. Otherwise, we return false, indicating that there's no cycle in the given grid.

## A solution in Python

```python
def contains_cycle(grid):
    def dfs(x, y, start_x, start_y, depth):
        if x < 0 or y < 0 or x >= len(grid) or y >= len(grid[0]) or grid[x][y] != grid[start_x][start_y]:
            return False

        grid[x][y] = '*'

        directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
        for dx, dy in directions:
            new_x, new_y = x + dx, y + dy

            if new_x == start_x and new_y == start_y and depth >= 4:
                return True

            if dfs(new_x, new_y, start_x, start_y, depth + 1):
                return True

        grid[x][y] = grid[start_x][start_y]

        return False

    for i in range(len(grid)):
        for j in range(len(grid[0])):
            if dfs(i, j, i, j, 0):
                return True

    return False
```
The algorithm uses a depth-first search (DFS) approach to find cycles in the given 2D grid. For each cell in the grid, we perform a DFS search on its adjacent cells with the same value, making sure not to revisit the cell we just came from. Since we are looking for cycles of length 4 or more, we keep track of the depth of the search. If we find a cycle of 4 or more cells, we return true. If no cycle is found, return false.

The main function `containsCycle` loops through every cell of the grid, and for each cell, it calls the DFS function. If the DFS function returns true at any point, we immediately return true from the main function, meaning a cycle has been found. Otherwise, we return false, indicating that there's no cycle in the given grid.

## A solution in Javascript

```javascript
function containsCycle(grid) {
    function dfs(x, y, startX, startY, depth) {
        if (x < 0 || y < 0 || x >= grid.length || y >= grid[0].length || grid[x][y] !== grid[startX][startY])
            return false;

        grid[x][y] = '*';

        const directions = [[0, 1], [0, -1], [1, 0], [-1, 0]];
        for (const [dx, dy] of directions) {
            const newX = x + dx;
            const newY = y + dy;

            if (newX === startX && newY === startY && depth >= 4) return true;

            if (dfs(newX, newY, startX, startY, depth + 1)) return true;
        }

        grid[x][y] = grid[startX][startY];

        return false;
    }

    for (let i = 0; i < grid.length; ++i) {
        for (let j = 0; j < grid[0].length; ++j) {
            if (dfs(i, j, i, j, 0)) return true;
        }
    }
    return false;
}
```
The algorithm uses a depth-first search (DFS) approach to find cycles in the given 2D grid. For each cell in the grid, we perform a DFS search on its adjacent cells with the same value, making sure not to revisit the cell we just came from. Since we are looking for cycles of length 4 or more, we keep track of the depth of the search. If we find a cycle of 4 or more cells, we return true. If no cycle is found, return false.

The main function `containsCycle` loops through every cell of the grid, and for each cell, it calls the DFS function. If the DFS function returns true at any point, we immediately return true from the main function, meaning a cycle has been found. Otherwise, we return false, indicating that there's no cycle in the given grid.


# Ways to Make a Fair Array

- slug: ways-to-make-a-fair-array
- difficulty: Medium

You are given an integer array `nums`. You can choose **exactly one** index (**0-indexed**) and remove the element. Notice that the index of the elements may change after the removal.

For example, if `nums = [6,1,7,4,1]`:

*   Choosing to remove index `1` results in `nums = [6,7,4,1]`.
*   Choosing to remove index `2` results in `nums = [6,1,4,1]`.
*   Choosing to remove index `4` results in `nums = [6,1,7,4]`.

An array is **fair** if the sum of the odd-indexed values equals the sum of the even-indexed values.

Return the _**number** of indices that you could choose such that after the removal,_ `nums` _is **fair**._

**Example 1:**

**Input:** nums = \[2,1,6,4\]
**Output:** 1
**Explanation:**
Remove index 0: \[1,6,4\] -> Even sum: 1 + 4 = 5. Odd sum: 6. Not fair.
Remove index 1: \[2,6,4\] -> Even sum: 2 + 4 = 6. Odd sum: 6. Fair.
Remove index 2: \[2,1,4\] -> Even sum: 2 + 4 = 6. Odd sum: 1. Not fair.
Remove index 3: \[2,1,6\] -> Even sum: 2 + 6 = 8. Odd sum: 1. Not fair.
There is 1 index that you can remove to make nums fair.

**Example 2:**

**Input:** nums = \[1,1,1\]
**Output:** 3
**Explanation:** You can remove any index and the remaining array is fair.

**Example 3:**

**Input:** nums = \[1,2,3\]
**Output:** 0
**Explanation:** You cannot make a fair array after removing any index.

**Constraints:**

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

## A solution in Java

```java
public int numberOfFairs(int[] nums) {
    int even_sum = 0, odd_sum = 0, l_even = 0, l_odd = 0, count = 0;
    for (int i = 0; i < nums.length; ++i) {
        if (i % 2 == 0) even_sum += nums[i];
        else odd_sum += nums[i];
    }
    for (int i = 0; i < nums.length; ++i) {
        if (i % 2 == 0) {
            even_sum -= nums[i];
            if (l_even + odd_sum == l_odd + even_sum) ++count;
            l_even += nums[i];
        } else {
            odd_sum -= nums[i];
            if (l_even + odd_sum == l_odd + even_sum) ++count;
            l_odd += nums[i];
        }
    }
    return count;
}
```
1. First, find the sum of values at even indices and odd indices and store them in `even_sum` and `odd_sum` respectively.
2. Iterate through the array with index `i`:
   - If `i` is even, subtract the value at `i` from `even_sum`, check if `l_even` (sum of even values to the left of `i`) plus `odd_sum` equals `l_odd` (sum of odd values to the left of `i`) plus `even_sum`, and if yes, increment `count`. Then add the value at `i` to `l_even`.
   - If `i` is odd, subtract the value at `i` from `odd_sum`, check if `l_even` plus `odd_sum` equals `l_odd` plus `even_sum`, and if yes, increment `count`. Then add the value at `i` to `l_odd`.
3. Return `count` as the number of indices you could choose such that after the removal, nums is fair.

## A solution in C++

```cpp
int numberOfFairs(int* nums, int numsSize) {
    int even_sum = 0, odd_sum = 0, l_even = 0, l_odd = 0, count = 0;
    for (int i = 0; i < numsSize; ++i) {
        if (i % 2 == 0) even_sum += nums[i];
        else odd_sum += nums[i];
    }
    for (int i = 0; i < numsSize; ++i) {
        if (i % 2 == 0) {
            even_sum -= nums[i];
            if (l_even + odd_sum == l_odd + even_sum) ++count;
            l_even += nums[i];
        } else {
            odd_sum -= nums[i];
            if (l_even + odd_sum == l_odd + even_sum) ++count;
            l_odd += nums[i];
        }
    }
    return count;
}
```
1. First, find the sum of values at even indices and odd indices and store them in `even_sum` and `odd_sum` respectively.
2. Iterate through the array with index `i`:
   - If `i` is even, subtract the value at `i` from `even_sum`, check if `l_even` (sum of even values to the left of `i`) plus `odd_sum` equals `l_odd` (sum of odd values to the left of `i`) plus `even_sum`, and if yes, increment `count`. Then add the value at `i` to `l_even`.
   - If `i` is odd, subtract the value at `i` from `odd_sum`, check if `l_even` plus `odd_sum` equals `l_odd` plus `even_sum`, and if yes, increment `count`. Then add the value at `i` to `l_odd`.
3. Return `count` as the number of indices you could choose such that after the removal, nums is fair.

## A solution in Python

```python
def numberOfFairs(nums):
    even_sum = sum(nums[0::2])
    odd_sum = sum(nums[1::2])
    l_even = l_odd = count = 0
    for i, num in enumerate(nums):
        if i % 2 == 0:
            even_sum -= num
            if l_even + odd_sum == l_odd + even_sum:
                count += 1
            l_even += num
        else:
            odd_sum -= num
            if l_even + odd_sum == l_odd + even_sum:
                count += 1
            l_odd += num
    return count
```
1. First, find the sum of values at even indices and odd indices and store them in `even_sum` and `odd_sum` respectively.
2. Iterate through the array with index `i`:
   - If `i` is even, subtract the value at `i` from `even_sum`, check if `l_even` (sum of even values to the left of `i`) plus `odd_sum` equals `l_odd` (sum of odd values to the left of `i`) plus `even_sum`, and if yes, increment `count`. Then add the value at `i` to `l_even`.
   - If `i` is odd, subtract the value at `i` from `odd_sum`, check if `l_even` plus `odd_sum` equals `l_odd` plus `even_sum`, and if yes, increment `count`. Then add the value at `i` to `l_odd`.
3. Return `count` as the number of indices you could choose such that after the removal, nums is fair.

## A solution in Javascript

```javascript
function numberOfFairs(nums) {
    let even_sum = 0, odd_sum = 0, l_even = 0, l_odd = 0, count = 0;
    for (let i = 0; i < nums.length; ++i) {
        if (i % 2 === 0) even_sum += nums[i];
        else odd_sum += nums[i];
    }
    for (let i = 0; i < nums.length; ++i) {
        if (i % 2 === 0) {
            even_sum -= nums[i];
            if (l_even + odd_sum === l_odd + even_sum) ++count;
            l_even += nums[i];
        } else {
            odd_sum -= nums[i];
            if (l_even + odd_sum === l_odd + even_sum) ++count;
            l_odd += nums[i];
        }
    }
    return count;
}
```
1. First, find the sum of values at even indices and odd indices and store them in `even_sum` and `odd_sum` respectively.
2. Iterate through the array with index `i`:
   - If `i` is even, subtract the value at `i` from `even_sum`, check if `l_even` (sum of even values to the left of `i`) plus `odd_sum` equals `l_odd` (sum of odd values to the left of `i`) plus `even_sum`, and if yes, increment `count`. Then add the value at `i` to `l_even`.
   - If `i` is odd, subtract the value at `i` from `odd_sum`, check if `l_even` plus `odd_sum` equals `l_odd` plus `even_sum`, and if yes, increment `count`. Then add the value at `i` to `l_odd`.
3. Return `count` as the number of indices you could choose such that after the removal, nums is fair.


# Minimum Initial Energy to Finish Tasks

- slug: minimum-initial-energy-to-finish-tasks
- difficulty: Hard

You are given an array `tasks` where `tasks[i] = [actuali, minimumi]`:

*   `actuali` is the actual amount of energy you **spend to finish** the `ith` task.
*   `minimumi` is the minimum amount of energy you **require to begin** the `ith` task.

For example, if the task is `[10, 12]` and your current energy is `11`, you cannot start this task. However, if your current energy is `13`, you can complete this task, and your energy will be `3` after finishing it.

You can finish the tasks in **any order** you like.

Return _the **minimum** initial amount of energy you will need_ _to finish all the tasks_.

**Example 1:**

**Input:** tasks = \[\[1,2\],\[2,4\],\[4,8\]\]
**Output:** 8
**Explanation:**
Starting with 8 energy, we finish the tasks in the following order:
    - 3rd task. Now energy = 8 - 4 = 4.
    - 2nd task. Now energy = 4 - 2 = 2.
    - 1st task. Now energy = 2 - 1 = 1.
Notice that even though we have leftover energy, starting with 7 energy does not work because we cannot do the 3rd task.

**Example 2:**

**Input:** tasks = \[\[1,3\],\[2,4\],\[10,11\],\[10,12\],\[8,9\]\]
**Output:** 32
**Explanation:**
Starting with 32 energy, we finish the tasks in the following order:
    - 1st task. Now energy = 32 - 1 = 31.
    - 2nd task. Now energy = 31 - 2 = 29.
    - 3rd task. Now energy = 29 - 10 = 19.
    - 4th task. Now energy = 19 - 10 = 9.
    - 5th task. Now energy = 9 - 8 = 1.

**Example 3:**

**Input:** tasks = \[\[1,7\],\[2,8\],\[3,9\],\[4,10\],\[5,11\],\[6,12\]\]
**Output:** 27
**Explanation:**
Starting with 27 energy, we finish the tasks in the following order:
    - 5th task. Now energy = 27 - 5 = 22.
    - 2nd task. Now energy = 22 - 2 = 20.
    - 3rd task. Now energy = 20 - 3 = 17.
    - 1st task. Now energy = 17 - 1 = 16.
    - 4th task. Now energy = 16 - 4 = 12.
    - 6th task. Now energy = 12 - 6 = 6.

**Constraints:**

*   `1 <= tasks.length <= 105`
*   `1 <= actuali <= minimumi <= 104`

## A solution in Java

```java
public int minimumEffort(int[][] tasks) {
    Arrays.sort(tasks, (a, b) -> (b[1] - b[0]) - (a[1] - a[0]));
    int ans = 0, sum = 0;
    for (int[] task : tasks) {
        ans = Math.max(ans, sum + task[1]);
        sum += task[0];
    }
    return ans;
}
```
The main idea of this algorithm is to sort the tasks in descending order based on the difference between their `minimum` and `actual` energy requirements. By sorting in this order, we can ensure that we first finish the tasks which require more minimum energy, and the remaining tasks require less minimum energy to start.

After sorting the tasks in the desired order, we iterate through the tasks to find the minimum initial energy required.

1. Set the initial values of `ans` and `sum_energy` to 0.
2. For each task in the sorted tasks list, calculate the maximum value between the current `ans` and the sum of `sum_energy` and the `minimum` energy required for the current task. Update the `ans` variable with this maximum value.
3. Add the `actual` energy spent on the current task to the `sum_energy`.
4. After iterating through all the tasks, the `ans` variable will store the minimum initial amount of energy required to finish all the tasks.

## A solution in C++

```cpp
int minimumEffort(vector<vector<int>>& tasks) {
    sort(tasks.begin(), tasks.end(), [](vector<int>& a, vector<int>& b) {
        return a[1] - a[0] > b[1] - b[0];
    });
    int ans = 0, sum = 0;
    for (auto& task : tasks) {
        ans = max(ans, sum + task[1]);
        sum += task[0];
    }
    return ans;
}
```
The main idea of this algorithm is to sort the tasks in descending order based on the difference between their `minimum` and `actual` energy requirements. By sorting in this order, we can ensure that we first finish the tasks which require more minimum energy, and the remaining tasks require less minimum energy to start.

After sorting the tasks in the desired order, we iterate through the tasks to find the minimum initial energy required.

1. Set the initial values of `ans` and `sum_energy` to 0.
2. For each task in the sorted tasks list, calculate the maximum value between the current `ans` and the sum of `sum_energy` and the `minimum` energy required for the current task. Update the `ans` variable with this maximum value.
3. Add the `actual` energy spent on the current task to the `sum_energy`.
4. After iterating through all the tasks, the `ans` variable will store the minimum initial amount of energy required to finish all the tasks.

## A solution in Python

```python
def minimumEffort(tasks):
    tasks.sort(key=lambda task: task[1] - task[0], reverse=True)
    ans, sum_energy = 0, 0
    for task in tasks:
        ans = max(ans, sum_energy + task[1])
        sum_energy += task[0]
    return ans
```
The main idea of this algorithm is to sort the tasks in descending order based on the difference between their `minimum` and `actual` energy requirements. By sorting in this order, we can ensure that we first finish the tasks which require more minimum energy, and the remaining tasks require less minimum energy to start.

After sorting the tasks in the desired order, we iterate through the tasks to find the minimum initial energy required.

1. Set the initial values of `ans` and `sum_energy` to 0.
2. For each task in the sorted tasks list, calculate the maximum value between the current `ans` and the sum of `sum_energy` and the `minimum` energy required for the current task. Update the `ans` variable with this maximum value.
3. Add the `actual` energy spent on the current task to the `sum_energy`.
4. After iterating through all the tasks, the `ans` variable will store the minimum initial amount of energy required to finish all the tasks.

## A solution in Javascript

```javascript
function minimumEffort(tasks) {
    tasks.sort((a, b) => (b[1] - b[0]) - (a[1] - a[0]));
    let ans = 0, sum = 0;
    for (const task of tasks) {
        ans = Math.max(ans, sum + task[1]);
        sum += task[0];
    }
    return ans;
}
```
The main idea of this algorithm is to sort the tasks in descending order based on the difference between their `minimum` and `actual` energy requirements. By sorting in this order, we can ensure that we first finish the tasks which require more minimum energy, and the remaining tasks require less minimum energy to start.

After sorting the tasks in the desired order, we iterate through the tasks to find the minimum initial energy required.

1. Set the initial values of `ans` and `sum_energy` to 0.
2. For each task in the sorted tasks list, calculate the maximum value between the current `ans` and the sum of `sum_energy` and the `minimum` energy required for the current task. Update the `ans` variable with this maximum value.
3. Add the `actual` energy spent on the current task to the `sum_energy`.
4. After iterating through all the tasks, the `ans` variable will store the minimum initial amount of energy required to finish all the tasks.


# Change the Root of a Binary Tree

- slug: change-the-root-of-a-binary-tree
- difficulty: Medium

Given the `root` of a binary tree and a `leaf` node, reroot the tree so that the `leaf` is the new root.

You can reroot the tree with the following steps for each node `cur` on the path **starting from the** `leaf` up to the `root` **excluding the root**:

1.  If `cur` has a left child, then that child becomes `cur`'s right child.
2.  `cur`'s original parent becomes `cur`'s left child. Note that in this process the original parent's pointer to `cur` becomes `null`, making it have at most one child.

Return _the new root_ _of the rerooted tree._

**Note:** Ensure that your solution sets the `Node.parent` pointers correctly after rerooting or you will receive "Wrong Answer ".

**Example 1:**

**Input:** root = \[3,5,1,6,2,0,8,null,null,7,4\], leaf = 7
**Output:** \[7,2,null,5,4,3,6,null,null,null,1,null,null,0,8\]

**Example 2:**

**Input:** root = \[3,5,1,6,2,0,8,null,null,7,4\], leaf = 0
**Output:** \[0,1,null,3,8,5,null,null,null,6,2,null,null,7,4\]

**Constraints:**

*   The number of nodes in the tree is in the range `[2, 100]`.
*   `-109 <= Node.val <= 109`
*   All `Node.val` are **unique**.
*   `leaf` exist in the tree.

## A solution in Java

```java
public String makeGood(String s) {
    StringBuilder result = new StringBuilder();
    for (char c : s.toCharArray()) {
        int length = result.length();
        if (length > 0 && Math.abs(result.charAt(length - 1) - c) == 32) {
            result.deleteCharAt(length - 1);
        } else {
            result.append(c);
        }
    }
    return result.toString();
}
```
The algorithm iterates through the input string. For each character, it checks whether the last character in the result string has the same letter but different case (i.e., the ASCII distance between the two characters is 32). If so, it removes the last character from the result string. Otherwise, it appends the current character to the result string. The final result is then returned.

## A solution in C++

```cpp
#include <string>

std::string makeGood(std::string s) {
    std::string result;
    for (char c : s) {
        if (!result.empty() && abs(result.back() - c) == 32) {
            result.pop_back();
        } else {
            result.push_back(c);
        }
    }
    return result;
}
```
The algorithm iterates through the input string. For each character, it checks whether the last character in the result string has the same letter but different case (i.e., the ASCII distance between the two characters is 32). If so, it removes the last character from the result string. Otherwise, it appends the current character to the result string. The final result is then returned.

## A solution in Python

```python
def make_good(s: str) -> str:
    result = []
    for c in s:
        if result and abs(ord(result[-1]) - ord(c)) == 32:
            result.pop()
        else:
            result.append(c)
    return "".join(result)
```
The algorithm iterates through the input string. For each character, it checks whether the last character in the result string has the same letter but different case (i.e., the ASCII distance between the two characters is 32). If so, it removes the last character from the result string. Otherwise, it appends the current character to the result string. The final result is then returned.

## A solution in Javascript

```javascript
function makeGood(s) {
    let result = [];
    for (let c of s) {
        if (result.length > 0 && Math.abs(result[result.length - 1].charCodeAt(0) - c.charCodeAt(0)) === 32) {
            result.pop();
        } else {
            result.push(c);
        }
    }
    return result.join("");
}
```
The algorithm iterates through the input string. For each character, it checks whether the last character in the result string has the same letter but different case (i.e., the ASCII distance between the two characters is 32). If so, it removes the last character from the result string. Otherwise, it appends the current character to the result string. The final result is then returned.


# Maximum Repeating Substring

- slug: maximum-repeating-substring
- difficulty: Easy

For a string `sequence`, a string `word` is **`k`\-repeating** if `word` concatenated `k` times is a substring of `sequence`. The `word`'s **maximum `k`\-repeating value** is the highest value `k` where `word` is `k`\-repeating in `sequence`. If `word` is not a substring of `sequence`, `word`'s maximum `k`\-repeating value is `0`.

Given strings `sequence` and `word`, return _the **maximum `k`\-repeating value** of `word` in `sequence`_.

**Example 1:**

**Input:** sequence =  "ababc ", word =  "ab "
**Output:** 2
**Explanation: ** "abab " is a substring in  "ababc ".

**Example 2:**

**Input:** sequence =  "ababc ", word =  "ba "
**Output:** 1
**Explanation: ** "ba " is a substring in  "ababc ".  "baba " is not a substring in  "ababc ".

**Example 3:**

**Input:** sequence =  "ababc ", word =  "ac "
**Output:** 0
**Explanation: ** "ac " is not a substring in  "ababc ".

**Constraints:**

*   `1 <= sequence.length <= 100`
*   `1 <= word.length <= 100`
*   `sequence` and `word` contains only lowercase English letters.

## A solution in Java

```java
int longestAwesomeSubstring(String s) {
    int n = s.length();
    int maxLen = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j <= n; ++j) {
            String substr = s.substring(i, j);
            if (isAwesome(substr)) {
                maxLen = Math.max(maxLen, j - i);
            }
        }
    }
    return maxLen;
}

boolean isAwesome(String s) {
    int odd_count = 0;
    int[] freq = new int[26];
    for (char c : s.toCharArray()) {
        freq[c - 'a']++;
    }
    for (int i = 0; i < 26; i++) {
        if (freq[i] % 2 == 1) {
            odd_count++;
        }
    }
    return (odd_count <= 1);
}
```
The algorithm starts by checking all possible substrings of the given string s. For each substring, it checks whether it's an awesome substring or not by calling the isAwesome function.
The isAwesome function calculates the frequency of each character in the string and counts the number of characters that have an odd frequency. If there are more than one characters with odd frequency, it returns false, otherwise, it returns true.
Finally, the algorithm returns the length of the longest awesome substring found.

## A solution in C++

```cpp
int longestAwesomeSubstring(std::string s) {
    int n = s.length();
    int maxLen = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j <= n; ++j) {
            std::string substr = s.substr(i, j - i);
            if (isAwesome(substr)) {
                maxLen = std::max(maxLen, j - i);
            }
        }
    }
    return maxLen;
}

bool isAwesome(std::string s) {
    int odd_count = 0;
    int freq[26] = {0};
    for (char c : s) {
        freq[c - 'a']++;
    }
    for (int i = 0; i < 26; i++) {
        if (freq[i] % 2 == 1) {
            odd_count++;
        }
    }
    return (odd_count <= 1);
}
```
The algorithm starts by checking all possible substrings of the given string s. For each substring, it checks whether it's an awesome substring or not by calling the isAwesome function.
The isAwesome function calculates the frequency of each character in the string and counts the number of characters that have an odd frequency. If there are more than one characters with odd frequency, it returns false, otherwise, it returns true.
Finally, the algorithm returns the length of the longest awesome substring found.

## A solution in Python

```python
def longestAwesomeSubstring(s):
    n = len(s)
    maxLen = 0
    for i in range(n):
        for j in range(i + 1, n + 1):
            substr = s[i:j]
            if isAwesome(substr):
                maxLen = max(maxLen, j - i)
    return maxLen

def isAwesome(s):
    odd_count = 0
    freq = [0] * 26
    for c in s:
        freq[ord(c) - ord('a')] += 1
    for i in range(26):
        if freq[i] % 2 == 1:
            odd_count += 1
    return odd_count <= 1
```
The algorithm starts by checking all possible substrings of the given string s. For each substring, it checks whether it's an awesome substring or not by calling the isAwesome function.
The isAwesome function calculates the frequency of each character in the string and counts the number of characters that have an odd frequency. If there are more than one characters with odd frequency, it returns false, otherwise, it returns true.
Finally, the algorithm returns the length of the longest awesome substring found.

## A solution in Javascript

```javascript
function longestAwesomeSubstring(s) {
    let n = s.length;
    let maxLen = 0;
    for (let i = 0; i < n; ++i) {
        for (let j = i + 1; j <= n; ++j) {
            let substr = s.substring(i, j);
            if (isAwesome(substr)) {
                maxLen = Math.max(maxLen, j - i);
            }
        }
    }
    return maxLen;
}

function isAwesome(s) {
    let odd_count = 0;
    let freq = new Array(26).fill(0);
    for (let c of s) {
        freq[c.charCodeAt(0) - 'a'.charCodeAt(0)]++;
    }
    for (let i = 0; i < 26; i++) {
        if (freq[i] % 2 == 1) {
            odd_count++;
        }
    }
    return odd_count <= 1;
}
```
The algorithm starts by checking all possible substrings of the given string s. For each substring, it checks whether it's an awesome substring or not by calling the isAwesome function.
The isAwesome function calculates the frequency of each character in the string and counts the number of characters that have an odd frequency. If there are more than one characters with odd frequency, it returns false, otherwise, it returns true.
Finally, the algorithm returns the length of the longest awesome substring found.


# Merge In Between Linked Lists

- slug: merge-in-between-linked-lists
- difficulty: Medium

You are given two linked lists: `list1` and `list2` of sizes `n` and `m` respectively.

Remove `list1`'s nodes from the `ath` node to the `bth` node, and put `list2` in their place.

The blue edges and nodes in the following figure indicate the result:

_Build the result list and return its head._

**Example 1:**

**Input:** list1 = \[0,1,2,3,4,5\], a = 3, b = 4, list2 = \[1000000,1000001,1000002\]
**Output:** \[0,1,2,1000000,1000001,1000002,5\]
**Explanation:** We remove the nodes 3 and 4 and put the entire list2 in their place. The blue edges and nodes in the above figure indicate the result.

**Example 2:**

**Input:** list1 = \[0,1,2,3,4,5,6\], a = 2, b = 5, list2 = \[1000000,1000001,1000002,1000003,1000004\]
**Output:** \[0,1,1000000,1000001,1000002,1000003,1000004,6\]
**Explanation:** The blue edges and nodes in the above figure indicate the result.

**Constraints:**

*   `3 <= list1.length <= 104`
*   `1 <= a <= b < list1.length - 1`
*   `1 <= list2.length <= 104`

## A solution in Java

```java
import java.util.Arrays;

public int minCost(int n, int[] cuts) {
    int[] new_cuts = Arrays.copyOf(cuts, cuts.length + 2);
    new_cuts[cuts.length] = 0;
    new_cuts[cuts.length + 1] = n;
    Arrays.sort(new_cuts);
    int size = new_cuts.length;

    int[][] dp = new int[size][size];

    for (int len = 2; len < size; ++len) {
        for (int i = 0; i < size - len; ++i) {
            int j = i + len;
            dp[i][j] = Integer.MAX_VALUE;
            for (int k = i + 1; k < j; ++k) {
                dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j] + new_cuts[j] - new_cuts[i]);
            }
        }
    }

    return dp[0][size - 1];
}
```
The algorithm uses dynamic programming to find the minimum total cost of the cuts.

1. Initialize an array in each language to store the original cuts, 0, and n, and then sort the array.
2. Create a 2D dp array where dp[i][j] represents the minimum cost of cutting the stick between cuts[i] and cuts[j].
3. Iterate through possible lengths, starting from 2 to the length of the cuts array.
4. Iterate over the cut positions and calculate the minimum cost for each cut by trying all possible cutting orders. The cost of a cut is calculated as the sum of lengths of the left and right parts of the stick after the cut.
5. Return the value in dp[0][size - 1] as the minimum total cost of the cuts.

## A solution in C++

```cpp
#include <vector>
#include <algorithm>
#include <limits.h>

int minCost(int n, std::vector<int>& cuts) {
    cuts.push_back(0);
    cuts.push_back(n);
    std::sort(cuts.begin(), cuts.end());
    int size = cuts.size();
    std::vector<std::vector<int>> dp(size, std::vector<int>(size, 0));

    for (int len = 2; len < size; ++len) {
        for (int i = 0; i < size - len; ++i) {
            int j = i + len;
            dp[i][j] = INT_MAX;
            for (int k = i + 1; k < j; ++k) {
                dp[i][j] = std::min(dp[i][j], dp[i][k] + dp[k][j] + cuts[j] - cuts[i]);
            }
        }
    }

    return dp[0][size - 1];
}
```
The algorithm uses dynamic programming to find the minimum total cost of the cuts.

1. Initialize an array in each language to store the original cuts, 0, and n, and then sort the array.
2. Create a 2D dp array where dp[i][j] represents the minimum cost of cutting the stick between cuts[i] and cuts[j].
3. Iterate through possible lengths, starting from 2 to the length of the cuts array.
4. Iterate over the cut positions and calculate the minimum cost for each cut by trying all possible cutting orders. The cost of a cut is calculated as the sum of lengths of the left and right parts of the stick after the cut.
5. Return the value in dp[0][size - 1] as the minimum total cost of the cuts.

## A solution in Python

```python
def minCost(n, cuts):
    cuts = [0] + cuts + [n]
    cuts.sort()
    size = len(cuts)
    dp = [[0] * size for _ in range(size)]

    for len in range(2, size):
        for i in range(size - len):
            j = i + len
            dp[i][j] = float('inf')
            for k in range(i + 1, j):
                dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + cuts[j] - cuts[i])

    return dp[0][size - 1]
```
The algorithm uses dynamic programming to find the minimum total cost of the cuts.

1. Initialize an array in each language to store the original cuts, 0, and n, and then sort the array.
2. Create a 2D dp array where dp[i][j] represents the minimum cost of cutting the stick between cuts[i] and cuts[j].
3. Iterate through possible lengths, starting from 2 to the length of the cuts array.
4. Iterate over the cut positions and calculate the minimum cost for each cut by trying all possible cutting orders. The cost of a cut is calculated as the sum of lengths of the left and right parts of the stick after the cut.
5. Return the value in dp[0][size - 1] as the minimum total cost of the cuts.

## A solution in Javascript

```javascript
function minCost(n, cuts) {
    cuts.push(0);
    cuts.push(n);
    cuts.sort((a, b) => a - b);
    const size = cuts.length;
    const dp = Array.from({ length: size }, () => Array(size).fill(0));

    for (let len = 2; len < size; len++) {
        for (let i = 0; i < size - len; i++) {
            const j = i + len;
            dp[i][j] = Infinity;
            for (let k = i + 1; k < j; k++) {
                dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j] + cuts[j] - cuts[i]);
            }
        }
    }

    return dp[0][size - 1];
}
```
The algorithm uses dynamic programming to find the minimum total cost of the cuts.

1. Initialize an array in each language to store the original cuts, 0, and n, and then sort the array.
2. Create a 2D dp array where dp[i][j] represents the minimum cost of cutting the stick between cuts[i] and cuts[j].
3. Iterate through possible lengths, starting from 2 to the length of the cuts array.
4. Iterate over the cut positions and calculate the minimum cost for each cut by trying all possible cutting orders. The cost of a cut is calculated as the sum of lengths of the left and right parts of the stick after the cut.
5. Return the value in dp[0][size - 1] as the minimum total cost of the cuts.


# Design Front Middle Back Queue

- slug: design-front-middle-back-queue
- difficulty: Medium

Design a queue that supports `push` and `pop` operations in the front, middle, and back.

Implement the `FrontMiddleBack` class:

*   `FrontMiddleBack()` Initializes the queue.
*   `void pushFront(int val)` Adds `val` to the **front** of the queue.
*   `void pushMiddle(int val)` Adds `val` to the **middle** of the queue.
*   `void pushBack(int val)` Adds `val` to the **back** of the queue.
*   `int popFront()` Removes the **front** element of the queue and returns it. If the queue is empty, return `-1`.
*   `int popMiddle()` Removes the **middle** element of the queue and returns it. If the queue is empty, return `-1`.
*   `int popBack()` Removes the **back** element of the queue and returns it. If the queue is empty, return `-1`.

**Notice** that when there are **two** middle position choices, the operation is performed on the **frontmost** middle position choice. For example:

*   Pushing `6` into the middle of `[1, 2, 3, 4, 5]` results in `[1, 2, 6, 3, 4, 5]`.
*   Popping the middle from `[1, 2, 3, 4, 5, 6]` returns `3` and results in `[1, 2, 4, 5, 6]`.

**Example 1:**

**Input:**
\[ "FrontMiddleBackQueue ",  "pushFront ",  "pushBack ",  "pushMiddle ",  "pushMiddle ",  "popFront ",  "popMiddle ",  "popMiddle ",  "popBack ",  "popFront "\]
\[\[\], \[1\], \[2\], \[3\], \[4\], \[\], \[\], \[\], \[\], \[\]\]
**Output:**
\[null, null, null, null, null, 1, 3, 4, 2, -1\]

**Explanation:**
FrontMiddleBackQueue q = new FrontMiddleBackQueue();
q.pushFront(1);   // \[1\]
q.pushBack(2);    // \[1, 2\]
q.pushMiddle(3);  // \[1, 3, 2\]
q.pushMiddle(4);  // \[1, 4, 3, 2\]
q.popFront();     // return 1 -> \[4, 3, 2\]
q.popMiddle();    // return 3 -> \[4, 2\]
q.popMiddle();    // return 4 -> \[2\]
q.popBack();      // return 2 -> \[\]
q.popFront();     // return -1 -> \[\] (The queue is empty)

**Constraints:**

*   `1 <= val <= 109`
*   At most `1000` calls will be made to `pushFront`, `pushMiddle`, `pushBack`, `popFront`, `popMiddle`, and `popBack`.

## A solution in Java

```java
import java.util.LinkedList;

class FrontMiddleBackQueue {
    LinkedList<Integer> first, second;

    public FrontMiddleBackQueue() {
        first = new LinkedList<>();
        second = new LinkedList<>();
    }

    public void pushFront(int val) {
        first.addFirst(val);
        if (first.size() > second.size() + 1) {
            second.addFirst(first.removeLast());
        }
    }

    public void pushMiddle(int val) {
        if (first.size() < second.size()) {
            first.addLast(val);
        } else {
            second.addFirst(val);
        }
    }

    public void pushBack(int val) {
        second.addLast(val);
        if (second.size() > first.size()) {
            first.addLast(second.removeFirst());
        }
    }

    public int popFront() {
        if (first.isEmpty() && second.isEmpty()) return -1;
        int val = first.pollFirst();
        if (first.size() + 1 < second.size()) {
            first.addLast(second.pollFirst());
        }
        return val;
    }

    public int popMiddle() {
        if (first.isEmpty() && second.isEmpty()) return -1;
        int val;
        if (first.size() < second.size()) {
            val = second.pollFirst();
        } else {
            val = first.pollLast();
        }
        if (second.size() > first.size()) {
            first.addLast(second.pollFirst());
        }
        return val;
    }

    public int popBack() {
        if (first.isEmpty() && second.isEmpty()) return -1;
        int val = second.pollLast();
        if (first.size() > second.size() + 1) {
            second.addFirst(first.pollLast());
        }
        return val;
    }
}
```
The algorithm is based on using two deques or double-ended queues, `first` and `second`. At any given point, the middle element(s) of the queue can be found between the last element of `first` and the first element of `second`.

When a new element is pushed to the front, middle, or back, depending on the size relationship between the two deques, adjustments are made by transferring elements between `first` and `second`.

For operations that involve popping elements, we check if the queue is empty or not. If it is empty, we return -1. If not, we remove the appropriate element based on the size relationship between the two deques and adjust the deques accordingly, similar to the push operations.

## A solution in C++

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

class FrontMiddleBackQueue {
    deque<int> first, second;
public:
    FrontMiddleBackQueue() {

    }

    void pushFront(int val) {
        first.push_front(val);
        if (first.size() > second.size() + 1) {
            second.push_front(first.back());
            first.pop_back();
        }
    }

    void pushMiddle(int val) {
        if (first.size() < second.size()) {
            first.push_back(val);
        } else {
            second.push_front(val);
        }
    }

    void pushBack(int val) {
        second.push_back(val);
        if (second.size() > first.size()) {
            first.push_back(second.front());
            second.pop_front();
        }
    }

    int popFront() {
        if (first.empty() && second.empty()) return -1;
        int val = first.front();
        first.pop_front();
        if (first.size() + 1 < second.size()) {
            first.push_back(second.front());
            second.pop_front();
        }
        return val;
    }

    int popMiddle() {
        if (first.empty() && second.empty()) return -1;
        int val;
        if (first.size() < second.size()) {
            val = second.front();
            second.pop_front();
        } else {
            val = first.back();
            first.pop_back();
        }
        if (second.size() > first.size()) {
            first.push_back(second.front());
            second.pop_front();
        }
        return val;
    }

    int popBack() {
        if (first.empty() && second.empty()) return -1;
        int val = second.back();
        second.pop_back();
        if (first.size() > second.size() + 1) {
            second.push_front(first.back());
            first.pop_back();
        }
        return val;
    }
};
```
The algorithm is based on using two deques or double-ended queues, `first` and `second`. At any given point, the middle element(s) of the queue can be found between the last element of `first` and the first element of `second`.

When a new element is pushed to the front, middle, or back, depending on the size relationship between the two deques, adjustments are made by transferring elements between `first` and `second`.

For operations that involve popping elements, we check if the queue is empty or not. If it is empty, we return -1. If not, we remove the appropriate element based on the size relationship between the two deques and adjust the deques accordingly, similar to the push operations.

## A solution in Python

```python
from collections import deque

class FrontMiddleBackQueue:

    def __init__(self):
        self.first = deque()
        self.second = deque()

    def pushFront(self, val: int) -> None:
        self.first.appendleft(val)
        if len(self.first) > len(self.second) + 1:
            self.second.appendleft(self.first.pop())

    def pushMiddle(self, val: int) -> None:
        if len(self.first) < len(self.second):
            self.first.append(val)
        else:
            self.second.appendleft(val)

    def pushBack(self, val: int) -> None:
        self.second.append(val)
        if len(self.second) > len(self.first):
            self.first.append(self.second.popleft())

    def popFront(self) -> int:
        if not self.first and not self.second:
            return -1
        val = self.first.popleft()
        if len(self.first) + 1 < len(self.second):
            self.first.append(self.second.popleft())
        return val

    def popMiddle(self) -> int:
        if not self.first and not self.second:
            return -1
        if len(self.first) < len(self.second):
            val = self.second.popleft()
        else:
            val = self.first.pop()
        if len(self.second) > len(self.first):
            self.first.append(self.second.popleft())
        return val

    def popBack(self) -> int:
        if not self.first and not self.second:
            return -1
        val = self.second.pop()
        if len(self.first) > len(self.second) + 1:
            self.second.appendleft(self.first.pop())
        return val
```
The algorithm is based on using two deques or double-ended queues, `first` and `second`. At any given point, the middle element(s) of the queue can be found between the last element of `first` and the first element of `second`.

When a new element is pushed to the front, middle, or back, depending on the size relationship between the two deques, adjustments are made by transferring elements between `first` and `second`.

For operations that involve popping elements, we check if the queue is empty or not. If it is empty, we return -1. If not, we remove the appropriate element based on the size relationship between the two deques and adjust the deques accordingly, similar to the push operations.

## A solution in Javascript

```javascript
class FrontMiddleBackQueue {
    constructor() {
        this.first = [];
        this.second = [];
    }

    pushFront(val) {
        this.first.unshift(val);
        if (this.first.length > this.second.length + 1) {
            this.second.unshift(this.first.pop());
        }
    }

    pushMiddle(val) {
        if (this.first.length < this.second.length) {
            this.first.push(val);
        } else {
            this.second.unshift(val);
        }
    }

    pushBack(val) {
        this.second.push(val);
        if (this.second.length > this.first.length) {
            this.first.push(this.second.shift());
        }
    }

    popFront() {
        if (this.first.length === 0 && this.second.length === 0) return -1;
        let val = this.first.shift();
        if (this.first.length + 1 < this.second.length) {
            this.first.push(this.second.shift());
        }
        return val;
    }

    popMiddle() {
        if (this.first.length === 0 && this.second.length === 0) return -1;
        let val;
        if (this.first.length < this.second.length) {
            val = this.second.shift();
        } else {
            val = this.first.pop();
        }
        if (this.second.length > this.first.length) {
            this.first.push(this.second.shift());
        }
        return val;
    }

    popBack() {
        if (this.first.length === 0 && this.second.length === 0) return -1;
        let val = this.second.pop();
        if (this.first.length > this.second.length + 1) {
            this.second.unshift(this.first.pop());
        }
        return val;
    }
}
```
The algorithm is based on using two deques or double-ended queues, `first` and `second`. At any given point, the middle element(s) of the queue can be found between the last element of `first` and the first element of `second`.

When a new element is pushed to the front, middle, or back, depending on the size relationship between the two deques, adjustments are made by transferring elements between `first` and `second`.

For operations that involve popping elements, we check if the queue is empty or not. If it is empty, we return -1. If not, we remove the appropriate element based on the size relationship between the two deques and adjust the deques accordingly, similar to the push operations.


# Minimum Number of Removals to Make Mountain Array

- slug: minimum-number-of-removals-to-make-mountain-array
- difficulty: Hard

You may recall that an array `arr` is a **mountain array** if and only if:

*   `arr.length >= 3`
*   There exists some index `i` (**0-indexed**) with `0 < i < arr.length - 1` such that:
    *   `arr[0] < arr[1] < ... < arr[i - 1] < arr[i]`
    *   `arr[i] > arr[i + 1] > ... > arr[arr.length - 1]`

Given an integer array `nums`, return _the **minimum** number of elements to remove to make_ `nums__` _a **mountain array**._

**Example 1:**

**Input:** nums = \[1,3,1\]
**Output:** 0
**Explanation:** The array itself is a mountain array so we do not need to remove any elements.

**Example 2:**

**Input:** nums = \[2,1,1,5,6,2,3,1\]
**Output:** 3
**Explanation:** One solution is to remove the elements at indices 0, 1, and 5, making the array nums = \[1,5,6,3,1\].

**Constraints:**

*   `3 <= nums.length <= 1000`
*   `1 <= nums[i] <= 109`
*   It is guaranteed that you can make a mountain array out of `nums`.

## A solution in Java

```java
public int minimumMountainRemovals(int[] nums) {
    int n = nums.length;
    int[] left = new int[n], right = new int[n];
    for (int i = 1; i < n; ++i) {
        left[i] = left[i - 1] + (nums[i] > nums[i - 1] ? 1 : 0);
        right[n - i - 1] = right[n - i] + (nums[n - i - 1] > nums[n - i] ? 1 : 0);
    }
    int ans = n - 3;
    for (int i = 1; i < n - 1; ++i) {
        ans = Math.min(ans, n - 1 - left[i] - right[i]);
    }
    return ans;
}
```
The algorithm calculates the minimum number of elements to remove to make the input array a mountain array. First, it initializes two arrays `left` and `right`, with the same length as the input array. These arrays will store the increasing and decreasing sequence, respectively, ending at position `i`.

For each index in the range of the input array, the algorithm increases the length of `left` and `right` sequences if the current element is greater than the previous one or if the current element in the reversed array is greater the next one, respectively. Then, the minimum number of elements to remove is calculated by comparing the sum of both sequences for each index, and keeping the minimum value. Subtracting this value from the total length minus one is the final answer.

## A solution in C++

```cpp
int minimumMountainRemovals(vector<int>& nums) {
    int n = nums.size();
    vector<int> left(n), right(n);
    for (int i = 1; i < n; ++i) {
        left[i] = left[i - 1] + (nums[i] > nums[i - 1]);
        right[n - i - 1] = right[n - i] + (nums[n - i - 1] > nums[n - i]);
    }
    int ans = n - 3;
    for (int i = 1; i < n - 1; ++i) {
        ans = min(ans, n - 1 - left[i] - right[i]);
    }
    return ans;
}
```
The algorithm calculates the minimum number of elements to remove to make the input array a mountain array. First, it initializes two arrays `left` and `right`, with the same length as the input array. These arrays will store the increasing and decreasing sequence, respectively, ending at position `i`.

For each index in the range of the input array, the algorithm increases the length of `left` and `right` sequences if the current element is greater than the previous one or if the current element in the reversed array is greater the next one, respectively. Then, the minimum number of elements to remove is calculated by comparing the sum of both sequences for each index, and keeping the minimum value. Subtracting this value from the total length minus one is the final answer.

## A solution in Python

```python
def minimumMountainRemovals(nums):
    n = len(nums)
    left, right = [0] * n, [0] * n
    for i in range(1, n):
        left[i] = left[i - 1] + int(nums[i] > nums[i - 1])
        right[n - i - 1] = right[n - i] + int(nums[n - i - 1] > nums[n - i])
    ans = n - 3
    for i in range(1, n - 1):
        ans = min(ans, n - 1 - left[i] - right[i])
    return ans
```
The algorithm calculates the minimum number of elements to remove to make the input array a mountain array. First, it initializes two arrays `left` and `right`, with the same length as the input array. These arrays will store the increasing and decreasing sequence, respectively, ending at position `i`.

For each index in the range of the input array, the algorithm increases the length of `left` and `right` sequences if the current element is greater than the previous one or if the current element in the reversed array is greater the next one, respectively. Then, the minimum number of elements to remove is calculated by comparing the sum of both sequences for each index, and keeping the minimum value. Subtracting this value from the total length minus one is the final answer.

## A solution in Javascript

```javascript
function minimumMountainRemovals(nums) {
    const n = nums.length;
    const left = new Array(n).fill(0);
    const right = new Array(n).fill(0);
    for (let i = 1; i < n; ++i) {
        left[i] = left[i - 1] + (nums[i] > nums[i - 1] ? 1 : 0);
        right[n - i - 1] = right[n - i] + (nums[n - i - 1] > nums[n - i] ? 1 : 0);
    }
    let ans = n - 3;
    for (let i = 1; i < n - 1; ++i) {
        ans = Math.min(ans, n - 1 - left[i] - right[i]);
    }
    return ans;
}
```
The algorithm calculates the minimum number of elements to remove to make the input array a mountain array. First, it initializes two arrays `left` and `right`, with the same length as the input array. These arrays will store the increasing and decreasing sequence, respectively, ending at position `i`.

For each index in the range of the input array, the algorithm increases the length of `left` and `right` sequences if the current element is greater than the previous one or if the current element in the reversed array is greater the next one, respectively. Then, the minimum number of elements to remove is calculated by comparing the sum of both sequences for each index, and keeping the minimum value. Subtracting this value from the total length minus one is the final answer.


# Richest Customer Wealth

- slug: richest-customer-wealth
- difficulty: Easy

You are given an `m x n` integer grid `accounts` where `accounts[i][j]` is the amount of money the `ith` customer has in the `jth` bank. Return _the **wealth** that the richest customer has._

A customer's **wealth** is the amount of money they have in all their bank accounts. The richest customer is the customer that has the maximum **wealth**.

**Example 1:**

**Input:** accounts = \[\[1,2,3\],\[3,2,1\]\]
**Output:** 6
**Explanation****:**
`1st customer has wealth = 1 + 2 + 3 = 6`
`2nd customer has wealth = 3 + 2 + 1 = 6`
Both customers are considered the richest with a wealth of 6 each, so return 6.

**Example 2:**

**Input:** accounts = \[\[1,5\],\[7,3\],\[3,5\]\]
**Output:** 10
**Explanation**:
1st customer has wealth = 6
2nd customer has wealth = 10
3rd customer has wealth = 8
The 2nd customer is the richest with a wealth of 10.

**Example 3:**

**Input:** accounts = \[\[2,8,7\],\[7,1,3\],\[1,9,5\]\]
**Output:** 17

**Constraints:**

*   `m == accounts.length`
*   `n == accounts[i].length`
*   `1 <= m, n <= 50`
*   `1 <= accounts[i][j] <= 100`

## A solution in Java

```java
public int maximumWealth(int[][] accounts) {
    int maxWealth = 0;
    for (int[] customer : accounts) {
        int wealth = 0;
        for (int account : customer) {
            wealth += account;
        }
        maxWealth = Math.max(maxWealth, wealth);
    }
    return maxWealth;
}
```
The algorithm iterates through each customer in the given grid (accounts) and calculates their total wealth by summing the values in their bank accounts. After calculating the wealth for a customer, the algorithm checks if it is greater than the current maximum wealth, and if so, the maximum wealth gets updated to the new wealth value. After all iterations, the algorithm returns the maximum wealth found.

The approach is the same for each language, just with minor syntactical differences between them.

## A solution in C++

```cpp
int maximumWealth(vector<vector<int>>& accounts) {
    int max_wealth = 0;
    for (auto& customer : accounts) {
        int wealth = 0;
        for (int account : customer) {
            wealth += account;
        }
        max_wealth = max(max_wealth, wealth);
    }
    return max_wealth;
}
```
The algorithm iterates through each customer in the given grid (accounts) and calculates their total wealth by summing the values in their bank accounts. After calculating the wealth for a customer, the algorithm checks if it is greater than the current maximum wealth, and if so, the maximum wealth gets updated to the new wealth value. After all iterations, the algorithm returns the maximum wealth found.

The approach is the same for each language, just with minor syntactical differences between them.

## A solution in Python

```python
def maximumWealth(accounts):
    max_wealth = 0
    for customer in accounts:
        wealth = sum(customer)
        max_wealth = max(max_wealth, wealth)
    return max_wealth
```
The algorithm iterates through each customer in the given grid (accounts) and calculates their total wealth by summing the values in their bank accounts. After calculating the wealth for a customer, the algorithm checks if it is greater than the current maximum wealth, and if so, the maximum wealth gets updated to the new wealth value. After all iterations, the algorithm returns the maximum wealth found.

The approach is the same for each language, just with minor syntactical differences between them.

## A solution in Javascript

```javascript
function maximumWealth(accounts) {
    let maxWealth = 0;
    for (let customer of accounts) {
        let wealth = 0;
        for (let account of customer) {
            wealth += account;
        }
        maxWealth = Math.max(maxWealth, wealth);
    }
    return maxWealth;
}
```
The algorithm iterates through each customer in the given grid (accounts) and calculates their total wealth by summing the values in their bank accounts. After calculating the wealth for a customer, the algorithm checks if it is greater than the current maximum wealth, and if so, the maximum wealth gets updated to the new wealth value. After all iterations, the algorithm returns the maximum wealth found.

The approach is the same for each language, just with minor syntactical differences between them.


# Find the Most Competitive Subsequence

- slug: find-the-most-competitive-subsequence
- difficulty: Medium

Given an integer array `nums` and a positive integer `k`, return _the most **competitive** subsequence of_ `nums` _of size_ `k`.

An array's subsequence is a resulting sequence obtained by erasing some (possibly zero) elements from the array.

We define that a subsequence `a` is more **competitive** than a subsequence `b` (of the same length) if in the first position where `a` and `b` differ, subsequence `a` has a number **less** than the corresponding number in `b`. For example, `[1,3,4]` is more competitive than `[1,3,5]` because the first position they differ is at the final number, and `4` is less than `5`.

**Example 1:**

**Input:** nums = \[3,5,2,6\], k = 2
**Output:** \[2,6\]
**Explanation:** Among the set of every possible subsequence: {\[3,5\], \[3,2\], \[3,6\], \[5,2\], \[5,6\], \[2,6\]}, \[2,6\] is the most competitive.

**Example 2:**

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

**Constraints:**

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

## A solution in Java

```java
import java.util.Stack;

public int[] mostCompetitive(int[] nums, int k) {
    Stack<Integer> stack = new Stack<>();
    int n = nums.length;
    for (int i = 0; i < n; i++) {
        while (!stack.empty() && stack.peek() > nums[i] && stack.size() + n - i > k) {
            stack.pop();
        }
        if (stack.size() < k) {
            stack.push(nums[i]);
        }
    }
    int[] result = new int[k];
    for (int i = k - 1; i >= 0; i--) {
        result[i] = stack.pop();
    }
    return result;
}
```
The algorithm works by keeping a monotonically increasing stack. We iterate through the `nums` array and try to make our stack size equal to `k`. At each step, we check if it is possible to remove the current top element of the stack and still have `k` elements after processing all of the array elements. If it is possible and the current top element of the stack is greater than the current element in `nums`, we remove it. This ensures that the stack remains monotonically increasing and holds the most competitive subsequence of size `k`.

After processing all the elements in `nums`, the stack will have the most competitive subsequence of size `k`. We convert the stack into a result array/vector/list and return it.

## A solution in C++

```cpp
#include <vector>
#include <stack>

std::vector<int> mostCompetitive(std::vector<int>& nums, int k) {
    std::stack<int> stk;
    int n = nums.size();
    for (int i = 0; i < n; i++) {
        while (!stk.empty() && stk.top() > nums[i] && stk.size() + n - i > k) {
            stk.pop();
        }
        if (stk.size() < k) {
            stk.push(nums[i]);
        }
    }
    std::vector<int> result(k);
    for (int i = k - 1; i >= 0; i--) {
        result[i] = stk.top();
        stk.pop();
    }
    return result;
}
```
The algorithm works by keeping a monotonically increasing stack. We iterate through the `nums` array and try to make our stack size equal to `k`. At each step, we check if it is possible to remove the current top element of the stack and still have `k` elements after processing all of the array elements. If it is possible and the current top element of the stack is greater than the current element in `nums`, we remove it. This ensures that the stack remains monotonically increasing and holds the most competitive subsequence of size `k`.

After processing all the elements in `nums`, the stack will have the most competitive subsequence of size `k`. We convert the stack into a result array/vector/list and return it.

## A solution in Python

```python
from collections import deque

def mostCompetitive(nums, k):
    stack = deque()
    n = len(nums)
    for i in range(n):
        while stack and stack[-1] > nums[i] and len(stack) + n - i > k:
            stack.pop()
        if len(stack) < k:
            stack.append(nums[i])
    return list(stack)
```
The algorithm works by keeping a monotonically increasing stack. We iterate through the `nums` array and try to make our stack size equal to `k`. At each step, we check if it is possible to remove the current top element of the stack and still have `k` elements after processing all of the array elements. If it is possible and the current top element of the stack is greater than the current element in `nums`, we remove it. This ensures that the stack remains monotonically increasing and holds the most competitive subsequence of size `k`.

After processing all the elements in `nums`, the stack will have the most competitive subsequence of size `k`. We convert the stack into a result array/vector/list and return it.

## A solution in Javascript

```javascript
function mostCompetitive(nums, k) {
    let stack = [];
    let n = nums.length;
    for (let i = 0; i < n; i++) {
        while (stack.length > 0 && stack[stack.length - 1] > nums[i] && stack.length + n - i > k) {
            stack.pop();
        }
        if (stack.length < k) {
            stack.push(nums[i]);
        }
    }
    return stack;
}
```
The algorithm works by keeping a monotonically increasing stack. We iterate through the `nums` array and try to make our stack size equal to `k`. At each step, we check if it is possible to remove the current top element of the stack and still have `k` elements after processing all of the array elements. If it is possible and the current top element of the stack is greater than the current element in `nums`, we remove it. This ensures that the stack remains monotonically increasing and holds the most competitive subsequence of size `k`.

After processing all the elements in `nums`, the stack will have the most competitive subsequence of size `k`. We convert the stack into a result array/vector/list and return it.


# Minimum Moves to Make Array Complementary

- slug: minimum-moves-to-make-array-complementary
- difficulty: Medium

You are given an integer array `nums` of **even** length `n` and an integer `limit`. In one move, you can replace any integer from `nums` with another integer between `1` and `limit`, inclusive.

The array `nums` is **complementary** if for all indices `i` (**0-indexed**), `nums[i] + nums[n - 1 - i]` equals the same number. For example, the array `[1,2,3,4]` is complementary because for all indices `i`, `nums[i] + nums[n - 1 - i] = 5`.

Return the _**minimum** number of moves required to make_ `nums` _**complementary**_.

**Example 1:**

**Input:** nums = \[1,2,4,3\], limit = 4
**Output:** 1
**Explanation:** In 1 move, you can change nums to \[1,2,2,3\] (underlined elements are changed).
nums\[0\] + nums\[3\] = 1 + 3 = 4.
nums\[1\] + nums\[2\] = 2 + 2 = 4.
nums\[2\] + nums\[1\] = 2 + 2 = 4.
nums\[3\] + nums\[0\] = 3 + 1 = 4.
Therefore, nums\[i\] + nums\[n-1-i\] = 4 for every i, so nums is complementary.

**Example 2:**

**Input:** nums = \[1,2,2,1\], limit = 2
**Output:** 2
**Explanation:** In 2 moves, you can change nums to \[2,2,2,2\]. You cannot change any number to 3 since 3 > limit.

**Example 3:**

**Input:** nums = \[1,2,1,2\], limit = 2
**Output:** 0
**Explanation:** nums is already complementary.

**Constraints:**

*   `n == nums.length`
*   `2 <= n <= 105`
*   `1 <= nums[i] <= limit <= 105`
*   `n` is even.

## A solution in Java

```java
public int minOperations(int n) {
    return n * (n - 1) / 2;
}
```
The array arr is an arithmetic progression with an odd common difference of 2, and we want to make all the elements equal. We can achieve this by making all elements equal to the average of the array. The average is equal to (2 * 0 + 1 + 2 * (n - 1) + 1) / 2 = n. Therefore, our goal is to make all elements equal to n.

Let's look at how many steps are required to convert each element in the array to the target value of n. For the first element (index 0), we need to increase its value by (n - 1) steps. For the second element (index 1), we need to decrease its value by (n - 3) steps. Continuing this pattern, for every pair of indices (i, n - i - 1) we can find the number of steps required as the sum of the absolute differences between each element and n.

We can write the sum of steps as:
S = (n - 1) + (n - 3) + ... up to n/2 times

Let's write this sum using the arithmetic progression sum formula:
S = (n - 1) * n / 4

Since we only need the integer value of the result, the total number of minimum operations needed to make all elements equal will be n * (n - 1) / 2.

## A solution in C++

```c++
int minOperations(int n) {
    return n * (n - 1) / 2;
}
```
The array arr is an arithmetic progression with an odd common difference of 2, and we want to make all the elements equal. We can achieve this by making all elements equal to the average of the array. The average is equal to (2 * 0 + 1 + 2 * (n - 1) + 1) / 2 = n. Therefore, our goal is to make all elements equal to n.

Let's look at how many steps are required to convert each element in the array to the target value of n. For the first element (index 0), we need to increase its value by (n - 1) steps. For the second element (index 1), we need to decrease its value by (n - 3) steps. Continuing this pattern, for every pair of indices (i, n - i - 1) we can find the number of steps required as the sum of the absolute differences between each element and n.

We can write the sum of steps as:
S = (n - 1) + (n - 3) + ... up to n/2 times

Let's write this sum using the arithmetic progression sum formula:
S = (n - 1) * n / 4

Since we only need the integer value of the result, the total number of minimum operations needed to make all elements equal will be n * (n - 1) / 2.

## A solution in Python

```python
def min_operations(n):
    return n * (n - 1) // 2
```
The array arr is an arithmetic progression with an odd common difference of 2, and we want to make all the elements equal. We can achieve this by making all elements equal to the average of the array. The average is equal to (2 * 0 + 1 + 2 * (n - 1) + 1) / 2 = n. Therefore, our goal is to make all elements equal to n.

Let's look at how many steps are required to convert each element in the array to the target value of n. For the first element (index 0), we need to increase its value by (n - 1) steps. For the second element (index 1), we need to decrease its value by (n - 3) steps. Continuing this pattern, for every pair of indices (i, n - i - 1) we can find the number of steps required as the sum of the absolute differences between each element and n.

We can write the sum of steps as:
S = (n - 1) + (n - 3) + ... up to n/2 times

Let's write this sum using the arithmetic progression sum formula:
S = (n - 1) * n / 4

Since we only need the integer value of the result, the total number of minimum operations needed to make all elements equal will be n * (n - 1) / 2.

## A solution in Javascript

```javascript
function minOperations(n) {
    return n * (n - 1) / 2;
}
```
The array arr is an arithmetic progression with an odd common difference of 2, and we want to make all the elements equal. We can achieve this by making all elements equal to the average of the array. The average is equal to (2 * 0 + 1 + 2 * (n - 1) + 1) / 2 = n. Therefore, our goal is to make all elements equal to n.

Let's look at how many steps are required to convert each element in the array to the target value of n. For the first element (index 0), we need to increase its value by (n - 1) steps. For the second element (index 1), we need to decrease its value by (n - 3) steps. Continuing this pattern, for every pair of indices (i, n - i - 1) we can find the number of steps required as the sum of the absolute differences between each element and n.

We can write the sum of steps as:
S = (n - 1) + (n - 3) + ... up to n/2 times

Let's write this sum using the arithmetic progression sum formula:
S = (n - 1) * n / 4

Since we only need the integer value of the result, the total number of minimum operations needed to make all elements equal will be n * (n - 1) / 2.


# Minimize Deviation in Array

- slug: minimize-deviation-in-array
- difficulty: Hard

You are given an array `nums` of `n` positive integers.

You can perform two types of operations on any element of the array any number of times:

*   If the element is **even**, **divide** it by `2`.
    *   For example, if the array is `[1,2,3,4]`, then you can do this operation on the last element, and the array will be `[1,2,3,2].`
*   If the element is **odd**, **multiply** it by `2`.
    *   For example, if the array is `[1,2,3,4]`, then you can do this operation on the first element, and the array will be `[2,2,3,4].`

The **deviation** of the array is the **maximum difference** between any two elements in the array.

Return _the **minimum deviation** the array can have after performing some number of operations._

**Example 1:**

**Input:** nums = \[1,2,3,4\]
**Output:** 1
**Explanation:** You can transform the array to \[1,2,3,2\], then to \[2,2,3,2\], then the deviation will be 3 - 2 = 1.

**Example 2:**

**Input:** nums = \[4,1,5,20,3\]
**Output:** 3
**Explanation:** You can transform the array after two operations to \[4,2,5,5,3\], then the deviation will be 5 - 2 = 3.

**Example 3:**

**Input:** nums = \[2,10,8\]
**Output:** 3

**Constraints:**

*   `n == nums.length`
*   `2 <= n <= 5 * 104`
*   `1 <= nums[i] <= 109`

## A solution in Java

```java
import java.util.Arrays;

public int maxDistance(int[] position, int m) {
    Arrays.sort(position);

    int left = 1;
    int right = position[position.length - 1] - position[0];
    int ans = 0;

    while (left <= right) {
        int mid = (left + right) / 2;
        if (canPlaceBalls(mid, position, m)) {
            ans = mid;
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }

    return ans;
}

private boolean canPlaceBalls(int force, int[] position, int m) {
    int last_position = position[0];
    int placed_balls = 1;

    for (int i = 1; i < position.length; i++) {
        if (position[i] - last_position >= force) {
            placed_balls++;
            last_position = position[i];

            if (placed_balls == m) {
                return true;
            }
        }
    }

    return false;
}
```
The algorithm consists of a binary search to find the minimum distance between `m` balls in the baskets. It has a helper function, `canPlaceBalls`, that checks if it is possible to place `m` balls in the baskets with the given minimum distance. The main function, `maxDistance`, sorts the position array first and then does the binary search. During the binary search, it repeatedly calls the `canPlaceBalls` function with different distances to find the maximum distance, where `m` balls can still be placed in the baskets.

## A solution in C++

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

bool canPlaceBalls(int force, const std::vector<int>& position, int m) {
    int last_position = position[0];
    int placed_balls = 1;

    for (int i = 1; i < position.size(); i++) {
        if (position[i] - last_position >= force) {
            placed_balls++;
            last_position = position[i];

            if (placed_balls == m) {
                return true;
            }
        }
    }

    return false;
}

int maxDistance(std::vector<int>& position, int m) {
    std::sort(position.begin(), position.end());

    int left = 1;
    int right = position.back() - position[0];
    int ans = 0;

    while (left <= right) {
        int mid = (left + right) / 2;
        if (canPlaceBalls(mid, position, m)) {
            ans = mid;
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }

    return ans;
}
```
The algorithm consists of a binary search to find the minimum distance between `m` balls in the baskets. It has a helper function, `canPlaceBalls`, that checks if it is possible to place `m` balls in the baskets with the given minimum distance. The main function, `maxDistance`, sorts the position array first and then does the binary search. During the binary search, it repeatedly calls the `canPlaceBalls` function with different distances to find the maximum distance, where `m` balls can still be placed in the baskets.

## A solution in Python

```python
from typing import List

def can_place_balls(force: int, position: List[int], m: int) -> bool:
    last_position = position[0]
    placed_balls = 1

    for i in range(1, len(position)):
        if position[i] - last_position >= force:
            placed_balls += 1
            last_position = position[i]

            if placed_balls == m:
                return True

    return False

def max_distance(position: List[int], m: int) -> int:
    position.sort()

    left = 1
    right = position[-1] - position[0]
    ans = 0

    while left <= right:
        mid = (left + right) // 2
        if can_place_balls(mid, position, m):
            ans = mid
            left = mid + 1
        else:
            right = mid - 1

    return ans
```
The algorithm consists of a binary search to find the minimum distance between `m` balls in the baskets. It has a helper function, `canPlaceBalls`, that checks if it is possible to place `m` balls in the baskets with the given minimum distance. The main function, `maxDistance`, sorts the position array first and then does the binary search. During the binary search, it repeatedly calls the `canPlaceBalls` function with different distances to find the maximum distance, where `m` balls can still be placed in the baskets.

## A solution in Javascript

```javascript
function canPlaceBalls(force, position, m) {
    let last_position = position[0];
    let placed_balls = 1;

    for (let i = 1; i < position.length; i++) {
        if (position[i] - last_position >= force) {
            placed_balls++;
            last_position = position[i];

            if (placed_balls === m) {
                return true;
            }
        }
    }

    return false;
}

function maxDistance(position, m) {
    position.sort((a, b) => a - b);

    let left = 1;
    let right = position[position.length - 1] - position[0];
    let ans = 0;

    while (left <= right) {
        let mid = Math.floor((left + right) / 2);
        if (canPlaceBalls(mid, position, m)) {
            ans = mid;
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }

    return ans;
}
```
The algorithm consists of a binary search to find the minimum distance between `m` balls in the baskets. It has a helper function, `canPlaceBalls`, that checks if it is possible to place `m` balls in the baskets with the given minimum distance. The main function, `maxDistance`, sorts the position array first and then does the binary search. During the binary search, it repeatedly calls the `canPlaceBalls` function with different distances to find the maximum distance, where `m` balls can still be placed in the baskets.