# Print Words Vertically

- slug: print-words-vertically
- difficulty: Medium

Given a string `s`. Return all the words vertically in the same order in which they appear in `s`.
Words are returned as a list of strings, complete with spaces when is necessary. (Trailing spaces are not allowed).
Each word would be put on only one column and that in one column there will be only one word.

**Example 1:**

**Input:** s =  "HOW ARE YOU "
**Output:** \[ "HAY ", "ORO ", "WEU "\]
**Explanation:** Each word is printed vertically.
  "HAY "
  "ORO "
  "WEU "

**Example 2:**

**Input:** s =  "TO BE OR NOT TO BE "
**Output:** \[ "TBONTB ", "OEROOE ", "   T "\]
**Explanation:** Trailing spaces is not allowed.
 "TBONTB "
 "OEROOE "
 "   T "

**Example 3:**

**Input:** s =  "CONTEST IS COMING "
**Output:** \[ "CIC ", "OSO ", "N M ", "T I ", "E N ", "S G ", "T "\]

**Constraints:**

*   `1 <= s.length <= 200`
*   `s` contains only upper case English letters.
*   It's guaranteed that there is only one space between 2 words.

## A solution in Java

```java
public int[] findBall(int[][] grid) {
    int m = grid.length;
    int n = grid[0].length;
    int[] result = new int[n];

    for (int i = 0; i < n; i++) {
        int x = 0, y = i;
        result[i] = -1;

        while (x < m) {
            int nx = x + 1, ny = y + grid[x][y];
            if (ny < 0 || ny >= n || grid[x][ny] != grid[x][y]) break;
            x = nx;
            y = ny;
        }

        if (x == m) {
            result[i] = y;
        }
    }

    return result;
}
```
1. Initialize the result array with a size of n and fill it with -1.
2. Loop through the columns of the grid.
3. For each ball dropped from the i-th column, store the current position (x, y) as 0, i.
4. In each step, calculate the next position of the ball based on the direction provided by the grid cell (i.e., x + 1, y + grid[x][y]).
5. Check if the ball would hit a wall or get stuck in a "V" shaped pattern: if the next y-coordinate is out of range or the direction in the next cell is different.
6. If neither condition is fulfilled, update the current position to the next position.
7. When the ball reaches the bottom (x == m), update the result[i] with the final y-coordinate.
8. Return the result array.

## A solution in C++

```cpp
vector<int> findBall(vector<vector<int>>& grid) {
    int m = grid.size();
    int n = grid[0].size();
    vector<int> result(n, -1);

    for (int i = 0; i < n; i++) {
        int x = 0, y = i;

        while (x < m) {
            int nx = x + 1, ny = y + grid[x][y];
            if (ny < 0 || ny >= n || grid[x][ny] != grid[x][y]) break;
            x = nx;
            y = ny;
        }

        if (x == m) {
            result[i] = y;
        }
    }

    return result;
}
```
1. Initialize the result array with a size of n and fill it with -1.
2. Loop through the columns of the grid.
3. For each ball dropped from the i-th column, store the current position (x, y) as 0, i.
4. In each step, calculate the next position of the ball based on the direction provided by the grid cell (i.e., x + 1, y + grid[x][y]).
5. Check if the ball would hit a wall or get stuck in a "V" shaped pattern: if the next y-coordinate is out of range or the direction in the next cell is different.
6. If neither condition is fulfilled, update the current position to the next position.
7. When the ball reaches the bottom (x == m), update the result[i] with the final y-coordinate.
8. Return the result array.

## A solution in Python

```python
def findBall(grid):
    m, n = len(grid), len(grid[0])
    result = [-1] * n

    for i in range(n):
        x, y = 0, i

        while x < m:
            nx, ny = x + 1, y + grid[x][y]
            if ny < 0 or ny >= n or grid[x][ny] != grid[x][y]:
                break
            x, y = nx, ny

        if x == m:
            result[i] = y

    return result
```
1. Initialize the result array with a size of n and fill it with -1.
2. Loop through the columns of the grid.
3. For each ball dropped from the i-th column, store the current position (x, y) as 0, i.
4. In each step, calculate the next position of the ball based on the direction provided by the grid cell (i.e., x + 1, y + grid[x][y]).
5. Check if the ball would hit a wall or get stuck in a "V" shaped pattern: if the next y-coordinate is out of range or the direction in the next cell is different.
6. If neither condition is fulfilled, update the current position to the next position.
7. When the ball reaches the bottom (x == m), update the result[i] with the final y-coordinate.
8. Return the result array.

## A solution in Javascript

```javascript
function findBall(grid) {
    const m = grid.length;
    const n = grid[0].length;
    const result = new Array(n).fill(-1);

    for (let i = 0; i < n; i++) {
        let x = 0, y = i;

        while (x < m) {
            let nx = x + 1;
            let ny = y + grid[x][y];
            if (ny < 0 || ny >= n || grid[x][ny] !== grid[x][y]) break;
            x = nx;
            y = ny;
        }

        if (x === m) {
            result[i] = y;
        }
    }

    return result;
}
```
1. Initialize the result array with a size of n and fill it with -1.
2. Loop through the columns of the grid.
3. For each ball dropped from the i-th column, store the current position (x, y) as 0, i.
4. In each step, calculate the next position of the ball based on the direction provided by the grid cell (i.e., x + 1, y + grid[x][y]).
5. Check if the ball would hit a wall or get stuck in a "V" shaped pattern: if the next y-coordinate is out of range or the direction in the next cell is different.
6. If neither condition is fulfilled, update the current position to the next position.
7. When the ball reaches the bottom (x == m), update the result[i] with the final y-coordinate.
8. Return the result array.


# Delete Leaves With a Given Value

- slug: delete-leaves-with-a-given-value
- difficulty: Medium

Given a binary tree `root` and an integer `target`, delete all the **leaf nodes** with value `target`.

Note that once you delete a leaf node with value `target`**,** if its parent node becomes a leaf node and has the value `target`, it should also be deleted (you need to continue doing that until you cannot).

**Example 1:**

**Input:** root = \[1,2,3,2,null,2,4\], target = 2
**Output:** \[1,null,3,null,4\]
**Explanation:** Leaf nodes in green with value (target = 2) are removed (Picture in left).
After removing, new nodes become leaf nodes with value (target = 2) (Picture in center).

**Example 2:**

**Input:** root = \[1,3,3,3,2\], target = 3
**Output:** \[1,3,null,null,2\]

**Example 3:**

**Input:** root = \[1,2,null,2,null,2\], target = 2
**Output:** \[1\]
**Explanation:** Leaf nodes in green with value (target = 2) are removed at each step.

**Constraints:**

*   The number of nodes in the tree is in the range `[1, 3000]`.
*   `1 <= Node.val, target <= 1000`

## A solution in Java

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

public class Solution {
    public double maxProbability(int n, int[][] edges, double[] succProb, int start, int end) {
        List<List<Edge>> graph = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            graph.add(new ArrayList<>());
        }
        for (int i = 0; i < edges.length; i++) {
            graph.get(edges[i][0]).add(new Edge(edges[i][1], succProb[i]));
            graph.get(edges[i][1]).add(new Edge(edges[i][0], succProb[i]));
        }

        double[] maxProb = new double[n];
        maxProb[start] = 1;

        PriorityQueue<Edge> pq = new PriorityQueue<>((a, b) -> Double.compare(b.prob, a.prob));
        pq.offer(new Edge(start, 1));

        while (!pq.isEmpty()) {
            Edge edge = pq.poll();
            int node = edge.to;
            double prob = edge.prob;

            if (node == end) {
                return prob;
            }

            if (prob < maxProb[node]) {
                continue;
            }

            for (Edge e : graph.get(node)) {
                double newProb = prob * e.prob;
                if (newProb > maxProb[e.to]) {
                    maxProb[e.to] = newProb;
                    pq.offer(new Edge(e.to, newProb));
                }
            }
        }

        return 0;
    }

    private static class Edge {
        int to;
        double prob;

        Edge(int to, double prob) {
            this.to = to;
            this.prob = prob;
        }
    }
}
```
We use Dijkstra's algorithm with a priority queue to find the path with the maximum probability in the given graph. In this variation, we calculate the probability of success for each edge/vertex and use it to update the maximum probabilities table, keeping the highest probability for each node. The algorithm begins with the start node and iterates through its neighbors, calculating new probabilities and updating the table if needed. If a node with an updated probability is found, we add it to the priority queue, keeping the highest probability nodes first. The process continues until the end node is reached or no more nodes can be visited. If the end node is reached, the algorithm returns its probability; otherwise, it returns 0.

## A solution in C++

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

double maxProbability(int n, vector<vector<int>>& edges, vector<double>& succProb, int start, int end) {
    vector<vector<pair<int, double>>> graph(n);
    for (int i = 0; i < edges.size(); ++i) {
        graph[edges[i][0]].emplace_back(edges[i][1], succProb[i]);
        graph[edges[i][1]].emplace_back(edges[i][0], succProb[i]);
    }

    vector<double> maxProb(n, 0);
    maxProb[start] = 1;

    priority_queue<pair<double, int>> pq;
    pq.emplace(1, start);

    while (!pq.empty()) {
        double prob = pq.top().first;
        int node = pq.top().second;
        pq.pop();

        if (node == end) {
            return prob;
        }

        if (prob < maxProb[node]) {
            continue;
        }

        for (auto& edge : graph[node]) {
            double newProb = prob * edge.second;
            if (newProb > maxProb[edge.first]) {
                maxProb[edge.first] = newProb;
                pq.emplace(newProb, edge.first);
            }
        }
    }

    return 0;
}
```
We use Dijkstra's algorithm with a priority queue to find the path with the maximum probability in the given graph. In this variation, we calculate the probability of success for each edge/vertex and use it to update the maximum probabilities table, keeping the highest probability for each node. The algorithm begins with the start node and iterates through its neighbors, calculating new probabilities and updating the table if needed. If a node with an updated probability is found, we add it to the priority queue, keeping the highest probability nodes first. The process continues until the end node is reached or no more nodes can be visited. If the end node is reached, the algorithm returns its probability; otherwise, it returns 0.

## A solution in Python

```python
from heapq import heappush, heappop

def maxProbability(n, edges, succProb, start, end):
    graph = [[] for _ in range(n)]
    for i in range(len(edges)):
        a, b = edges[i]
        graph[a].append((b, succProb[i]))
        graph[b].append((a, succProb[i]))

    max_prob = [0] * n
    max_prob[start] = 1

    pq = [(-1, start)]

    while pq:
        prob, node = heappop(pq)

        if node == end:
            return -prob

        if -prob < max_prob[node]:
            continue

        for neighbor, edge_prob in graph[node]:
            new_prob = -prob * edge_prob
            if new_prob > max_prob[neighbor]:
                max_prob[neighbor] = new_prob
                heappush(pq, (-new_prob, neighbor))

    return 0
```
We use Dijkstra's algorithm with a priority queue to find the path with the maximum probability in the given graph. In this variation, we calculate the probability of success for each edge/vertex and use it to update the maximum probabilities table, keeping the highest probability for each node. The algorithm begins with the start node and iterates through its neighbors, calculating new probabilities and updating the table if needed. If a node with an updated probability is found, we add it to the priority queue, keeping the highest probability nodes first. The process continues until the end node is reached or no more nodes can be visited. If the end node is reached, the algorithm returns its probability; otherwise, it returns 0.

## A solution in Javascript

```javascript
function maxProbability(n, edges, succProb, start, end) {
  const graph = new Array(n).fill(null).map(() => []);
  for (let i = 0; i < edges.length; i++) {
    const [a, b] = edges[i];
    graph[a].push([b, succProb[i]]);
    graph[b].push([a, succProb[i]]);
  }

  const maxProb = new Array(n).fill(0);
  maxProb[start] = 1;

  const pq = [[1, start]];

  while (pq.length) {
    const [prob, node] = pq.pop();

    if (node === end) {
      return prob;
    }

    if (prob < maxProb[node]) {
      continue;
    }

    for (const [neighbor, edgeProb] of graph[node]) {
      const newProb = prob * edgeProb;
      if (newProb > maxProb[neighbor]) {
        maxProb[neighbor] = newProb;
        pq.push([newProb, neighbor]);

        // Re-sort the queue, so it stays a max heap.
        pq.sort(([a], [b]) => b - a);
      }
    }
  }

  return 0;
}
```
We use Dijkstra's algorithm with a priority queue to find the path with the maximum probability in the given graph. In this variation, we calculate the probability of success for each edge/vertex and use it to update the maximum probabilities table, keeping the highest probability for each node. The algorithm begins with the start node and iterates through its neighbors, calculating new probabilities and updating the table if needed. If a node with an updated probability is found, we add it to the priority queue, keeping the highest probability nodes first. The process continues until the end node is reached or no more nodes can be visited. If the end node is reached, the algorithm returns its probability; otherwise, it returns 0.


# Minimum Number of Taps to Open to Water a Garden

- slug: minimum-number-of-taps-to-open-to-water-a-garden
- difficulty: Hard

There is a one-dimensional garden on the x-axis. The garden starts at the point `0` and ends at the point `n`. (i.e The length of the garden is `n`).

There are `n + 1` taps located at points `[0, 1, ..., n]` in the garden.

Given an integer `n` and an integer array `ranges` of length `n + 1` where `ranges[i]` (0-indexed) means the `i-th` tap can water the area `[i - ranges[i], i + ranges[i]]` if it was open.

Return _the minimum number of taps_ that should be open to water the whole garden, If the garden cannot be watered return **\-1**.

**Example 1:**

**Input:** n = 5, ranges = \[3,4,1,1,0,0\]
**Output:** 1
**Explanation:** The tap at point 0 can cover the interval \[-3,3\]
The tap at point 1 can cover the interval \[-3,5\]
The tap at point 2 can cover the interval \[1,3\]
The tap at point 3 can cover the interval \[2,4\]
The tap at point 4 can cover the interval \[4,4\]
The tap at point 5 can cover the interval \[5,5\]
Opening Only the second tap will water the whole garden \[0,5\]

**Example 2:**

**Input:** n = 3, ranges = \[0,0,0,0\]
**Output:** -1
**Explanation:** Even if you activate all the four taps you cannot water the whole garden.

**Constraints:**

*   `1 <= n <= 104`
*   `ranges.length == n + 1`
*   `0 <= ranges[i] <= 100`

## A solution in Java

```java
public int sumOfFlooredPairs(int[] nums) {
    int mod = 1000000007;
    int maxVal = Integer.MIN_VALUE;
    for (int num : nums) {
        maxVal = Math.max(maxVal, num);
    }
    int[] count = new int[maxVal + 1];
    long[] prefSum = new long[maxVal + 1];

    for (int num : nums) {
        count[num]++;
    }

    for (int i = 1; i <= maxVal; i++) {
        prefSum[i] = (prefSum[i - 1] + count[i]) % mod;
    }

    long res = 0;
    for (int x = 1; x <= maxVal; x++) {
        for (int k = 1, nx = x; nx <= maxVal; k++, nx += x) {
            res = (res + ((prefSum[nx] - prefSum[nx - x] + mod) % mod) * k % mod * count[x] % mod) % mod;
        }
    }
    return (int) res;
}
```
The algorithm first calculates the maximum value present in the array named maxVal. Then it initializes two other arrays: count and prefSum of size (maxVal + 1). The count array stores the frequency count of numbers in the input array, and prefSum stores the prefix sum of count array modulo mod (10^9 + 7).

The main logic is implemented using nested loops. The outer loop iterates through each unique number (x) in the input array, and the inner loop generates multiples of that number (nx) within the range of the maximum value. For each nx, calculate the result as the product of count[x], k, and the sum of the prefSum values within the range (nx - x) and nx modulo mod. The final result is obtained by summing these products modulo mod for every possible pair of numbers in the input array.

The time complexity of the algorithm is O(maxVal^2) where maxVal is the maximum value in the input array nums. The space complexity is O(maxVal) due to the count and prefSum arrays.

## A solution in C++

```cpp
#include <vector>

int sumOfFlooredPairs(std::vector<int>& nums) {
    int mod = 1e9 + 7;
    int maxVal = *max_element(nums.begin(), nums.end());
    std::vector<int> count(maxVal + 1, 0);
    std::vector<long long> prefSum(maxVal + 1, 0);

    for (int num : nums) {
        count[num]++;
    }

    for (int i = 1; i <= maxVal; i++) {
        prefSum[i] = (prefSum[i - 1] + count[i]) % mod;
    }

    long long res = 0;
    for (int x = 1; x <= maxVal; x++) {
        for (int k = 1, nx = x; nx <= maxVal; k++, nx += x) {
            res = (res + ((prefSum[nx] - prefSum[nx - x] + mod) % mod) * k % mod * count[x] % mod) % mod;
        }
    }
    return res;
}
```
The algorithm first calculates the maximum value present in the array named maxVal. Then it initializes two other arrays: count and prefSum of size (maxVal + 1). The count array stores the frequency count of numbers in the input array, and prefSum stores the prefix sum of count array modulo mod (10^9 + 7).

The main logic is implemented using nested loops. The outer loop iterates through each unique number (x) in the input array, and the inner loop generates multiples of that number (nx) within the range of the maximum value. For each nx, calculate the result as the product of count[x], k, and the sum of the prefSum values within the range (nx - x) and nx modulo mod. The final result is obtained by summing these products modulo mod for every possible pair of numbers in the input array.

The time complexity of the algorithm is O(maxVal^2) where maxVal is the maximum value in the input array nums. The space complexity is O(maxVal) due to the count and prefSum arrays.

## A solution in Python

```python
def sum_of_floored_pairs(nums):
    mod = 10**9 + 7
    max_val = max(nums)
    count = [0] * (max_val + 1)
    pref_sum = [0] * (max_val + 1)

    for num in nums:
        count[num] += 1

    for i in range(1, max_val + 1):
        pref_sum[i] = (pref_sum[i - 1] + count[i]) % mod

    res = 0
    for x in range(1, max_val + 1):
        nx = x
        k = 1
        while nx <= max_val:
            res = (res + ((pref_sum[nx] - pref_sum[nx - x] + mod) % mod) * k % mod * count[x] % mod) % mod
            k += 1
            nx += x
    return res
```
The algorithm first calculates the maximum value present in the array named maxVal. Then it initializes two other arrays: count and prefSum of size (maxVal + 1). The count array stores the frequency count of numbers in the input array, and prefSum stores the prefix sum of count array modulo mod (10^9 + 7).

The main logic is implemented using nested loops. The outer loop iterates through each unique number (x) in the input array, and the inner loop generates multiples of that number (nx) within the range of the maximum value. For each nx, calculate the result as the product of count[x], k, and the sum of the prefSum values within the range (nx - x) and nx modulo mod. The final result is obtained by summing these products modulo mod for every possible pair of numbers in the input array.

The time complexity of the algorithm is O(maxVal^2) where maxVal is the maximum value in the input array nums. The space complexity is O(maxVal) due to the count and prefSum arrays.

## A solution in Javascript

```javascript
function sumOfFlooredPairs(nums) {
    const mod = 1e9 + 7;
    const maxVal = Math.max(...nums);
    const count = Array(maxVal + 1).fill(0);
    const prefSum = Array(maxVal + 1).fill(0);

    for (let num of nums) {
        count[num]++;
    }

    for (let i = 1; i <= maxVal; i++) {
        prefSum[i] = (prefSum[i - 1] + count[i]) % mod;
    }

    let res = 0;
    for (let x = 1; x <= maxVal; x++) {
        for (let k = 1, nx = x; nx <= maxVal; k++, nx += x) {
            res = (res + ((prefSum[nx] - prefSum[nx - x] + mod) % mod) * k % mod * count[x] % mod) % mod;
        }
    }
    return res;
}
```
The algorithm first calculates the maximum value present in the array named maxVal. Then it initializes two other arrays: count and prefSum of size (maxVal + 1). The count array stores the frequency count of numbers in the input array, and prefSum stores the prefix sum of count array modulo mod (10^9 + 7).

The main logic is implemented using nested loops. The outer loop iterates through each unique number (x) in the input array, and the inner loop generates multiples of that number (nx) within the range of the maximum value. For each nx, calculate the result as the product of count[x], k, and the sum of the prefSum values within the range (nx - x) and nx modulo mod. The final result is obtained by summing these products modulo mod for every possible pair of numbers in the input array.

The time complexity of the algorithm is O(maxVal^2) where maxVal is the maximum value in the input array nums. The space complexity is O(maxVal) due to the count and prefSum arrays.


# Break a Palindrome

- slug: break-a-palindrome
- difficulty: Medium

Given a palindromic string of lowercase English letters `palindrome`, replace **exactly one** character with any lowercase English letter so that the resulting string is **not** a palindrome and that it is the **lexicographically smallest** one possible.

Return _the resulting string. If there is no way to replace a character to make it not a palindrome, return an **empty string**._

A string `a` is lexicographically smaller than a string `b` (of the same length) if in the first position where `a` and `b` differ, `a` has a character strictly smaller than the corresponding character in `b`. For example, `"abcc "` is lexicographically smaller than `"abcd "` because the first position they differ is at the fourth character, and `'c'` is smaller than `'d'`.

**Example 1:**

**Input:** palindrome =  "abccba "
**Output:**  "aaccba "
**Explanation:** There are many ways to make  "abccba " not a palindrome, such as  "zbccba ",  "aaccba ", and  "abacba ".
Of all the ways,  "aaccba " is the lexicographically smallest.

**Example 2:**

**Input:** palindrome =  "a "
**Output:**  " "
**Explanation:** There is no way to replace a single character to make  "a " not a palindrome, so return an empty string.

**Constraints:**

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

## A solution in Java

```java
public String breakPalindrome(String palindrome) {
    int length = palindrome.length();
    if (length == 1) return "";

    char[] chars = palindrome.toCharArray();
    for (int i = 0; i < length / 2; i++) {
        if (chars[i] != 'a') {
            chars[i] = 'a';
            return String.valueOf(chars);
        }
    }

    chars[length - 1] = 'b';
    return String.valueOf(chars);
}
```
To find the lexicographically smallest non-palindromic string, we first check if the length of the input string is 1. If it is, we return an empty string since we can't change a single character to make it a non-palindrome. Otherwise, we iterate through the first half of the string and look for any character not equal to `'a'`. If we find one, we change it to `'a'` and return the new string.

If we reach the end of the loop without finding a non-`'a'` character, it means that the string is composed of only `'a'` characters. In this case, we can change the last character to `'b'` to create a non-palindrome, and return the result. This ensures the lexicographically smallest string since it only changes one character and does so as early in the string as possible.

## A solution in C++

```cpp
#include <string>

std::string breakPalindrome(std::string palindrome) {
    int length = palindrome.length();
    if (length == 1) return "";

    for (int i = 0; i < length / 2; i++) {
        if (palindrome[i] != 'a') {
            palindrome[i] = 'a';
            return palindrome;
        }
    }

    palindrome[length - 1] = 'b';
    return palindrome;
}
```
To find the lexicographically smallest non-palindromic string, we first check if the length of the input string is 1. If it is, we return an empty string since we can't change a single character to make it a non-palindrome. Otherwise, we iterate through the first half of the string and look for any character not equal to `'a'`. If we find one, we change it to `'a'` and return the new string.

If we reach the end of the loop without finding a non-`'a'` character, it means that the string is composed of only `'a'` characters. In this case, we can change the last character to `'b'` to create a non-palindrome, and return the result. This ensures the lexicographically smallest string since it only changes one character and does so as early in the string as possible.

## A solution in Python

```python
def breakPalindrome(palindrome: str) -> str:
    length = len(palindrome)
    if length == 1:
        return ""

    chars = list(palindrome)
    for i in range(length // 2):
        if chars[i] != 'a':
            chars[i] = 'a'
            return "".join(chars)

    chars[length - 1] = 'b'
    return "".join(chars)
```
To find the lexicographically smallest non-palindromic string, we first check if the length of the input string is 1. If it is, we return an empty string since we can't change a single character to make it a non-palindrome. Otherwise, we iterate through the first half of the string and look for any character not equal to `'a'`. If we find one, we change it to `'a'` and return the new string.

If we reach the end of the loop without finding a non-`'a'` character, it means that the string is composed of only `'a'` characters. In this case, we can change the last character to `'b'` to create a non-palindrome, and return the result. This ensures the lexicographically smallest string since it only changes one character and does so as early in the string as possible.

## A solution in Javascript

```javascript
function breakPalindrome(palindrome) {
    const length = palindrome.length;
    if (length === 1) return "";

    let chars = palindrome.split("");
    for (let i = 0; i < Math.floor(length / 2); i++) {
        if (chars[i] !== 'a') {
            chars[i] = 'a';
            return chars.join("");
        }
    }

    chars[length - 1] = 'b';
    return chars.join("");
}
```
To find the lexicographically smallest non-palindromic string, we first check if the length of the input string is 1. If it is, we return an empty string since we can't change a single character to make it a non-palindrome. Otherwise, we iterate through the first half of the string and look for any character not equal to `'a'`. If we find one, we change it to `'a'` and return the new string.

If we reach the end of the loop without finding a non-`'a'` character, it means that the string is composed of only `'a'` characters. In this case, we can change the last character to `'b'` to create a non-palindrome, and return the result. This ensures the lexicographically smallest string since it only changes one character and does so as early in the string as possible.


# Sort the Matrix Diagonally

- slug: sort-the-matrix-diagonally
- difficulty: Medium

A **matrix diagonal** is a diagonal line of cells starting from some cell in either the topmost row or leftmost column and going in the bottom-right direction until reaching the matrix's end. For example, the **matrix diagonal** starting from `mat[2][0]`, where `mat` is a `6 x 3` matrix, includes cells `mat[2][0]`, `mat[3][1]`, and `mat[4][2]`.

Given an `m x n` matrix `mat` of integers, sort each **matrix diagonal** in ascending order and return _the resulting matrix_.

**Example 1:**

**Input:** mat = \[\[3,3,1,1\],\[2,2,1,2\],\[1,1,1,2\]\]
**Output:** \[\[1,1,1,1\],\[1,2,2,2\],\[1,2,3,3\]\]

**Example 2:**

**Input:** mat = \[\[11,25,66,1,69,7\],\[23,55,17,45,15,52\],\[75,31,36,44,58,8\],\[22,27,33,25,68,4\],\[84,28,14,11,5,50\]\]
**Output:** \[\[5,17,4,1,52,7\],\[11,11,25,45,8,69\],\[14,23,25,44,58,15\],\[22,27,31,36,50,66\],\[84,28,75,33,55,68\]\]

**Constraints:**

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

## A solution in Java

```java
public int minCostToMoveChips(int[] position) {
    int evenCount = 0, oddCount = 0;
    for (int i : position) {
        if (i % 2 == 0)
            evenCount++;
        else
            oddCount++;
    }
    return Math.min(evenCount, oddCount);
}
```
The strategy to minimize the cost is to move all the chips to the position where most chips are already placed, either in an even or odd position. In each step, we can move a chip by 2 positions at no cost. So we count the number of chips on even positions and the number of chips on odd positions. The minimum cost is the minimum between the counts of even and odd positioned chips, as we can move the smaller set of chips to the bigger set with minimum operations.

## A solution in C++

```cpp
int minCostToMoveChips(vector<int>& position) {
    int evenCount = 0, oddCount = 0;
    for (int i : position) {
        if (i % 2 == 0)
            evenCount++;
        else
            oddCount++;
    }
    return min(evenCount, oddCount);
}
```
The strategy to minimize the cost is to move all the chips to the position where most chips are already placed, either in an even or odd position. In each step, we can move a chip by 2 positions at no cost. So we count the number of chips on even positions and the number of chips on odd positions. The minimum cost is the minimum between the counts of even and odd positioned chips, as we can move the smaller set of chips to the bigger set with minimum operations.

## A solution in Python

```python
def minCostToMoveChips(position):
    evenCount, oddCount = 0, 0
    for i in position:
        if i % 2 == 0:
            evenCount += 1
        else:
            oddCount += 1
    return min(evenCount, oddCount)
```
The strategy to minimize the cost is to move all the chips to the position where most chips are already placed, either in an even or odd position. In each step, we can move a chip by 2 positions at no cost. So we count the number of chips on even positions and the number of chips on odd positions. The minimum cost is the minimum between the counts of even and odd positioned chips, as we can move the smaller set of chips to the bigger set with minimum operations.

## A solution in Javascript

```javascript
function minCostToMoveChips(position) {
    let evenCount = 0, oddCount = 0;
    for (let i of position) {
        if (i % 2 === 0)
            evenCount++;
        else
            oddCount++;
    }
    return Math.min(evenCount, oddCount);
}
```
The strategy to minimize the cost is to move all the chips to the position where most chips are already placed, either in an even or odd position. In each step, we can move a chip by 2 positions at no cost. So we count the number of chips on even positions and the number of chips on odd positions. The minimum cost is the minimum between the counts of even and odd positioned chips, as we can move the smaller set of chips to the bigger set with minimum operations.


# Reverse Subarray To Maximize Array Value

- slug: reverse-subarray-to-maximize-array-value
- difficulty: Hard

You are given an integer array `nums`. The _value_ of this array is defined as the sum of `|nums[i] - nums[i + 1]|` for all `0 <= i < nums.length - 1`.

You are allowed to select any subarray of the given array and reverse it. You can perform this operation **only once**.

Find maximum possible value of the final array.

**Example 1:**

**Input:** nums = \[2,3,1,5,4\]
**Output:** 10
**Explanation:** By reversing the subarray \[3,1,5\] the array becomes \[2,5,1,3,4\] whose value is 10.

**Example 2:**

**Input:** nums = \[2,4,9,24,2,1,10\]
**Output:** 68

**Constraints:**

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

## A solution in Java

```java
public int longestSubsequence(int[] arr, int difference) {
    HashMap<Integer, Integer> dp = new HashMap<>();
    int maxLength = 0;
    for (int num : arr) {
        dp.put(num, dp.getOrDefault(num - difference, 0) + 1);
        maxLength = Math.max(maxLength, dp.get(num));
    }
    return maxLength;
}
```
The algorithm creates a hashmap to store the maximum length of the arithmetic subsequence with difference "difference" ending at each element of the array. We iterate through each element in the array, calculate the length of the arithmetic subsequence ending at the current number, and update the hashmap accordingly. During the loop, we also keep track of the maximum length of the arithmetic subsequence seen so far. At the end of the loop, we return the maxLength.

The time complexity of this algorithm is O(n), where n is the length of the array "arr".

## A solution in C++

```cpp
int longestSubsequence(vector<int>& arr, int difference) {
    unordered_map<int, int> dp;
    int maxLength = 0;
    for (int num : arr) {
        dp[num] = dp[num - difference] + 1;
        maxLength = max(maxLength, dp[num]);
    }
    return maxLength;
}
```
The algorithm creates a hashmap to store the maximum length of the arithmetic subsequence with difference "difference" ending at each element of the array. We iterate through each element in the array, calculate the length of the arithmetic subsequence ending at the current number, and update the hashmap accordingly. During the loop, we also keep track of the maximum length of the arithmetic subsequence seen so far. At the end of the loop, we return the maxLength.

The time complexity of this algorithm is O(n), where n is the length of the array "arr".

## A solution in Python

```python
def longestSubsequence(arr, difference):
    dp = {}
    maxLength = 0
    for num in arr:
        dp[num] = dp.get(num - difference, 0) + 1
        maxLength = max(maxLength, dp[num])
    return maxLength
```
The algorithm creates a hashmap to store the maximum length of the arithmetic subsequence with difference "difference" ending at each element of the array. We iterate through each element in the array, calculate the length of the arithmetic subsequence ending at the current number, and update the hashmap accordingly. During the loop, we also keep track of the maximum length of the arithmetic subsequence seen so far. At the end of the loop, we return the maxLength.

The time complexity of this algorithm is O(n), where n is the length of the array "arr".

## A solution in Javascript

```javascript
function longestSubsequence(arr, difference) {
    const dp = new Map();
    let maxLength = 0;
    for (let num of arr) {
        dp.set(num, (dp.get(num - difference) || 0) + 1);
        maxLength = Math.max(maxLength, dp.get(num));
    }
    return maxLength;
}
```
The algorithm creates a hashmap to store the maximum length of the arithmetic subsequence with difference "difference" ending at each element of the array. We iterate through each element in the array, calculate the length of the arithmetic subsequence ending at the current number, and update the hashmap accordingly. During the loop, we also keep track of the maximum length of the arithmetic subsequence seen so far. At the end of the loop, we return the maxLength.

The time complexity of this algorithm is O(n), where n is the length of the array "arr".


# Rank Transform of an Array

- slug: rank-transform-of-an-array
- difficulty: Easy

Given an array of integers `arr`, replace each element with its rank.

The rank represents how large the element is. The rank has the following rules:

*   Rank is an integer starting from 1.
*   The larger the element, the larger the rank. If two elements are equal, their rank must be the same.
*   Rank should be as small as possible.

**Example 1:**

**Input:** arr = \[40,10,20,30\]
**Output:** \[4,1,2,3\]
**Explanation**: 40 is the largest element. 10 is the smallest. 20 is the second smallest. 30 is the third smallest.

**Example 2:**

**Input:** arr = \[100,100,100\]
**Output:** \[1,1,1\]
**Explanation**: Same elements share the same rank.

**Example 3:**

**Input:** arr = \[37,12,28,9,100,56,80,5,12\]
**Output:** \[5,3,4,2,8,6,7,1,3\]

**Constraints:**

*   `0 <= arr.length <= 105`
*   `-109 <= arr[i] <= 109`

\- Every time you are in a cell you will collect all the gold in that cell. - From your position, you can walk one step to the left, right, up, or down. - You can't visit the same cell more than once. - Never visit a cell with 0 gold. - You can start and stop collecting gold from any position in the grid that has some gold.

## A solution in Java

```java
import java.util.Arrays;

public int getMaximumGold(int[][] grid) {
    int m = grid.length, n = grid[0].length, maxGold = 0;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (grid[i][j] != 0) {
                maxGold = Math.max(maxGold, getMaximumGoldHelper(grid, i, j, m, n));
            }
        }
    }
    return maxGold;
}

private int getMaximumGoldHelper(int[][] grid, int x, int y, int m, int n) {
    if (x < 0 || x >= m || y < 0 || y >= n || grid[x][y] == 0) return 0;

    int originalGold = grid[x][y];
    grid[x][y] = 0;

    int maxGold = 0;
    maxGold = Math.max(maxGold, getMaximumGoldHelper(grid, x + 1, y, m, n));
    maxGold = Math.max(maxGold, getMaximumGoldHelper(grid, x - 1, y, m, n));
    maxGold = Math.max(maxGold, getMaximumGoldHelper(grid, x, y + 1, m, n));
    maxGold = Math.max(maxGold, getMaximumGoldHelper(grid, x, y - 1, m, n));

    grid[x][y] = originalGold;
    return maxGold + originalGold;
}
```
We use a depth-first search (DFS) algorithm to calculate the maximum gold that can be collected in one DFS run, which we do starting from each cell with gold. This algorithm keeps track of the visited cells by changing the gold amount to 0 in the original grid temporarily as part of its recursive computations. As we go through the grid, we store the maximum gold found so far to be returned at the end. Note that the algorithm itself is relatively simple, but the actual implementation varies slightly between languages.

## A solution in C++

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

int getMaximumGoldHelper(vector<vector<int>> &grid, int x, int y, int m, int n) {
    if (x < 0 || x >= m || y < 0 || y >= n || grid[x][y] == 0) return 0;

    int originalGold = grid[x][y];
    grid[x][y] = 0;

    int maxGold = 0;
    maxGold = max(maxGold, getMaximumGoldHelper(grid, x + 1, y, m, n));
    maxGold = max(maxGold, getMaximumGoldHelper(grid, x - 1, y, m, n));
    maxGold = max(maxGold, getMaximumGoldHelper(grid, x, y + 1, m, n));
    maxGold = max(maxGold, getMaximumGoldHelper(grid, x, y - 1, m, n));

    grid[x][y] = originalGold;
    return maxGold + originalGold;
}

int getMaximumGold(vector<vector<int>>& grid) {
    int m = grid.size(), n = grid[0].size(), maxGold = 0;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (grid[i][j] != 0) {
                maxGold = max(maxGold, getMaximumGoldHelper(grid, i, j, m, n));
            }
        }
    }
    return maxGold;
}
```
We use a depth-first search (DFS) algorithm to calculate the maximum gold that can be collected in one DFS run, which we do starting from each cell with gold. This algorithm keeps track of the visited cells by changing the gold amount to 0 in the original grid temporarily as part of its recursive computations. As we go through the grid, we store the maximum gold found so far to be returned at the end. Note that the algorithm itself is relatively simple, but the actual implementation varies slightly between languages.

## A solution in Python

```python
def getMaximumGold(grid):
    m, n, max_gold = len(grid), len(grid[0]), 0

    def getMaximumGoldHelper(x, y):
        if not (0 <= x < m) or not (0 <= y < n) or grid[x][y] == 0:
            return 0

        original_gold = grid[x][y]
        grid[x][y] = 0

        max_gold = 0
        max_gold = max(max_gold, getMaximumGoldHelper(x + 1, y))
        max_gold = max(max_gold, getMaximumGoldHelper(x - 1, y))
        max_gold = max(max_gold, getMaximumGoldHelper(x, y + 1))
        max_gold = max(max_gold, getMaximumGoldHelper(x, y - 1))

        grid[x][y] = original_gold
        return max_gold + original_gold

    for i in range(m):
        for j in range(n):
            if grid[i][j] != 0:
                max_gold = max(max_gold, getMaximumGoldHelper(i, j))

    return max_gold
```
We use a depth-first search (DFS) algorithm to calculate the maximum gold that can be collected in one DFS run, which we do starting from each cell with gold. This algorithm keeps track of the visited cells by changing the gold amount to 0 in the original grid temporarily as part of its recursive computations. As we go through the grid, we store the maximum gold found so far to be returned at the end. Note that the algorithm itself is relatively simple, but the actual implementation varies slightly between languages.

## A solution in Javascript

```javascript
function getMaximumGold(grid) {
    let m = grid.length, n = grid[0].length, maxGold = 0;

    const getMaximumGoldHelper = (x, y) => {
        if (x < 0 || x >= m || y < 0 || y >= n || grid[x][y] === 0) return 0;

        let originalGold = grid[x][y];
        grid[x][y] = 0;

        let maxGold = 0;
        maxGold = Math.max(maxGold, getMaximumGoldHelper(x + 1, y));
        maxGold = Math.max(maxGold, getMaximumGoldHelper(x - 1, y));
        maxGold = Math.max(maxGold, getMaximumGoldHelper(x, y + 1));
        maxGold = Math.max(maxGold, getMaximumGoldHelper(x, y - 1));

        grid[x][y] = originalGold;
        return maxGold + originalGold;
    };

    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            if (grid[i][j] !== 0) {
                maxGold = Math.max(maxGold, getMaximumGoldHelper(i, j));
            }
        }
    }
    return maxGold;
}
```
We use a depth-first search (DFS) algorithm to calculate the maximum gold that can be collected in one DFS run, which we do starting from each cell with gold. This algorithm keeps track of the visited cells by changing the gold amount to 0 in the original grid temporarily as part of its recursive computations. As we go through the grid, we store the maximum gold found so far to be returned at the end. Note that the algorithm itself is relatively simple, but the actual implementation varies slightly between languages.


# Remove Palindromic Subsequences

- slug: remove-palindromic-subsequences
- difficulty: Easy

You are given a string `s` consisting **only** of letters `'a'` and `'b'`. In a single step you can remove one **palindromic subsequence** from `s`.

Return _the **minimum** number of steps to make the given string empty_.

A string is a **subsequence** of a given string if it is generated by deleting some characters of a given string without changing its order. Note that a subsequence does **not** necessarily need to be contiguous.

A string is called **palindrome** if is one that reads the same backward as well as forward.

**Example 1:**

**Input:** s =  "ababa "
**Output:** 1
**Explanation:** s is already a palindrome, so its entirety can be removed in a single step.

**Example 2:**

**Input:** s =  "abb "
**Output:** 2
**Explanation:**  "abb " ->  "bb " ->  " ".
Remove palindromic subsequence  "a " then  "bb ".

**Example 3:**

**Input:** s =  "baabb "
**Output:** 2
**Explanation:**  "baabb " ->  "b " ->  " ".
Remove palindromic subsequence  "baab " then  "b ".

**Constraints:**

*   `1 <= s.length <= 1000`
*   `s[i]` is either `'a'` or `'b'`.

## A solution in Java

```java
public int countStrings(int n) {
    int mod = 1000000007;
    long a = 1, b = 1;
    for (int i = 0; i < n; i++) {
        a = (a * 2) % mod;
        b = (b * 3) % mod;
    }
    return (int)((b - a + mod) % mod);
}
```
The problem requires us to find the total number of valid strings of the given length based on certain rules. To solve this, we calculate:

1. `a`: Count of all strings of length n using just 'a'. Each position can be either 'a' or not 'a', so there are 2 possibilities for each position. Therefore, the count is `2^n`.
2. `b`: Count of all strings of length n using only 'a' and 'b'. Any position can be either 'a', 'b', or neither 'a' nor 'b', so there are 3 possibilities for each position. Therefore, the count is `3^n`.

As we have already counted the strings with all positions either 'a' or not 'a' in step one, we need to subtract these duplicates. Thus, the answer is the difference (`b - a`) plus the modulo value to make it positive, and the final result is calculated using `% mod`.

## A solution in C++

```cpp
int countStrings(int n) {
    const int mod = 1e9 + 7;
    long long a = 1, b = 1;
    for (int i = 0; i < n; ++i) {
        a = (a * 2) % mod;
        b = (b * 3) % mod;
    }
    return (b - a + mod) % mod;
}
```
The problem requires us to find the total number of valid strings of the given length based on certain rules. To solve this, we calculate:

1. `a`: Count of all strings of length n using just 'a'. Each position can be either 'a' or not 'a', so there are 2 possibilities for each position. Therefore, the count is `2^n`.
2. `b`: Count of all strings of length n using only 'a' and 'b'. Any position can be either 'a', 'b', or neither 'a' nor 'b', so there are 3 possibilities for each position. Therefore, the count is `3^n`.

As we have already counted the strings with all positions either 'a' or not 'a' in step one, we need to subtract these duplicates. Thus, the answer is the difference (`b - a`) plus the modulo value to make it positive, and the final result is calculated using `% mod`.

## A solution in Python

```python
def countStrings(n):
    mod = 10**9 + 7
    a, b = 1, 1
    for _ in range(n):
        a = (a * 2) % mod
        b = (b * 3) % mod
    return (b - a + mod) % mod
```
The problem requires us to find the total number of valid strings of the given length based on certain rules. To solve this, we calculate:

1. `a`: Count of all strings of length n using just 'a'. Each position can be either 'a' or not 'a', so there are 2 possibilities for each position. Therefore, the count is `2^n`.
2. `b`: Count of all strings of length n using only 'a' and 'b'. Any position can be either 'a', 'b', or neither 'a' nor 'b', so there are 3 possibilities for each position. Therefore, the count is `3^n`.

As we have already counted the strings with all positions either 'a' or not 'a' in step one, we need to subtract these duplicates. Thus, the answer is the difference (`b - a`) plus the modulo value to make it positive, and the final result is calculated using `% mod`.

## A solution in Javascript

```javascript
function countStrings(n) {
    const mod = 1e9 + 7;
    let a = 1, b = 1;
    for (let i = 0; i < n; i++) {
        a = (a * 2) % mod;
        b = (b * 3) % mod;
    }
    return (b - a + mod) % mod;
}
```
The problem requires us to find the total number of valid strings of the given length based on certain rules. To solve this, we calculate:

1. `a`: Count of all strings of length n using just 'a'. Each position can be either 'a' or not 'a', so there are 2 possibilities for each position. Therefore, the count is `2^n`.
2. `b`: Count of all strings of length n using only 'a' and 'b'. Any position can be either 'a', 'b', or neither 'a' nor 'b', so there are 3 possibilities for each position. Therefore, the count is `3^n`.

As we have already counted the strings with all positions either 'a' or not 'a' in step one, we need to subtract these duplicates. Thus, the answer is the difference (`b - a`) plus the modulo value to make it positive, and the final result is calculated using `% mod`.


# Filter Restaurants by Vegan-Friendly, Price and Distance

- slug: filter-restaurants-by-vegan-friendly-price-and-distance
- difficulty: Medium

Given the array `restaurants` where `restaurants[i] = [idi, ratingi, veganFriendlyi, pricei, distancei]`. You have to filter the restaurants using three filters.

The `veganFriendly` filter will be either _true_ (meaning you should only include restaurants with `veganFriendlyi` set to true) or _false_ (meaning you can include any restaurant). In addition, you have the filters `maxPrice` and `maxDistance` which are the maximum value for price and distance of restaurants you should consider respectively.

Return the array of restaurant _**IDs**_ after filtering, ordered by **rating** from highest to lowest. For restaurants with the same rating, order them by _**id**_ from highest to lowest. For simplicity `veganFriendlyi` and `veganFriendly` take value _1_ when it is _true_, and _0_ when it is _false_.

**Example 1:**

**Input:** restaurants = \[\[1,4,1,40,10\],\[2,8,0,50,5\],\[3,8,1,30,4\],\[4,10,0,10,3\],\[5,1,1,15,1\]\], veganFriendly = 1, maxPrice = 50, maxDistance = 10
**Output:** \[3,1,5\]
**Explanation:**
The restaurants are:
Restaurant 1 \[id=1, rating=4, veganFriendly=1, price=40, distance=10\]
Restaurant 2 \[id=2, rating=8, veganFriendly=0, price=50, distance=5\]
Restaurant 3 \[id=3, rating=8, veganFriendly=1, price=30, distance=4\]
Restaurant 4 \[id=4, rating=10, veganFriendly=0, price=10, distance=3\]
Restaurant 5 \[id=5, rating=1, veganFriendly=1, price=15, distance=1\]
After filter restaurants with veganFriendly = 1, maxPrice = 50 and maxDistance = 10 we have restaurant 3, restaurant 1 and restaurant 5 (ordered by rating from highest to lowest).

**Example 2:**

**Input:** restaurants = \[\[1,4,1,40,10\],\[2,8,0,50,5\],\[3,8,1,30,4\],\[4,10,0,10,3\],\[5,1,1,15,1\]\], veganFriendly = 0, maxPrice = 50, maxDistance = 10
**Output:** \[4,3,2,1,5\]
**Explanation:** The restaurants are the same as in example 1, but in this case the filter veganFriendly = 0, therefore all restaurants are considered.

**Example 3:**

**Input:** restaurants = \[\[1,4,1,40,10\],\[2,8,0,50,5\],\[3,8,1,30,4\],\[4,10,0,10,3\],\[5,1,1,15,1\]\], veganFriendly = 0, maxPrice = 30, maxDistance = 3
**Output:** \[4,5\]

**Constraints:**

*   `1 <= restaurants.length <= 10^4`
*   `restaurants[i].length == 5`
*   `1 <= idi, ratingi, pricei, distancei <= 10^5`
*   `1 <= maxPrice, maxDistance <= 10^5`
*   `veganFriendlyi` and `veganFriendly` are 0 or 1.
*   All `idi` are distinct.

## A solution in Java

```java
import java.util.Arrays;

public int[] sortBasedOnMapping(int[] mapping, int[] nums) {
    Integer[] boxedNums = Arrays.stream(nums).boxed().toArray(Integer[]::new);
    Arrays.sort(boxedNums, (a, b) -> {
        String aStr = Integer.toString(a);
        String bStr = Integer.toString(b);
        for (int i = 0; i < aStr.length(); i++)
            aStr = aStr.substring(0, i) + mapping[aStr.charAt(i) - '0'] + aStr.substring(i + 1);
        for (int i = 0; i < bStr.length(); i++)
            bStr = bStr.substring(0, i) + mapping[bStr.charAt(i) - '0'] + bStr.substring(i + 1);
        return aStr.compareTo(bStr);
    });
    return Arrays.stream(boxedNums).mapToInt(Integer::intValue).toArray();
}
```
The algorithm consists of the following steps:
1. Define a function to map the given number based on the mapping rules provided.
2. For each number in the array, calculate and store its mapped value while maintaining the original number.
3. Sort the numbers based on their mapped values.
4. Return the sorted array.

In each language implementation, we start by defining a function to calculate the mapped value of a given number. We then use a sorting function provided by the language and pass a custom comparison function to sort the array based on the mapped values. Finally, we return the sorted array.

## A solution in C++

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

std::vector<int> sortBasedOnMapping(std::vector<int>& mapping, std::vector<int>& nums) {
    std::sort(nums.begin(), nums.end(), [&](int a, int b) {
        std::string aStr = std::to_string(a);
        std::string bStr = std::to_string(b);
        for (char &c : aStr) c = '0' + mapping[c - '0'];
        for (char &c : bStr) c = '0' + mapping[c - '0'];
        return aStr < bStr;
    });
    return nums;
}
```
The algorithm consists of the following steps:
1. Define a function to map the given number based on the mapping rules provided.
2. For each number in the array, calculate and store its mapped value while maintaining the original number.
3. Sort the numbers based on their mapped values.
4. Return the sorted array.

In each language implementation, we start by defining a function to calculate the mapped value of a given number. We then use a sorting function provided by the language and pass a custom comparison function to sort the array based on the mapped values. Finally, we return the sorted array.

## A solution in Python

```python
def sort_based_on_mapping(mapping, nums):
    def mapped_value(num):
        return int(''.join(str(mapping[int(d)]) for d in str(num)))

    return sorted(nums, key=mapped_value)
```
The algorithm consists of the following steps:
1. Define a function to map the given number based on the mapping rules provided.
2. For each number in the array, calculate and store its mapped value while maintaining the original number.
3. Sort the numbers based on their mapped values.
4. Return the sorted array.

In each language implementation, we start by defining a function to calculate the mapped value of a given number. We then use a sorting function provided by the language and pass a custom comparison function to sort the array based on the mapped values. Finally, we return the sorted array.

## A solution in Javascript

```javascript
function sortBasedOnMapping(mapping, nums) {
    const mappedValue = num => {
        return parseInt([...num.toString()].map(d => mapping[parseInt(d)]).join(''));
    };

    return nums.sort((a, b) => mappedValue(a) - mappedValue(b));
}
```
The algorithm consists of the following steps:
1. Define a function to map the given number based on the mapping rules provided.
2. For each number in the array, calculate and store its mapped value while maintaining the original number.
3. Sort the numbers based on their mapped values.
4. Return the sorted array.

In each language implementation, we start by defining a function to calculate the mapped value of a given number. We then use a sorting function provided by the language and pass a custom comparison function to sort the array based on the mapped values. Finally, we return the sorted array.


# Find the City With the Smallest Number of Neighbors at a Threshold Distance

- slug: find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance
- difficulty: Medium

There are `n` cities numbered from `0` to `n-1`. Given the array `edges` where `edges[i] = [fromi, toi, weighti]` represents a bidirectional and weighted edge between cities `fromi` and `toi`, and given the integer `distanceThreshold`.

Return the city with the smallest number of cities that are reachable through some path and whose distance is **at most** `distanceThreshold`, If there are multiple such cities, return the city with the greatest number.

Notice that the distance of a path connecting cities _**i**_ and _**j**_ is equal to the sum of the edges' weights along that path.

**Example 1:**

**Input:** n = 4, edges = \[\[0,1,3\],\[1,2,1\],\[1,3,4\],\[2,3,1\]\], distanceThreshold = 4
**Output:** 3
**Explanation:** The figure above describes the graph.
The neighboring cities at a distanceThreshold = 4 for each city are:
City 0 -> \[City 1, City 2\]
City 1 -> \[City 0, City 2, City 3\]
City 2 -> \[City 0, City 1, City 3\]
City 3 -> \[City 1, City 2\]
Cities 0 and 3 have 2 neighboring cities at a distanceThreshold = 4, but we have to return city 3 since it has the greatest number.

**Example 2:**

**Input:** n = 5, edges = \[\[0,1,2\],\[0,4,8\],\[1,2,3\],\[1,4,2\],\[2,3,1\],\[3,4,1\]\], distanceThreshold = 2
**Output:** 0
**Explanation:** The figure above describes the graph.
The neighboring cities at a distanceThreshold = 2 for each city are:
City 0 -> \[City 1\]
City 1 -> \[City 0, City 4\]
City 2 -> \[City 3, City 4\]
City 3 -> \[City 2, City 4\]
City 4 -> \[City 1, City 2, City 3\]
The city 0 has 1 neighboring city at a distanceThreshold = 2.

**Constraints:**

*   `2 <= n <= 100`
*   `1 <= edges.length <= n * (n - 1) / 2`
*   `edges[i].length == 3`
*   `0 <= fromi < toi < n`
*   `1 <= weighti, distanceThreshold <= 10^4`
*   All pairs `(fromi, toi)` are distinct.

## A solution in Java

```java
public int findTheCity(int n, int[][] edges, int distanceThreshold) {
    int[][] distance = new int[n][n];

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            distance[i][j] = 10001;
        }
    }

    for (int[] edge : edges) {
        distance[edge[0]][edge[1]] = edge[2];
        distance[edge[1]][edge[0]] = edge[2];
    }

    for (int i = 0; i < n; i++) distance[i][i] = 0;

    for (int k = 0; k < n; k++) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                distance[i][j] = Math.min(distance[i][j], distance[i][k] + distance[k][j]);
            }
        }
    }

    int res = 0, minReachable = n;
    for (int i = 0; i < n; i++) {
        int reachable = 0;
        for (int j = 0; j < n; j++) {
            if (distance[i][j] <= distanceThreshold) reachable++;
        }
        if (reachable <= minReachable) {
            minReachable = reachable;
            res = i;
        }
    }
    return res;
}
```
The problem can be solved using Floyd-Warshall algorithm for finding shortest paths between all pairs of cities. First, we initialize an `n x n` distance matrix with a value larger than the maximum distance, and set the distance of each edge given in the input. The initial distance from each city to themselves is set to 0.

Then we iteratively update the distance matrix using the Floyd-Warshall algorithm. To do this, we iterate over all pairs of cities (i, j), and for each pair, check if the distance through an additional city k is shorter than the current distance between i and j. If yes, we update the distance matrix entry to the shorter distance.

After the algorithm is done, we iterate through each city and count the number of cities that are reachable within the distance threshold. If the number of reachable cities is smaller than or equal to the current smallest count, we update the smallest count and set the resulting city index to the current city index.

Finally, we return the result city index.

## A solution in C++

```cpp
#include <vector>
#include <limits>

int findTheCity(int n, std::vector<std::vector<int>>& edges, int distanceThreshold) {
    std::vector<std::vector<int>> distance(n, std::vector<int>(n, 1e5));
    for (const auto& edge : edges) {
        distance[edge[0]][edge[1]] = edge[2];
        distance[edge[1]][edge[0]] = edge[2];
    }

    for (int i = 0; i < n; i++) distance[i][i] = 0;

    for (int k = 0; k < n; k++) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                distance[i][j] = std::min(distance[i][j], distance[i][k] + distance[k][j]);
            }
        }
    }

    int res = 0, minReachable = n;
    for (int i = 0; i < n; i++) {
        int reachable = 0;
        for (int j = 0; j < n; j++) {
            if (distance[i][j] <= distanceThreshold) reachable++;
        }
        if (reachable <= minReachable) {
            minReachable = reachable;
            res = i;
        }
    }
    return res;
}
```
The problem can be solved using Floyd-Warshall algorithm for finding shortest paths between all pairs of cities. First, we initialize an `n x n` distance matrix with a value larger than the maximum distance, and set the distance of each edge given in the input. The initial distance from each city to themselves is set to 0.

Then we iteratively update the distance matrix using the Floyd-Warshall algorithm. To do this, we iterate over all pairs of cities (i, j), and for each pair, check if the distance through an additional city k is shorter than the current distance between i and j. If yes, we update the distance matrix entry to the shorter distance.

After the algorithm is done, we iterate through each city and count the number of cities that are reachable within the distance threshold. If the number of reachable cities is smaller than or equal to the current smallest count, we update the smallest count and set the resulting city index to the current city index.

Finally, we return the result city index.

## A solution in Python

```python
def findTheCity(n, edges, distanceThreshold):
    distance = [[1e5] * n for _ in range(n)]

    for edge in edges:
        distance[edge[0]][edge[1]] = edge[2]
        distance[edge[1]][edge[0]] = edge[2]

    for i in range(n):
        distance[i][i] = 0

    for k in range(n):
        for i in range(n):
            for j in range(n):
                distance[i][j] = min(distance[i][j], distance[i][k] + distance[k][j])

    res, minReachable = 0, n
    for i in range(n):
        reachable = sum(1 for j in range(n) if distance[i][j] <= distanceThreshold)
        if reachable <= minReachable:
            minReachable = reachable
            res = i
    return res
```
The problem can be solved using Floyd-Warshall algorithm for finding shortest paths between all pairs of cities. First, we initialize an `n x n` distance matrix with a value larger than the maximum distance, and set the distance of each edge given in the input. The initial distance from each city to themselves is set to 0.

Then we iteratively update the distance matrix using the Floyd-Warshall algorithm. To do this, we iterate over all pairs of cities (i, j), and for each pair, check if the distance through an additional city k is shorter than the current distance between i and j. If yes, we update the distance matrix entry to the shorter distance.

After the algorithm is done, we iterate through each city and count the number of cities that are reachable within the distance threshold. If the number of reachable cities is smaller than or equal to the current smallest count, we update the smallest count and set the resulting city index to the current city index.

Finally, we return the result city index.

## A solution in Javascript

```javascript
function findTheCity(n, edges, distanceThreshold) {
    const distance = Array.from({ length: n }, () => Array(n).fill(10001));

    for (const edge of edges) {
        distance[edge[0]][edge[1]] = edge[2];
        distance[edge[1]][edge[0]] = edge[2];
    }

    for (let i = 0; i < n; i++) distance[i][i] = 0;

    for (let k = 0; k < n; k++) {
        for (let i = 0; i < n; i++) {
            for (let j = 0; j < n; j++) {
                distance[i][j] = Math.min(distance[i][j], distance[i][k] + distance[k][j]);
            }
        }
    }

    let res = 0, minReachable = n;
    for (let i = 0; i < n; i++) {
        let reachable = 0;
        for (let j = 0; j < n; j++) {
            if (distance[i][j] <= distanceThreshold) reachable++;
        }
        if (reachable <= minReachable) {
            minReachable = reachable;
            res = i;
        }
    }
    return res;
}
```
The problem can be solved using Floyd-Warshall algorithm for finding shortest paths between all pairs of cities. First, we initialize an `n x n` distance matrix with a value larger than the maximum distance, and set the distance of each edge given in the input. The initial distance from each city to themselves is set to 0.

Then we iteratively update the distance matrix using the Floyd-Warshall algorithm. To do this, we iterate over all pairs of cities (i, j), and for each pair, check if the distance through an additional city k is shorter than the current distance between i and j. If yes, we update the distance matrix entry to the shorter distance.

After the algorithm is done, we iterate through each city and count the number of cities that are reachable within the distance threshold. If the number of reachable cities is smaller than or equal to the current smallest count, we update the smallest count and set the resulting city index to the current city index.

Finally, we return the result city index.


# Minimum Difficulty of a Job Schedule

- slug: minimum-difficulty-of-a-job-schedule
- difficulty: Hard

You want to schedule a list of jobs in `d` days. Jobs are dependent (i.e To work on the `ith` job, you have to finish all the jobs `j` where `0 <= j < i`).

You have to finish **at least** one task every day. The difficulty of a job schedule is the sum of difficulties of each day of the `d` days. The difficulty of a day is the maximum difficulty of a job done on that day.

You are given an integer array `jobDifficulty` and an integer `d`. The difficulty of the `ith` job is `jobDifficulty[i]`.

Return _the minimum difficulty of a job schedule_. If you cannot find a schedule for the jobs return `-1`.

**Example 1:**

**Input:** jobDifficulty = \[6,5,4,3,2,1\], d = 2
**Output:** 7
**Explanation:** First day you can finish the first 5 jobs, total difficulty = 6.
Second day you can finish the last job, total difficulty = 1.
The difficulty of the schedule = 6 + 1 = 7

**Example 2:**

**Input:** jobDifficulty = \[9,9,9\], d = 4
**Output:** -1
**Explanation:** If you finish a job per day you will still have a free day. you cannot find a schedule for the given jobs.

**Example 3:**

**Input:** jobDifficulty = \[1,1,1\], d = 3
**Output:** 3
**Explanation:** The schedule is one job per day. total difficulty will be 3.

**Constraints:**

*   `1 <= jobDifficulty.length <= 300`
*   `0 <= jobDifficulty[i] <= 1000`
*   `1 <= d <= 10`

## A solution in Java

```java
public int maxCandies(int[] candies, int k) {
    int left = 1;
    int right = 0;

    for (int candy : candies) {
        right = Math.max(right, candy);
    }

    while (left <= right) {
        int mid = left + (right - left) / 2;
        int count = 0;
        for (int candy : candies) {
            count += candy / mid;
        }
        if (count >= k) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return right;
}
```
We can use binary search to find the maximum number of candies. Initialize two pointers `left` and `right` with values 1 and the maximum value in the candies array, respectively.

While `left` is smaller or equal to `right`, calculate the middle value `mid`, which is the current number of candies to be distributed per child. Then calculate the number of children that can be given `mid` candies by dividing each `candies[i]` by `mid` and summing the values.

If the sum is greater or equal to `k`, it means that we can give the current `mid` value of candies to `k` children or more, so we can try increasing the candy count by setting `left` to `mid + 1`. If the sum is less than `k`, it means we cannot give `mid` candies to `k` children, so we set `right` to `mid - 1`.

The binary search ends when `left` is greater than `right`, and we return the value of `right`, which is the maximum number of candies per child that can be distributed to `k` children.

## A solution in C++

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

int maxCandies(const std::vector<int>& candies, int k) {
    int left = 1;
    int right = *std::max_element(candies.begin(), candies.end());

    while (left <= right) {
        int mid = left + (right - left) / 2;
        int count = 0;
        for (int candy : candies) {
            count += candy / mid;
        }
        if (count >= k) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return right;
}
```
We can use binary search to find the maximum number of candies. Initialize two pointers `left` and `right` with values 1 and the maximum value in the candies array, respectively.

While `left` is smaller or equal to `right`, calculate the middle value `mid`, which is the current number of candies to be distributed per child. Then calculate the number of children that can be given `mid` candies by dividing each `candies[i]` by `mid` and summing the values.

If the sum is greater or equal to `k`, it means that we can give the current `mid` value of candies to `k` children or more, so we can try increasing the candy count by setting `left` to `mid + 1`. If the sum is less than `k`, it means we cannot give `mid` candies to `k` children, so we set `right` to `mid - 1`.

The binary search ends when `left` is greater than `right`, and we return the value of `right`, which is the maximum number of candies per child that can be distributed to `k` children.

## A solution in Python

```python
def max_candies(candies, k):
    left, right = 1, max(candies)

    while left <= right:
        mid = left + (right - left) // 2
        count = sum(candy // mid for candy in candies)
        if count >= k:
            left = mid + 1
        else:
            right = mid - 1
    return right
```
We can use binary search to find the maximum number of candies. Initialize two pointers `left` and `right` with values 1 and the maximum value in the candies array, respectively.

While `left` is smaller or equal to `right`, calculate the middle value `mid`, which is the current number of candies to be distributed per child. Then calculate the number of children that can be given `mid` candies by dividing each `candies[i]` by `mid` and summing the values.

If the sum is greater or equal to `k`, it means that we can give the current `mid` value of candies to `k` children or more, so we can try increasing the candy count by setting `left` to `mid + 1`. If the sum is less than `k`, it means we cannot give `mid` candies to `k` children, so we set `right` to `mid - 1`.

The binary search ends when `left` is greater than `right`, and we return the value of `right`, which is the maximum number of candies per child that can be distributed to `k` children.

## A solution in Javascript

```javascript
function maxCandies(candies, k) {
    let left = 1;
    let right = Math.max(...candies);

    while (left <= right) {
        let mid = left + Math.floor((right - left) / 2);
        let count = candies.reduce((acc, candy) => acc + Math.floor(candy / mid), 0);
        if (count >= k) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return right;
}
```
We can use binary search to find the maximum number of candies. Initialize two pointers `left` and `right` with values 1 and the maximum value in the candies array, respectively.

While `left` is smaller or equal to `right`, calculate the middle value `mid`, which is the current number of candies to be distributed per child. Then calculate the number of children that can be given `mid` candies by dividing each `candies[i]` by `mid` and summing the values.

If the sum is greater or equal to `k`, it means that we can give the current `mid` value of candies to `k` children or more, so we can try increasing the candy count by setting `left` to `mid + 1`. If the sum is less than `k`, it means we cannot give `mid` candies to `k` children, so we set `right` to `mid - 1`.

The binary search ends when `left` is greater than `right`, and we return the value of `right`, which is the maximum number of candies per child that can be distributed to `k` children.


# The K Weakest Rows in a Matrix

- slug: the-k-weakest-rows-in-a-matrix
- difficulty: Easy

You are given an `m x n` binary matrix `mat` of `1`'s (representing soldiers) and `0`'s (representing civilians). The soldiers are positioned **in front** of the civilians. That is, all the `1`'s will appear to the **left** of all the `0`'s in each row.

A row `i` is **weaker** than a row `j` if one of the following is true:

*   The number of soldiers in row `i` is less than the number of soldiers in row `j`.
*   Both rows have the same number of soldiers and `i < j`.

Return _the indices of the_ `k` _**weakest** rows in the matrix ordered from weakest to strongest_.

**Example 1:**

**Input:** mat =
\[\[1,1,0,0,0\],
 \[1,1,1,1,0\],
 \[1,0,0,0,0\],
 \[1,1,0,0,0\],
 \[1,1,1,1,1\]\],
k = 3
**Output:** \[2,0,3\]
**Explanation:**
The number of soldiers in each row is:
- Row 0: 2
- Row 1: 4
- Row 2: 1
- Row 3: 2
- Row 4: 5
The rows ordered from weakest to strongest are \[2,0,3,1,4\].

**Example 2:**

**Input:** mat =
\[\[1,0,0,0\],
 \[1,1,1,1\],
 \[1,0,0,0\],
 \[1,0,0,0\]\],
k = 2
**Output:** \[0,2\]
**Explanation:**
The number of soldiers in each row is:
- Row 0: 1
- Row 1: 4
- Row 2: 1
- Row 3: 1
The rows ordered from weakest to strongest are \[0,2,3,1\].

**Constraints:**

*   `m == mat.length`
*   `n == mat[i].length`
*   `2 <= n, m <= 100`
*   `1 <= k <= m`
*   `matrix[i][j]` is either 0 or 1.

## A solution in Java

```java
import java.util.*;

class Solution {
    public int[] kWeakestRows(int[][] mat, int k) {
        int[] result = new int[k];
        List<Integer> tmp = new ArrayList<Integer>();
        for (int i = 0; i < mat.length; i++) {
            tmp.add(i, mat[i].length - Arrays.binarySearch(mat[i], 0) - 1);
        }
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>((a, b) -> a - b);
        pq.addAll(tmp);
        for (int i = 0; i < k; i++) {
            result[i] = tmp.indexOf(pq.poll());
            tmp.set(result[i], -1);
        }
        return result;
    }
}
```
1. Count the number of soldiers in each row, and store the count along with the index of the row in a list.
2. Sort the list of pairs by the count of soldiers, and if there is a tie, use the index in ascending order.
3. Return the indices of the first k elements of the sorted list.

## A solution in C++

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

using namespace std;

vector<int> kWeakestRows(vector<vector<int>>& mat, int k) {
    vector<pair<int, int>> soldiersCount;

    for (int i = 0; i < mat.size(); ++i) {
        int cnt = count(mat[i].begin(), mat[i].end(), 1);
        soldiersCount.push_back({cnt, i});
    }

    sort(soldiersCount.begin(), soldiersCount.end());
    vector<int> result(k);
    for (int i = 0; i < k; ++i) {
        result[i] = soldiersCount[i].second;
    }
    return result;
}
```
1. Count the number of soldiers in each row, and store the count along with the index of the row in a list.
2. Sort the list of pairs by the count of soldiers, and if there is a tie, use the index in ascending order.
3. Return the indices of the first k elements of the sorted list.

## A solution in Python

```python
from typing import List

def kWeakestRows(mat: List[List[int]], k: int) -> List[int]:
    soldiers_count = [(sum(row), idx) for idx, row in enumerate(mat)]
    soldiers_count.sort()
    return [x[1] for x in soldiers_count[:k]]
```
1. Count the number of soldiers in each row, and store the count along with the index of the row in a list.
2. Sort the list of pairs by the count of soldiers, and if there is a tie, use the index in ascending order.
3. Return the indices of the first k elements of the sorted list.

## A solution in Javascript

```javascript
var kWeakestRows = function(mat, k) {
    const soldiersCount = mat.map((row, idx) => [row.filter(x => x === 1).length, idx]);
    soldiersCount.sort((a, b) => a[0] - b[0] || a[1] - b[1]);
    return soldiersCount.slice(0, k).map(x => x[1]);
};
```
1. Count the number of soldiers in each row, and store the count along with the index of the row in a list.
2. Sort the list of pairs by the count of soldiers, and if there is a tie, use the index in ascending order.
3. Return the indices of the first k elements of the sorted list.


# Reduce Array Size to The Half

- slug: reduce-array-size-to-the-half
- difficulty: Medium

You are given an integer array `arr`. You can choose a set of integers and remove all the occurrences of these integers in the array.

Return _the minimum size of the set so that **at least** half of the integers of the array are removed_.

**Example 1:**

**Input:** arr = \[3,3,3,3,5,5,5,2,2,7\]
**Output:** 2
**Explanation:** Choosing {3,7} will make the new array \[5,5,5,2,2\] which has size 5 (i.e equal to half of the size of the old array).
Possible sets of size 2 are {3,5},{3,2},{5,2}.
Choosing set {2,7} is not possible as it will make the new array \[3,3,3,3,5,5,5\] which has a size greater than half of the size of the old array.

**Example 2:**

**Input:** arr = \[7,7,7,7,7,7\]
**Output:** 1
**Explanation:** The only possible set you can choose is {7}. This will make the new array empty.

**Constraints:**

*   `2 <= arr.length <= 105`
*   `arr.length` is even.
*   `1 <= arr[i] <= 105`

## A solution in Java

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

public int minSetSize(int[] arr) {
    Map<Integer, Integer> freq_map = new HashMap<>();
    PriorityQueue<Integer> max_heap = new PriorityQueue<>((a, b) -> b - a);
    for (int x : arr)
        freq_map.put(x, freq_map.getOrDefault(x, 0) + 1);
    for (int cnt : freq_map.values())
        max_heap.offer(cnt);
    int half = arr.length / 2;
    int cnt = 0;
    int size = 0;
    while (size < half) {
        size += max_heap.poll();
        cnt++;
    }
    return cnt;
}
```
To solve this problem, we need to count the occurrences of each integer in the array. We can then calculate the minimum set size by greedily selecting the most frequent integers until at least half of the elements are removed.

1. Construct a frequency map for each integer, i.e., count how many times each integer appears in the array.
2. Create a max heap (priority queue) from the frequency map values.
3. Initialize two counters: one for the total removed elements and one for the set size.
4. While the total removed elements are less than half of the array's length, pop elements from the max heap and add their frequency to the total removed elements. Increment the set size each time.
5. Return the minimum set size.

This algorithm has a time complexity of O(n + k * log(k)) and a space complexity of O(k), where n is the length of the given array and k is the number of distinct integers in the array.

## A solution in C++

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

int minSetSize(vector<int>& arr) {
    unordered_map<int, int> freq_map;
    priority_queue<int> max_heap;
    for (int x : arr)
        freq_map[x]++;
    for (auto &[_, cnt] : freq_map)
        max_heap.push(cnt);
    int half = arr.size() / 2;
    int cnt = 0;
    int size = 0;
    while (size < half) {
        size += max_heap.top();
        max_heap.pop();
        cnt++;
    }
    return cnt;
}
```
To solve this problem, we need to count the occurrences of each integer in the array. We can then calculate the minimum set size by greedily selecting the most frequent integers until at least half of the elements are removed.

1. Construct a frequency map for each integer, i.e., count how many times each integer appears in the array.
2. Create a max heap (priority queue) from the frequency map values.
3. Initialize two counters: one for the total removed elements and one for the set size.
4. While the total removed elements are less than half of the array's length, pop elements from the max heap and add their frequency to the total removed elements. Increment the set size each time.
5. Return the minimum set size.

This algorithm has a time complexity of O(n + k * log(k)) and a space complexity of O(k), where n is the length of the given array and k is the number of distinct integers in the array.

## A solution in Python

```python
from collections import Counter
import heapq

def minSetSize(arr):
    freq_map = Counter(arr)
    max_heap = [-cnt for cnt in freq_map.values()]
    heapq.heapify(max_heap)
    half = len(arr) // 2
    cnt = 0
    size = 0
    while size < half:
        size -= heapq.heappop(max_heap)
        cnt += 1
    return cnt
```
To solve this problem, we need to count the occurrences of each integer in the array. We can then calculate the minimum set size by greedily selecting the most frequent integers until at least half of the elements are removed.

1. Construct a frequency map for each integer, i.e., count how many times each integer appears in the array.
2. Create a max heap (priority queue) from the frequency map values.
3. Initialize two counters: one for the total removed elements and one for the set size.
4. While the total removed elements are less than half of the array's length, pop elements from the max heap and add their frequency to the total removed elements. Increment the set size each time.
5. Return the minimum set size.

This algorithm has a time complexity of O(n + k * log(k)) and a space complexity of O(k), where n is the length of the given array and k is the number of distinct integers in the array.

## A solution in Javascript

```javascript
function minSetSize(arr) {
    let freq_map = new Map();
    for (let x of arr)
        freq_map.set(x, (freq_map.get(x) || 0) + 1);
    let max_heap = Array.from(freq_map.values());
    max_heap.sort((a, b) => b - a);
    let half = arr.length / 2;
    let cnt = 0;
    let size = 0;
    for (let i = 0; size < half; i++) {
        size += max_heap[i];
        cnt++;
    }
    return cnt;
}
```
To solve this problem, we need to count the occurrences of each integer in the array. We can then calculate the minimum set size by greedily selecting the most frequent integers until at least half of the elements are removed.

1. Construct a frequency map for each integer, i.e., count how many times each integer appears in the array.
2. Create a max heap (priority queue) from the frequency map values.
3. Initialize two counters: one for the total removed elements and one for the set size.
4. While the total removed elements are less than half of the array's length, pop elements from the max heap and add their frequency to the total removed elements. Increment the set size each time.
5. Return the minimum set size.

This algorithm has a time complexity of O(n + k * log(k)) and a space complexity of O(k), where n is the length of the given array and k is the number of distinct integers in the array.


# Maximum Product of Splitted Binary Tree

- slug: maximum-product-of-splitted-binary-tree
- difficulty: Medium

Given the `root` of a binary tree, split the binary tree into two subtrees by removing one edge such that the product of the sums of the subtrees is maximized.

Return _the maximum product of the sums of the two subtrees_. Since the answer may be too large, return it **modulo** `109 + 7`.

**Note** that you need to maximize the answer before taking the mod and not after taking it.

**Example 1:**

**Input:** root = \[1,2,3,4,5,6\]
**Output:** 110
**Explanation:** Remove the red edge and get 2 binary trees with sum 11 and 10. Their product is 110 (11\*10)

**Example 2:**

**Input:** root = \[1,null,2,3,4,null,null,5,6\]
**Output:** 90
**Explanation:** Remove the red edge and get 2 binary trees with sum 15 and 6.Their product is 90 (15\*6)

**Constraints:**

*   The number of nodes in the tree is in the range `[2, 5 * 104]`.
*   `1 <= Node.val <= 104`

## A solution in Java

```java
import java.util.ArrayList;

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
}

class Solution {
    private int sumSubtrees(TreeNode root, ArrayList<Integer> sums) {
        if (root == null) return 0;
        int sum = root.val + sumSubtrees(root.left, sums) + sumSubtrees(root.right, sums);
        sums.add(sum);
        return sum;
    }

    public int maxProduct(TreeNode root) {
        ArrayList<Integer> sums = new ArrayList<>();
        long total = sumSubtrees(root, sums);
        long max_product = 0;

        for (long sum : sums) {
            max_product = Math.max(max_product, sum * (total - sum));
        }

        return (int)(max_product % 1000000007L);
    }
}
```
1. Traverse the binary tree using a depth-first search and calculate the sum of the subtree rooted at each node. Append the subtree sums to an array as you go.
2. Calculate the total sum of the tree (which is the sum of the subtree rooted at the original root node).
3. Iterate through the array of subtree sums and for each subtree sum, calculate the product of that subtree sum and the sum of the rest of the tree (total sum - subtree sum). Keep track of the maximum product found.
4. Return the maximum product found, modulo 10^9 + 7.

## A solution in C++

```cpp
#include <algorithm>
#include <vector>
using std::max;
using std::vector;

class TreeNode {
public:
    int val;
    TreeNode* left;
    TreeNode* right;
};

class Solution {
    int sumSubtrees(TreeNode* root, vector<int>& sums) {
        if (!root) return 0;
        int sum = root->val + sumSubtrees(root->left, sums) + sumSubtrees(root->right, sums);
        sums.push_back(sum);
        return sum;
    }

public:
    int maxProduct(TreeNode* root) {
        vector<int> sums;
        long long total = sumSubtrees(root, sums);
        long long max_product = 0;

        for (long long sum : sums) {
            max_product = max(max_product, sum * (total - sum));
        }

        return max_product % 1000000007;
    }
};
```
1. Traverse the binary tree using a depth-first search and calculate the sum of the subtree rooted at each node. Append the subtree sums to an array as you go.
2. Calculate the total sum of the tree (which is the sum of the subtree rooted at the original root node).
3. Iterate through the array of subtree sums and for each subtree sum, calculate the product of that subtree sum and the sum of the rest of the tree (total sum - subtree sum). Keep track of the maximum product found.
4. Return the maximum product found, modulo 10^9 + 7.

## A solution in Python

```python
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def sum_subtrees(self, root, sums):
        if not root: return 0
        s = root.val + self.sum_subtrees(root.left, sums) + self.sum_subtrees(root.right, sums)
        sums.append(s)
        return s

    def maxProduct(self, root):
        sums = []
        total = self.sum_subtrees(root, sums)
        max_product = max(s * (total - s) for s in sums)
        return max_product % 1000000007
```
1. Traverse the binary tree using a depth-first search and calculate the sum of the subtree rooted at each node. Append the subtree sums to an array as you go.
2. Calculate the total sum of the tree (which is the sum of the subtree rooted at the original root node).
3. Iterate through the array of subtree sums and for each subtree sum, calculate the product of that subtree sum and the sum of the rest of the tree (total sum - subtree sum). Keep track of the maximum product found.
4. Return the maximum product found, modulo 10^9 + 7.

## A solution in Javascript

```javascript
class TreeNode {
    constructor(val, left = null, right = null) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

var maxProduct = function(root) {
    let sums = [];

    function sumSubtrees(node) {
        if (!node) return 0;
        let sum = node.val + sumSubtrees(node.left) + sumSubtrees(node.right);
        sums.push(sum);
        return sum;
    }

    let total = sumSubtrees(root);
    let max_product = 0;
    for (let sum of sums) {
        max_product = Math.max(max_product, sum * (total - sum));
    }

    return max_product % 1000000007;
};
```
1. Traverse the binary tree using a depth-first search and calculate the sum of the subtree rooted at each node. Append the subtree sums to an array as you go.
2. Calculate the total sum of the tree (which is the sum of the subtree rooted at the original root node).
3. Iterate through the array of subtree sums and for each subtree sum, calculate the product of that subtree sum and the sum of the rest of the tree (total sum - subtree sum). Keep track of the maximum product found.
4. Return the maximum product found, modulo 10^9 + 7.