# Decoded String at Index

- slug: decoded-string-at-index
- difficulty: Medium

You are given an encoded string `s`. To decode the string to a tape, the encoded string is read one character at a time and the following steps are taken:

*   If the character read is a letter, that letter is written onto the tape.
*   If the character read is a digit `d`, the entire current tape is repeatedly written `d - 1` more times in total.

Given an integer `k`, return _the_ `kth` _letter (**1-indexed)** in the decoded string_.

**Example 1:**

**Input:** s =  "leet2code3 ", k = 10
**Output:**  "o "
**Explanation:** The decoded string is  "leetleetcodeleetleetcodeleetleetcode ".
The 10th letter in the string is  "o ".

**Example 2:**

**Input:** s =  "ha22 ", k = 5
**Output:**  "h "
**Explanation:** The decoded string is  "hahahaha ".
The 5th letter is  "h ".

**Example 3:**

**Input:** s =  "a2345678999999999999999 ", k = 1
**Output:**  "a "
**Explanation:** The decoded string is  "a " repeated 8301530446056247680 times.
The 1st letter is  "a ".

**Constraints:**

*   `2 <= s.length <= 100`
*   `s` consists of lowercase English letters and digits `2` through `9`.
*   `s` starts with a letter.
*   `1 <= k <= 109`
*   It is guaranteed that `k` is less than or equal to the length of the decoded string.
*   The decoded string is guaranteed to have less than `263` letters.

## A solution in Java

```java
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

class Solution {
    public int rectangleArea(int[][] rectangles) {
        int mod = 1000000007;
        ArrayList<Integer> X = new ArrayList<>();
        HashMap<Integer, Integer> Xcompress = new HashMap<>();
        for(int[] rect : rectangles){
            X.add(rect[0]);
            X.add(rect[2]);
        }
        Collections.sort(X);
        int idx = 0;
        for(int x : X){
            if(!Xcompress.containsKey(x))
                Xcompress.put(x, idx++);
        }

        ArrayList<int[]> events = new ArrayList<>();
        for(int[] rect : rectangles){
            events.add(new int[]{Xcompress.get(rect[0]), 1, rect[1], rect[3]});
            events.add(new int[]{Xcompress.get(rect[2]), -1, rect[1], rect[3]});
        }
        events.sort((a, b) -> Integer.compare(a[0], b[0]));

        int area = 0;
        int[] cnt = new int[idx];
        int active = 0;
        for(int[] e : events){
            int index = e[0], type = e[1], y1 = e[2], y2 = e[3];
            area = (int) ((area + (long)(X.get(index+1) - X.get(index)) * active % mod) % mod);
            cnt[y1] += type;
            cnt[y2] -= type;
            active = 0;
            for(int i = 0; i < index; ++i){
                if(cnt[i] > 0)
                    active += X.get(i+1) - X.get(i);
            }
        }
        return area;
    }
}
```
The problem is to find the total area covered by the given rectangles, only counting the area which is covered once. The algorithm uses line sweep technique along the x-axis.

1. Scan through all the unique x-coordinates values from the given rectangles and map them to their index in the sorted order. This will help in compressing the x-coordinate range.

2. Create a list of events from the given rectangles. Each event will have the format of (x-coordinate index, event type, y1, and y3). The event type will be 1 (start) for the left side of the rectangle and -1 (end) for the right side of the rectangle. Sort the events by the x-coordinate index.

3. Initialize the area value to zero and create a count array for y-coordinate ranges. Iterate through the sorted events list, and for each event:

    a. Update the area by adding the product of the distance between the current x-coordinate and the next x-coordinate and the active y-coordinate ranges.

    b. Update the count of y-coordinate ranges based on the event type (increment for start, decrement for end).

    c. Calculate the active y-coordinate ranges by summing the y-coordinate differences for those ranges whose count is greater than 0.

4. Return the total area.

## A solution in C++

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

int rectangleArea(vector<vector<int>>& rectangles) {
    int mod = 1e9 + 7;
    vector<int> X;
    map<int,int> Xcompress;
    for(auto r : rectangles){
        X.push_back(r[0]);
        X.push_back(r[2]);
    }
    sort(X.begin(), X.end());
    int idx = 0;
    for(auto x : X){
        if(!Xcompress.count(x))
            Xcompress[x] = idx++;
    }

    vector<vector<int>> events;
    for(auto r : rectangles){
        events.push_back({Xcompress[r[0]], 1, r[1], r[3]});
        events.push_back({Xcompress[r[2]], -1, r[1], r[3]});
    }
    sort(events.begin(), events.end());

    int area = 0;
    vector<int> cnt(idx,0);
    int active = 0;
    for(auto e : events){
        int idx = e[0], type = e[1],	y1 = e[2], y2 = e[3];
        area = (area + (long long)(X[idx+1] - X[idx]) * active % mod) % mod;
        cnt[y1] += type;
        cnt[y2] -= type;
        active = 0;
        for(int i = 0; i < idx; ++i){
            if(cnt[i])
                active += X[i+1] - X[i];
        }
    }
    return area;
}
```
The problem is to find the total area covered by the given rectangles, only counting the area which is covered once. The algorithm uses line sweep technique along the x-axis.

1. Scan through all the unique x-coordinates values from the given rectangles and map them to their index in the sorted order. This will help in compressing the x-coordinate range.

2. Create a list of events from the given rectangles. Each event will have the format of (x-coordinate index, event type, y1, and y3). The event type will be 1 (start) for the left side of the rectangle and -1 (end) for the right side of the rectangle. Sort the events by the x-coordinate index.

3. Initialize the area value to zero and create a count array for y-coordinate ranges. Iterate through the sorted events list, and for each event:

    a. Update the area by adding the product of the distance between the current x-coordinate and the next x-coordinate and the active y-coordinate ranges.

    b. Update the count of y-coordinate ranges based on the event type (increment for start, decrement for end).

    c. Calculate the active y-coordinate ranges by summing the y-coordinate differences for those ranges whose count is greater than 0.

4. Return the total area.

## A solution in Python

```python
def rectangleArea(rectangles):
    mod = 10**9 + 7
    X = sorted(set(x for rect in rectangles for x in rect[::2]))
    Xdict = {x:i for i,x in enumerate(X)}

    events = []
    for x1,y1,x2,y2 in rectangles:
        events.append((Xdict[x1], 1, y1, y2))
        events.append((Xdict[x2], -1, y1, y2))
    events.sort()

    area = 0
    cnt = [0] * len(X)
    active = 0
    for idx, type, y1, y2 in events:
        area = (area + (X[idx+1] - X[idx]) * active % mod) % mod
        cnt[y1] += type
        cnt[y2] -= type
        active = sum(p for j,p in zip(X, cnt) if p)

    return area
```
The problem is to find the total area covered by the given rectangles, only counting the area which is covered once. The algorithm uses line sweep technique along the x-axis.

1. Scan through all the unique x-coordinates values from the given rectangles and map them to their index in the sorted order. This will help in compressing the x-coordinate range.

2. Create a list of events from the given rectangles. Each event will have the format of (x-coordinate index, event type, y1, and y3). The event type will be 1 (start) for the left side of the rectangle and -1 (end) for the right side of the rectangle. Sort the events by the x-coordinate index.

3. Initialize the area value to zero and create a count array for y-coordinate ranges. Iterate through the sorted events list, and for each event:

    a. Update the area by adding the product of the distance between the current x-coordinate and the next x-coordinate and the active y-coordinate ranges.

    b. Update the count of y-coordinate ranges based on the event type (increment for start, decrement for end).

    c. Calculate the active y-coordinate ranges by summing the y-coordinate differences for those ranges whose count is greater than 0.

4. Return the total area.

## A solution in Javascript

```javascript
function rectangleArea(rectangles) {
    const mod = 1e9 + 7;
    const X = Array.from(new Set(rectangles.flatMap(rect => [rect[0], rect[2]]))).sort((a, b) => a - b);
    const Xcompress = new Map(X.map((x, idx) => [x, idx]));

    const events = [];
    for(const rect of rectangles) {
        events.push([Xcompress.get(rect[0]), 1, rect[1], rect[3]]);
        events.push([Xcompress.get(rect[2]), -1, rect[1], rect[3]]);
    }
    events.sort((a, b) => a[0] - b[0]);

    let area = 0;
    const cnt = Array(X.length).fill(0);
    let active = 0;
    for(const [idx, type, y1, y2] of events) {
        area = (area + (X[idx + 1] - X[idx]) * active % mod) % mod;
        cnt[y1] += type;
        cnt[y2] -= type;
        active = 0;
        for(let i = 0; i < idx; ++i) {
            if (cnt[i] > 0) active += X[i+1] - X[i];
        }
    }

    return area;
}
```
The problem is to find the total area covered by the given rectangles, only counting the area which is covered once. The algorithm uses line sweep technique along the x-axis.

1. Scan through all the unique x-coordinates values from the given rectangles and map them to their index in the sorted order. This will help in compressing the x-coordinate range.

2. Create a list of events from the given rectangles. Each event will have the format of (x-coordinate index, event type, y1, and y3). The event type will be 1 (start) for the left side of the rectangle and -1 (end) for the right side of the rectangle. Sort the events by the x-coordinate index.

3. Initialize the area value to zero and create a count array for y-coordinate ranges. Iterate through the sorted events list, and for each event:

    a. Update the area by adding the product of the distance between the current x-coordinate and the next x-coordinate and the active y-coordinate ranges.

    b. Update the count of y-coordinate ranges based on the event type (increment for start, decrement for end).

    c. Calculate the active y-coordinate ranges by summing the y-coordinate differences for those ranges whose count is greater than 0.

4. Return the total area.


# Boats to Save People

- slug: boats-to-save-people
- difficulty: Medium

You are given an array `people` where `people[i]` is the weight of the `ith` person, and an **infinite number of boats** where each boat can carry a maximum weight of `limit`. Each boat carries at most two people at the same time, provided the sum of the weight of those people is at most `limit`.

Return _the minimum number of boats to carry every given person_.

**Example 1:**

**Input:** people = \[1,2\], limit = 3
**Output:** 1
**Explanation:** 1 boat (1, 2)

**Example 2:**

**Input:** people = \[3,2,2,1\], limit = 3
**Output:** 3
**Explanation:** 3 boats (1, 2), (2) and (3)

**Example 3:**

**Input:** people = \[3,5,3,4\], limit = 5
**Output:** 4
**Explanation:** 4 boats (3), (3), (4), (5)

**Constraints:**

*   `1 <= people.length <= 5 * 104`
*   `1 <= people[i] <= limit <= 3 * 104`

## A solution in Java

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

public int[] loudAndRich(int[][] richer, int[] quiet) {
    int n = quiet.length;
    List<Integer>[] graph = new ArrayList[n];
    for (int i = 0; i < n; ++i)
        graph[i] = new ArrayList<>();

    for (int[] entry : richer)
        graph[entry[1]].add(entry[0]);

    int[] answer = new int[n];
    Arrays.fill(answer, -1);
    for (int i = 0; i < n; ++i)
        dfs(i, graph, quiet, answer);

    return answer;
}

private void dfs(int x, List<Integer>[] graph, int[] quiet, int[] answer) {
    if (answer[x] != -1) return;
    answer[x] = x;
    for (int y : graph[x]) {
        dfs(y, graph, quiet, answer);
        if (quiet[answer[y]] < quiet[answer[x]])
            answer[x] = answer[y];
    }
}
```
For this problem, we will use Depth-First Search algorithm (DFS). The main idea is to represent richer relationships as a directed graph, where the edge a -> b means the person 'a' has more money than the person 'b'. Then, for each person 'x', we want to find the smallest value of quiet[y] for all 'y' who have equal or more money than 'x'.

1. First, convert the richer array into the adjacency list representation graph where graph[i] contains an integer list of people who are richer than the person i.
2. Initialize an answer list with all values as -1.
3. Define a DFS function, in which:
   - If the DFS for a person x is already calculated, return the result.
   - Set answer[x] = x
   - For each neighbor y in graph[x], call DFS(y).
   - If quiet[answer[y]] < quiet[answer[x]], update answer[x] with answer[y].
   - Return answer[x].
4. Iterate through all people (0 to n-1), and call the DFS function for each person.
5. The final answer array will have values equal to the least quiet person among all people who definitely have equal to or more money than the person x.

## A solution in C++

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

void dfs(int x, vector<vector<int>>& graph, vector<int>& quiet, vector<int>& answer) {
    if (answer[x] != -1) return;
    answer[x] = x;

    for (int y : graph[x]) {
        dfs(y, graph, quiet, answer);
        if (quiet[answer[y]] < quiet[answer[x]])
            answer[x] = answer[y];
    }
}

vector<int> loudAndRich(vector<vector<int>>& richer, vector<int>& quiet) {
    int n = quiet.size();
    vector<vector<int>> graph(n);
    for (auto& entry : richer)
        graph[entry[1]].push_back(entry[0]);

    vector<int> answer(n, -1);
    for (int i = 0; i < n; ++i)
        dfs(i, graph, quiet, answer);

    return answer;
}
```
For this problem, we will use Depth-First Search algorithm (DFS). The main idea is to represent richer relationships as a directed graph, where the edge a -> b means the person 'a' has more money than the person 'b'. Then, for each person 'x', we want to find the smallest value of quiet[y] for all 'y' who have equal or more money than 'x'.

1. First, convert the richer array into the adjacency list representation graph where graph[i] contains an integer list of people who are richer than the person i.
2. Initialize an answer list with all values as -1.
3. Define a DFS function, in which:
   - If the DFS for a person x is already calculated, return the result.
   - Set answer[x] = x
   - For each neighbor y in graph[x], call DFS(y).
   - If quiet[answer[y]] < quiet[answer[x]], update answer[x] with answer[y].
   - Return answer[x].
4. Iterate through all people (0 to n-1), and call the DFS function for each person.
5. The final answer array will have values equal to the least quiet person among all people who definitely have equal to or more money than the person x.

## A solution in Python

```python
from collections import defaultdict

def loudAndRich(richer, quiet):
    n = len(quiet)
    graph = defaultdict(list)
    for r in richer:
        graph[r[1]].append(r[0])

    answer = [-1] * n

    def dfs(x):
        if answer[x] != -1:
            return answer[x]
        answer[x] = x
        for y in graph[x]:
            cand = dfs(y)
            if quiet[cand] < quiet[answer[x]]:
                answer[x] = cand
        return answer[x]

    for i in range(n):
        dfs(i)

    return answer
```
For this problem, we will use Depth-First Search algorithm (DFS). The main idea is to represent richer relationships as a directed graph, where the edge a -> b means the person 'a' has more money than the person 'b'. Then, for each person 'x', we want to find the smallest value of quiet[y] for all 'y' who have equal or more money than 'x'.

1. First, convert the richer array into the adjacency list representation graph where graph[i] contains an integer list of people who are richer than the person i.
2. Initialize an answer list with all values as -1.
3. Define a DFS function, in which:
   - If the DFS for a person x is already calculated, return the result.
   - Set answer[x] = x
   - For each neighbor y in graph[x], call DFS(y).
   - If quiet[answer[y]] < quiet[answer[x]], update answer[x] with answer[y].
   - Return answer[x].
4. Iterate through all people (0 to n-1), and call the DFS function for each person.
5. The final answer array will have values equal to the least quiet person among all people who definitely have equal to or more money than the person x.

## A solution in Javascript

```javascript
function loudAndRich(richer, quiet) {
    const n = quiet.length;
    const graph = Array.from({ length: n }, () => []);
    richer.forEach(([a, b]) => graph[b].push(a));

    const answer = Array(n).fill(-1);

    function dfs(x) {
        if (answer[x] != -1) return answer[x];
        answer[x] = x;
        for (const y of graph[x]) {
            const cand = dfs(y)
            if (quiet[cand] < quiet[answer[x]])
                answer[x] = cand;
        }
        return answer[x];
    }

    for (let i = 0; i < n; ++i)
        dfs(i)

    return answer;
}
```
For this problem, we will use Depth-First Search algorithm (DFS). The main idea is to represent richer relationships as a directed graph, where the edge a -> b means the person 'a' has more money than the person 'b'. Then, for each person 'x', we want to find the smallest value of quiet[y] for all 'y' who have equal or more money than 'x'.

1. First, convert the richer array into the adjacency list representation graph where graph[i] contains an integer list of people who are richer than the person i.
2. Initialize an answer list with all values as -1.
3. Define a DFS function, in which:
   - If the DFS for a person x is already calculated, return the result.
   - Set answer[x] = x
   - For each neighbor y in graph[x], call DFS(y).
   - If quiet[answer[y]] < quiet[answer[x]], update answer[x] with answer[y].
   - Return answer[x].
4. Iterate through all people (0 to n-1), and call the DFS function for each person.
5. The final answer array will have values equal to the least quiet person among all people who definitely have equal to or more money than the person x.


# Reachable Nodes In Subdivided Graph

- slug: reachable-nodes-in-subdivided-graph
- difficulty: Hard

You are given an undirected graph (the **"original graph "**) with `n` nodes labeled from `0` to `n - 1`. You decide to **subdivide** each edge in the graph into a chain of nodes, with the number of new nodes varying between each edge.

The graph is given as a 2D array of `edges` where `edges[i] = [ui, vi, cnti]` indicates that there is an edge between nodes `ui` and `vi` in the original graph, and `cnti` is the total number of new nodes that you will **subdivide** the edge into. Note that `cnti == 0` means you will not subdivide the edge.

To **subdivide** the edge `[ui, vi]`, replace it with `(cnti + 1)` new edges and `cnti` new nodes. The new nodes are `x1`, `x2`, ..., `xcnti`, and the new edges are `[ui, x1]`, `[x1, x2]`, `[x2, x3]`, ..., `[xcnti-1, xcnti]`, `[xcnti, vi]`.

In this **new graph**, you want to know how many nodes are **reachable** from the node `0`, where a node is **reachable** if the distance is `maxMoves` or less.

Given the original graph and `maxMoves`, return _the number of nodes that are **reachable** from node_ `0` _in the new graph_.

**Example 1:**

**Input:** edges = \[\[0,1,10\],\[0,2,1\],\[1,2,2\]\], maxMoves = 6, n = 3
**Output:** 13
**Explanation:** The edge subdivisions are shown in the image above.
The nodes that are reachable are highlighted in yellow.

**Example 2:**

**Input:** edges = \[\[0,1,4\],\[1,2,6\],\[0,2,8\],\[1,3,1\]\], maxMoves = 10, n = 4
**Output:** 23

**Example 3:**

**Input:** edges = \[\[1,2,4\],\[1,4,5\],\[1,3,1\],\[2,3,4\],\[3,4,5\]\], maxMoves = 17, n = 5
**Output:** 1
**Explanation:** Node 0 is disconnected from the rest of the graph, so only node 0 is reachable.

**Constraints:**

*   `0 <= edges.length <= min(n * (n - 1) / 2, 104)`
*   `edges[i].length == 3`
*   `0 <= ui < vi < n`
*   There are **no multiple edges** in the graph.
*   `0 <= cnti <= 104`
*   `0 <= maxMoves <= 109`
*   `1 <= n <= 3000`

## A solution in Java

```java
public int peakIndexInMountainArray(int[] arr) {
    int low = 0, high = arr.length - 1;
    while (low < high) {
        int mid = low + (high - low) / 2;
        if (arr[mid] < arr[mid + 1])
            low = mid + 1;
        else
            high = mid;
    }
    return low;
}
```
The algorithm uses a binary search approach to find the peak index in the mountain array. It starts with two pointers, `low` and `high`, initially set to the beginning and end of the array. In each iteration of the loop, it calculates the middle index as `mid = low + (high - low) / 2` (in Python, use integer division). If the middle element is smaller than the next one, we know the peak is to the right, so we update `low` to `mid + 1`. If not, the peak is to the left, and we update `high` to `mid`. The loop continues until `low` and `high` pointers meet, where the peak index is found and returned.

## A solution in C++

```cpp
int peakIndexInMountainArray(vector<int>& arr) {
    int low = 0, high = arr.size() - 1;
    while (low < high) {
        int mid = low + (high - low) / 2;
        if (arr[mid] < arr[mid + 1])
            low = mid + 1;
        else
            high = mid;
    }
    return low;
}
```
The algorithm uses a binary search approach to find the peak index in the mountain array. It starts with two pointers, `low` and `high`, initially set to the beginning and end of the array. In each iteration of the loop, it calculates the middle index as `mid = low + (high - low) / 2` (in Python, use integer division). If the middle element is smaller than the next one, we know the peak is to the right, so we update `low` to `mid + 1`. If not, the peak is to the left, and we update `high` to `mid`. The loop continues until `low` and `high` pointers meet, where the peak index is found and returned.

## A solution in Python

```python
def peakIndexInMountainArray(arr):
    low, high = 0, len(arr) - 1
    while low < high:
        mid = low + (high - low) // 2
        if arr[mid] < arr[mid + 1]:
            low = mid + 1
        else:
            high = mid
    return low
```
The algorithm uses a binary search approach to find the peak index in the mountain array. It starts with two pointers, `low` and `high`, initially set to the beginning and end of the array. In each iteration of the loop, it calculates the middle index as `mid = low + (high - low) / 2` (in Python, use integer division). If the middle element is smaller than the next one, we know the peak is to the right, so we update `low` to `mid + 1`. If not, the peak is to the left, and we update `high` to `mid`. The loop continues until `low` and `high` pointers meet, where the peak index is found and returned.

## A solution in Javascript

```javascript
function peakIndexInMountainArray(arr) {
    let low = 0, high = arr.length - 1;
    while (low < high) {
        let mid = low + Math.floor((high - low) / 2);
        if (arr[mid] < arr[mid + 1])
            low = mid + 1;
        else
            high = mid;
    }
    return low;
}
```
The algorithm uses a binary search approach to find the peak index in the mountain array. It starts with two pointers, `low` and `high`, initially set to the beginning and end of the array. In each iteration of the loop, it calculates the middle index as `mid = low + (high - low) / 2` (in Python, use integer division). If the middle element is smaller than the next one, we know the peak is to the right, so we update `low` to `mid + 1`. If not, the peak is to the left, and we update `high` to `mid`. The loop continues until `low` and `high` pointers meet, where the peak index is found and returned.


# Projection Area of 3D Shapes

- slug: projection-area-of-3d-shapes
- difficulty: Easy

You are given an `n x n` `grid` where we place some `1 x 1 x 1` cubes that are axis-aligned with the `x`, `y`, and `z` axes.

Each value `v = grid[i][j]` represents a tower of `v` cubes placed on top of the cell `(i, j)`.

We view the projection of these cubes onto the `xy`, `yz`, and `zx` planes.

A **projection** is like a shadow, that maps our **3-dimensional** figure to a **2-dimensional** plane. We are viewing the "shadow " when looking at the cubes from the top, the front, and the side.

Return _the total area of all three projections_.

**Example 1:**

**Input:** grid = \[\[1,2\],\[3,4\]\]
**Output:** 17
**Explanation:** Here are the three projections ( "shadows ") of the shape made with each axis-aligned plane.

**Example 2:**

**Input:** grid = \[\[2\]\]
**Output:** 5

**Example 3:**

**Input:** grid = \[\[1,0\],\[0,2\]\]
**Output:** 8

**Constraints:**

*   `n == grid.length == grid[i].length`
*   `1 <= n <= 50`
*   `0 <= grid[i][j] <= 50`

## A solution in Java

```java
public int carFleet(int target, int[] position, int[] speed) {
    int n = position.length;
    Integer[] indices = new Integer[n];
    for (int i = 0; i < n; i++) {
        indices[i] = i;
    }

    Arrays.sort(indices, (a, b) -> position[b] - position[a]);

    int fleets = 0;
    double lastArrival = -1;
    for (int i : indices) {
        double arrival = (double) (target - position[i]) / speed[i];
        if (arrival > lastArrival) {
            fleets++;
            lastArrival = arrival;
        }
    }

    return fleets;
}
```
First, we create a `cars` data structure containing the car's position and speed, sorted in descending order by position. This ensures that we examine the cars from the front of the road (i.e., closest to the target) to the back.

Next, we initialize a `fleets` counter and a `last_arrival` variable to keep track of the last car's arrival time at the destination.

Then, we iterate through the sorted cars. For each car, we calculate its arrival time as `(target - position) / speed`. If this car's arrival time is greater than the last car's arrival time (i.e., `arrival > last_arrival`), then it is considered a new car fleet, and we will increment the `fleets` counter. We update the `last_arrival` variable for the next iteration.

Finally, we return the total number of car fleets that will arrive at the destination.

## A solution in C++

```cpp
int carFleet(int target, vector<int>& position, vector<int>& speed) {
    int n = position.size();
    vector<pair<int, int>> cars;
    for (int i = 0; i < n; ++i) {
        cars.emplace_back(position[i], speed[i]);
    }
    sort(cars.begin(), cars.end(), [](const pair<int, int>& a, const pair<int, int>& b) {
        return a.first > b.first;
    });

    int fleets = 0;
    double last_arrival = -1;
    for (int i = 0; i < n; ++i) {
        double arrival = (double)(target - cars[i].first) / cars[i].second;
        if (arrival > last_arrival) {
            ++fleets;
            last_arrival = arrival;
        }
    }

    return fleets;
}
```
First, we create a `cars` data structure containing the car's position and speed, sorted in descending order by position. This ensures that we examine the cars from the front of the road (i.e., closest to the target) to the back.

Next, we initialize a `fleets` counter and a `last_arrival` variable to keep track of the last car's arrival time at the destination.

Then, we iterate through the sorted cars. For each car, we calculate its arrival time as `(target - position) / speed`. If this car's arrival time is greater than the last car's arrival time (i.e., `arrival > last_arrival`), then it is considered a new car fleet, and we will increment the `fleets` counter. We update the `last_arrival` variable for the next iteration.

Finally, we return the total number of car fleets that will arrive at the destination.

## A solution in Python

```python
def carFleet(target: int, position: List[int], speed: List[int]) -> int:
    cars = sorted(zip(position, speed), reverse=True)
    fleets = 0
    last_arrival = -1

    for pos, sp in cars:
        arrival = (target - pos) / sp
        if arrival > last_arrival:
            fleets += 1
            last_arrival = arrival

    return fleets
```
First, we create a `cars` data structure containing the car's position and speed, sorted in descending order by position. This ensures that we examine the cars from the front of the road (i.e., closest to the target) to the back.

Next, we initialize a `fleets` counter and a `last_arrival` variable to keep track of the last car's arrival time at the destination.

Then, we iterate through the sorted cars. For each car, we calculate its arrival time as `(target - position) / speed`. If this car's arrival time is greater than the last car's arrival time (i.e., `arrival > last_arrival`), then it is considered a new car fleet, and we will increment the `fleets` counter. We update the `last_arrival` variable for the next iteration.

Finally, we return the total number of car fleets that will arrive at the destination.

## A solution in Javascript

```javascript
function carFleet(target, position, speed) {
  const n = position.length;
  const cars = position.map((pos, i) => [pos, speed[i]]).sort((a, b) => b[0] - a[0]);

  let fleets = 0;
  let lastArrival = -1;

  for (let i = 0; i < n; i++) {
    const arrival = (target - cars[i][0]) / cars[i][1];
    if (arrival > lastArrival) {
      fleets++;
      lastArrival = arrival;
    }
  }

  return fleets;
}
```
First, we create a `cars` data structure containing the car's position and speed, sorted in descending order by position. This ensures that we examine the cars from the front of the road (i.e., closest to the target) to the back.

Next, we initialize a `fleets` counter and a `last_arrival` variable to keep track of the last car's arrival time at the destination.

Then, we iterate through the sorted cars. For each car, we calculate its arrival time as `(target - position) / speed`. If this car's arrival time is greater than the last car's arrival time (i.e., `arrival > last_arrival`), then it is considered a new car fleet, and we will increment the `fleets` counter. We update the `last_arrival` variable for the next iteration.

Finally, we return the total number of car fleets that will arrive at the destination.


# Uncommon Words from Two Sentences

- slug: uncommon-words-from-two-sentences
- difficulty: Easy

A **sentence** is a string of single-space separated words where each word consists only of lowercase letters.

A word is **uncommon** if it appears exactly once in one of the sentences, and **does not appear** in the other sentence.

Given two **sentences** `s1` and `s2`, return _a list of all the **uncommon words**_. You may return the answer in **any order**.

**Example 1:**

**Input:** s1 = "this apple is sweet", s2 = "this apple is sour"
**Output:** \["sweet","sour"\]

**Example 2:**

**Input:** s1 = "apple apple", s2 = "banana"
**Output:** \["banana"\]

**Constraints:**

*   `1 <= s1.length, s2.length <= 200`
*   `s1` and `s2` consist of lowercase English letters and spaces.
*   `s1` and `s2` do not have leading or trailing spaces.
*   All the words in `s1` and `s2` are separated by a single space.

## A solution in Java

```java
public int kSimilarity(String s1, String s2) {
    int k = 0;
    StringBuilder a = new StringBuilder(s1);
    StringBuilder b = new StringBuilder(s2);
    for (int i = 0; i < a.length(); ++i) {
        if (a.charAt(i) != b.charAt(i)) {
            for (int j = i + 1; j < b.length(); ++j) {
                if (a.charAt(i) == b.charAt(j) && a.charAt(j) != b.charAt(j)) {
                    a.setCharAt(i, a.charAt(j));
                    a.setCharAt(j, b.charAt(j));
                    k++;
                    break;
                }
            }
        }
    }
    return k;
}
```
The algorithm begins by initializing the counter `k` to 0. We then create two mutable copies of the inputs: `a` and `b`. We loop through each character in `a` and compare it to its corresponding position in `b`. If they don't match, we look for matching characters in both `b` and the later part of `a`, ensuring that the swap candidate is not 'correct' (i.e., needs to be swapped itself). If we find a good swap candidate, we swap the characters in `a` and increment the `k`. We continue this process until reaching the end of the strings, and return `k` as the final result.

## A solution in C++

```cpp
int kSimilarity(const std::string& s1, const std::string& s2) {
    int k = 0;
    std::string a = s1, b = s2;
    for (int i = 0; i < a.size(); ++i) {
        if (a[i] != b[i]) {
            for (int j = i + 1; j < b.size(); ++j) {
                if (a[i] == b[j] && a[j] != b[j]) {
                    std::swap(a[i], a[j]);
                    k++;
                    break;
                }
            }
        }
    }
    return k;
}
```
The algorithm begins by initializing the counter `k` to 0. We then create two mutable copies of the inputs: `a` and `b`. We loop through each character in `a` and compare it to its corresponding position in `b`. If they don't match, we look for matching characters in both `b` and the later part of `a`, ensuring that the swap candidate is not 'correct' (i.e., needs to be swapped itself). If we find a good swap candidate, we swap the characters in `a` and increment the `k`. We continue this process until reaching the end of the strings, and return `k` as the final result.

## A solution in Python

```python
def k_similarity(s1, s2):
    k = 0
    a, b = list(s1), list(s2)
    for i in range(len(a)):
        if a[i] != b[i]:
            for j in range(i + 1, len(b)):
                if a[i] == b[j] and a[j] != b[j]:
                    a[i], a[j] = a[j], a[i]
                    k += 1
                    break
    return k
```
The algorithm begins by initializing the counter `k` to 0. We then create two mutable copies of the inputs: `a` and `b`. We loop through each character in `a` and compare it to its corresponding position in `b`. If they don't match, we look for matching characters in both `b` and the later part of `a`, ensuring that the swap candidate is not 'correct' (i.e., needs to be swapped itself). If we find a good swap candidate, we swap the characters in `a` and increment the `k`. We continue this process until reaching the end of the strings, and return `k` as the final result.

## A solution in Javascript

```javascript
function kSimilarity(s1, s2) {
    let k = 0;
    let a = Array.from(s1);
    let b = Array.from(s2);
    for (let i = 0; i < a.length; ++i) {
        if (a[i] !== b[i]) {
            for (let j = i + 1; j < b.length; ++j) {
                if (a[i] === b[j] && a[j] !== b[j]) {
                    [a[i], a[j]] = [a[j], a[i]];
                    k++;
                    break;
                }
            }
        }
    }
    return k;
}
```
The algorithm begins by initializing the counter `k` to 0. We then create two mutable copies of the inputs: `a` and `b`. We loop through each character in `a` and compare it to its corresponding position in `b`. If they don't match, we look for matching characters in both `b` and the later part of `a`, ensuring that the swap candidate is not 'correct' (i.e., needs to be swapped itself). If we find a good swap candidate, we swap the characters in `a` and increment the `k`. We continue this process until reaching the end of the strings, and return `k` as the final result.


# Spiral Matrix III

- slug: spiral-matrix-iii
- difficulty: Medium

You start at the cell `(rStart, cStart)` of an `rows x cols` grid facing east. The northwest corner is at the first row and column in the grid, and the southeast corner is at the last row and column.

You will walk in a clockwise spiral shape to visit every position in this grid. Whenever you move outside the grid's boundary, we continue our walk outside the grid (but may return to the grid boundary later.). Eventually, we reach all `rows * cols` spaces of the grid.

Return _an array of coordinates representing the positions of the grid in the order you visited them_.

**Example 1:**

**Input:** rows = 1, cols = 4, rStart = 0, cStart = 0
**Output:** \[\[0,0\],\[0,1\],\[0,2\],\[0,3\]\]

**Example 2:**

**Input:** rows = 5, cols = 6, rStart = 1, cStart = 4
**Output:** \[\[1,4\],\[1,5\],\[2,5\],\[2,4\],\[2,3\],\[1,3\],\[0,3\],\[0,4\],\[0,5\],\[3,5\],\[3,4\],\[3,3\],\[3,2\],\[2,2\],\[1,2\],\[0,2\],\[4,5\],\[4,4\],\[4,3\],\[4,2\],\[4,1\],\[3,1\],\[2,1\],\[1,1\],\[0,1\],\[4,0\],\[3,0\],\[2,0\],\[1,0\],\[0,0\]\]

**Constraints:**

*   `1 <= rows, cols <= 100`
*   `0 <= rStart < rows`
*   `0 <= cStart < cols`

## A solution in Java

```java
import java.util.TreeSet;

class ExamRoom {
    TreeSet<Integer> students;
    int n;

    public ExamRoom(int n) {
        this.students = new TreeSet<>();
        this.n = n;
    }

    public int seat() {
        if (students.isEmpty()) {
            students.add(0);
            return 0;
        }

        int distance = students.first(), seatIndex = 0;

        Integer prev = students.first();
        for (Integer current : students) {
            if (current != prev) {
                int d = (current - prev) / 2;

                if (d > distance) {
                    distance = d;
                    seatIndex = prev + d;
                }
                prev = current;
            }
        }

        if (n - 1 - students.last() > distance)
            seatIndex = n - 1;

        students.add(seatIndex);
        return seatIndex;
    }

    public void leave(int p) {
        students.remove(p);
    }
}
```
The ExamRoom class stores a ordered set of seat indices where students are sitting. When a student enters the room, we find the seat that maximizes distance to the closest student following these steps:
1. If the room is empty, the student sits at seat 0.
2. Iterate through the current seat indices to find the two adjacent seats with the maximum difference in indices. If we see a larger difference than the current maximum difference, we update the maximum distance and the seat index.
3. Check if sitting at the last seat (n-1) would result in a larger distance than the current maximum distance, and if so, update the seat index.
4. Insert the chosen seat index into our set.
5. When a student leaves, we remove that seat index from the set.

## A solution in C++

```cpp
class ExamRoom {
public:
    set<int> students;
    int n;

    ExamRoom(int n) {
        this->n = n;
    }

    int seat() {
        if (students.empty()) {
            students.insert(0);
            return 0;
        }

        int distance = *students.begin(), seat_index = 0;

        for (auto itr = next(students.begin()); itr != students.end(); ++itr) {
            auto prev = prev(itr);
            int d = (*itr - *prev) / 2;

            if (d > distance) {
                distance = d;
                seat_index = *prev + d;
            }
        }

        if (n - 1 - *students.rbegin() > distance)
            seat_index = n - 1;

        students.insert(seat_index);
        return seat_index;
    }

    void leave(int p) {
        students.erase(p);
    }
};
```
The ExamRoom class stores a ordered set of seat indices where students are sitting. When a student enters the room, we find the seat that maximizes distance to the closest student following these steps:
1. If the room is empty, the student sits at seat 0.
2. Iterate through the current seat indices to find the two adjacent seats with the maximum difference in indices. If we see a larger difference than the current maximum difference, we update the maximum distance and the seat index.
3. Check if sitting at the last seat (n-1) would result in a larger distance than the current maximum distance, and if so, update the seat index.
4. Insert the chosen seat index into our set.
5. When a student leaves, we remove that seat index from the set.

## A solution in Python

```python
from bisect import bisect_left, insort_left

class ExamRoom:

    def __init__(self, n: int):
        self.students = []
        self.n = n

    def seat(self) -> int:
        if not self.students:
            seat_index = 0
        else:
            distance, seat_index = self.students[0], 0

            for i in range(1, len(self.students)):
                d = (self.students[i] - self.students[i - 1]) // 2
                if d > distance:
                    distance = d
                    seat_index = self.students[i - 1] + d

            if self.n - 1 - self.students[-1] > distance:
                seat_index = self.n - 1

        insort_left(self.students, seat_index)
        return seat_index

    def leave(self, p: int) -> None:
        index = bisect_left(self.students, p)
        self.students.pop(index)
```
The ExamRoom class stores a ordered set of seat indices where students are sitting. When a student enters the room, we find the seat that maximizes distance to the closest student following these steps:
1. If the room is empty, the student sits at seat 0.
2. Iterate through the current seat indices to find the two adjacent seats with the maximum difference in indices. If we see a larger difference than the current maximum difference, we update the maximum distance and the seat index.
3. Check if sitting at the last seat (n-1) would result in a larger distance than the current maximum distance, and if so, update the seat index.
4. Insert the chosen seat index into our set.
5. When a student leaves, we remove that seat index from the set.

## A solution in Javascript

```javascript
class ExamRoom {
    constructor(n) {
        this.n = n;
        this.students = new Set();
    }

    seat() {
        if (this.students.size === 0) {
            this.students.add(0);
            return 0;
        }

        let distance = [...this.students][0], seatIndex = 0;

        for (let i = 0, prev = distance; i < this.students.size - 1; i++) {
            let srcArr = [...this.students.values()];
            let curr = srcArr[i + 1];
            let d = Math.floor((curr - prev) / 2);

            if (d > distance) {
                distance = d;
                seatIndex = prev + d;
            }
            prev = curr;
        }

        if (this.n - 1 - Array.from(this.students).pop() > distance)
            seatIndex = this.n - 1;

        this.students.add(seatIndex);
        return seatIndex;
    }

    leave(p) {
        this.students.delete(p);
    }
}
```
The ExamRoom class stores a ordered set of seat indices where students are sitting. When a student enters the room, we find the seat that maximizes distance to the closest student following these steps:
1. If the room is empty, the student sits at seat 0.
2. Iterate through the current seat indices to find the two adjacent seats with the maximum difference in indices. If we see a larger difference than the current maximum difference, we update the maximum distance and the seat index.
3. Check if sitting at the last seat (n-1) would result in a larger distance than the current maximum distance, and if so, update the seat index.
4. Insert the chosen seat index into our set.
5. When a student leaves, we remove that seat index from the set.


# Possible Bipartition

- slug: possible-bipartition
- difficulty: Medium

We want to split a group of `n` people (labeled from `1` to `n`) into two groups of **any size**. Each person may dislike some other people, and they should not go into the same group.

Given the integer `n` and the array `dislikes` where `dislikes[i] = [ai, bi]` indicates that the person labeled `ai` does not like the person labeled `bi`, return `true` _if it is possible to split everyone into two groups in this way_.

**Example 1:**

**Input:** n = 4, dislikes = \[\[1,2\],\[1,3\],\[2,4\]\]
**Output:** true
**Explanation:** The first group has \[1,4\], and the second group has \[2,3\].

**Example 2:**

**Input:** n = 3, dislikes = \[\[1,2\],\[1,3\],\[2,3\]\]
**Output:** false
**Explanation:** We need at least 3 groups to divide them. We cannot put them in two groups.

**Constraints:**

*   `1 <= n <= 2000`
*   `0 <= dislikes.length <= 104`
*   `dislikes[i].length == 2`
*   `1 <= ai < bi <= n`
*   All the pairs of `dislikes` are **unique**.

## A solution in Java

```java
int scoreOfParentheses(String s) {
    int score = 0, depth = 0;
    for (int i = 0; i < s.length(); i++) {
        if (s.charAt(i) == '(')
            depth++;
        else {
            depth--;
            if (s.charAt(i - 1) == '(')
                score += 1 << depth;
        }
    }
    return score;
}
```
The algorithm processes the given balanced parentheses string `s` in a single pass, keeping track of the current depth (number of open parentheses) and the current score. When an open parenthesis is encountered, the depth is incremented. When a close parenthesis is encountered, the depth is decremented. If the close parenthesis follows an open parenthesis, the pair contributes to the score according to the depth. The final score is returned.

## A solution in C++

```cpp
int scoreOfParentheses(string s) {
    int score = 0, depth = 0;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] == '(')
            depth++;
        else {
            depth--;
            if (s[i - 1] == '(')
                score += 1 << depth;
        }
    }
    return score;
}
```
The algorithm processes the given balanced parentheses string `s` in a single pass, keeping track of the current depth (number of open parentheses) and the current score. When an open parenthesis is encountered, the depth is incremented. When a close parenthesis is encountered, the depth is decremented. If the close parenthesis follows an open parenthesis, the pair contributes to the score according to the depth. The final score is returned.

## A solution in Python

```python
def scoreOfParentheses(s):
    score, depth = 0, 0
    for i in range(len(s)):
        if s[i] == '(':
            depth += 1
        else:
            depth -= 1
            if s[i - 1] == '(':
                score += 1 << depth
    return score
```
The algorithm processes the given balanced parentheses string `s` in a single pass, keeping track of the current depth (number of open parentheses) and the current score. When an open parenthesis is encountered, the depth is incremented. When a close parenthesis is encountered, the depth is decremented. If the close parenthesis follows an open parenthesis, the pair contributes to the score according to the depth. The final score is returned.

## A solution in Javascript

```javascript
function scoreOfParentheses(s) {
    let score = 0, depth = 0;
    for (let i = 0; i < s.length; i++) {
        if (s[i] === '(')
            depth++;
        else {
            depth--;
            if (s[i - 1] === '(')
                score += 1 << depth;
        }
    }
    return score;
}
```
The algorithm processes the given balanced parentheses string `s` in a single pass, keeping track of the current depth (number of open parentheses) and the current score. When an open parenthesis is encountered, the depth is incremented. When a close parenthesis is encountered, the depth is decremented. If the close parenthesis follows an open parenthesis, the pair contributes to the score according to the depth. The final score is returned.


# Super Egg Drop

- slug: super-egg-drop
- difficulty: Hard

You are given `k` identical eggs and you have access to a building with `n` floors labeled from `1` to `n`.

You know that there exists a floor `f` where `0 <= f <= n` such that any egg dropped at a floor **higher** than `f` will **break**, and any egg dropped **at or below** floor `f` will **not break**.

Each move, you may take an unbroken egg and drop it from any floor `x` (where `1 <= x <= n`). If the egg breaks, you can no longer use it. However, if the egg does not break, you may **reuse** it in future moves.

Return _the **minimum number of moves** that you need to determine **with certainty** what the value of_ `f` is.

**Example 1:**

**Input:** k = 1, n = 2
**Output:** 2
**Explanation:**
Drop the egg from floor 1. If it breaks, we know that f = 0.
Otherwise, drop the egg from floor 2. If it breaks, we know that f = 1.
If it does not break, then we know f = 2.
Hence, we need at minimum 2 moves to determine with certainty what the value of f is.

**Example 2:**

**Input:** k = 2, n = 6
**Output:** 3

**Example 3:**

**Input:** k = 3, n = 14
**Output:** 4

**Constraints:**

*   `1 <= k <= 100`
*   `1 <= n <= 104`

## A solution in Java

```java
import java.util.PriorityQueue;
import java.util.Arrays;

public double mincostToHireWorkers(int[] quality, int[] wage, int K) {
    int N = quality.length;
    double[][] workers = new double[N][2];
    for (int i = 0; i < N; ++i)
        workers[i] = new double[] {(double) wage[i] / quality[i], (double) quality[i]};

    Arrays.sort(workers, (a, b) -> Double.compare(a[0], b[0]));

    double ans = 1e60;
    int sumq = 0;
    PriorityQueue<Integer> pool = new PriorityQueue<>((a, b) -> -Integer.compare(a, b));
    for (double[] worker: workers) {
        pool.offer((int) worker[1]);
        sumq += worker[1];

        if (pool.size() > K)
            sumq -= pool.poll();

        if (pool.size() == K)
            ans = Math.min(ans, worker[0] * sumq);
    }

    return ans;
}
```
We represent each worker as a pair of `(wage / quality, quality)`. We sort these workers based on the wage-to-quality ratio, making it easier to track the cost of hiring each worker. The algorithm maintains a priority queue, which is initially empty. The total quality sum starts at 0.

We iterate through the sorted workers, for each worker:
1. Add their quality value to the max heap and increment the total quality sum.
2. If max heap size is greater than `k`, we subtract the largest quality value from the sum and pop it from the max heap.
3. If max heap size equals `k`, we update the result with the minimum of the current result and the product of the total quality sum and the current worker's wage-to-quality ratio.

Finally, we return the lowest cost.

## A solution in C++

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

double mincostToHireWorkers(std::vector<int>& quality, std::vector<int>& wage, int k) {
    std::vector<std::pair<double, int>> workers;
    for (int i = 0; i < quality.size(); i++) {
        workers.emplace_back((double)wage[i] / quality[i], quality[i]);
    }
    std::sort(workers.begin(), workers.end());

    int sum_quality = 0;
    double result = 1e60;
    std::priority_queue<int> pq;

    for (auto [ratio, q] : workers) {
        sum_quality += q;
        pq.push(q);

        if (pq.size() > k) {
            sum_quality -= pq.top();
            pq.pop();
        }

        if (pq.size() == k) {
            result = std::min(result, ratio * sum_quality);
        }
    }

    return result;
}
```
We represent each worker as a pair of `(wage / quality, quality)`. We sort these workers based on the wage-to-quality ratio, making it easier to track the cost of hiring each worker. The algorithm maintains a priority queue, which is initially empty. The total quality sum starts at 0.

We iterate through the sorted workers, for each worker:
1. Add their quality value to the max heap and increment the total quality sum.
2. If max heap size is greater than `k`, we subtract the largest quality value from the sum and pop it from the max heap.
3. If max heap size equals `k`, we update the result with the minimum of the current result and the product of the total quality sum and the current worker's wage-to-quality ratio.

Finally, we return the lowest cost.

## A solution in Python

```python
import heapq

def mincost_to_hire_workers(quality, wage, k):
    workers = sorted((w / q, q) for w, q in zip(wage, quality))
    total_quality = 0
    max_heap = []
    result = float("inf")

    for ratio, q in workers:
        heapq.heappush(max_heap, -q)
        total_quality += q

        if len(max_heap) > k:
            total_quality += heapq.heappop(max_heap)

        if len(max_heap) == k:
            result = min(result, total_quality * ratio)

    return result
```
We represent each worker as a pair of `(wage / quality, quality)`. We sort these workers based on the wage-to-quality ratio, making it easier to track the cost of hiring each worker. The algorithm maintains a priority queue, which is initially empty. The total quality sum starts at 0.

We iterate through the sorted workers, for each worker:
1. Add their quality value to the max heap and increment the total quality sum.
2. If max heap size is greater than `k`, we subtract the largest quality value from the sum and pop it from the max heap.
3. If max heap size equals `k`, we update the result with the minimum of the current result and the product of the total quality sum and the current worker's wage-to-quality ratio.

Finally, we return the lowest cost.

## A solution in Javascript

```javascript
function mincostToHireWorkers(quality, wage, K) {
    const workers = Array.from({length: quality.length}, (_, i) => [
        wage[i] / quality[i], quality[i],
    ]).sort((a, b) => a[0] - b[0]);

    let sumQuality = 0;
    const maxHeap = new MaxHeap(comparator);

    let result = Infinity;
    for (const [ratio, q] of workers) {
        maxHeap.add(q);
        sumQuality += q;

        if (maxHeap.size() > K) {
            sumQuality -= maxHeap.pop();
        }

        if (maxHeap.size() === K) {
            result = Math.min(result, ratio * sumQuality);
        }
    }

    return result;
}

class MaxHeap {
    constructor(comparator) {
        this._heap = [];
        this._comparator = comparator;
    }

    add(value) {
        this._heap.push(value);
        this.bubbleUp(this.size() - 1);
    }

    pop() {
        if (this.isEmpty()) return undefined;

        this.swap(0, this.size() - 1);
        const result = this._heap.pop();
        this.bubbleDown(0);
        return result;
    }

    size() {
        return this._heap.length;
    }

    isEmpty() {
        return this._heap.length === 0;
    }

    bubbleUp(index) {
        const parent = this.parent(index);
        if (parent >= 0 && this._compare(parent, index)) {
            this.swap(parent, index);
            this.bubbleUp(parent);
        }
    }

    bubbleDown(index) {
        const largest = this.maxChildIndex(index);
        if (largest !== -1 && this._compare(index, largest)) {
            this.swap(index, largest);
            this.bubbleDown(largest);
        }
    }

    parent(index) {
        return index <= 0 ? -1 : Math.floor((index - 1) / 2);
    }

    maxChildIndex(index) {
        const left = index * 2 + 1;
        const right = index * 2 + 2;
        if (left >= this.size()) return -1;

        if (right >= this.size()) return left;

        return this._compare(left, right) ? right : left;
    }

    swap(i, j) {
        [this._heap[i], this._heap[j]] = [this._heap[j], this._heap[i]];
    }

    _compare(i, j) {
        return this._comparator(this._heap[i], this._heap[j]);
    }
}

function comparator(a, b) {
    return a < b;
}
```
We represent each worker as a pair of `(wage / quality, quality)`. We sort these workers based on the wage-to-quality ratio, making it easier to track the cost of hiring each worker. The algorithm maintains a priority queue, which is initially empty. The total quality sum starts at 0.

We iterate through the sorted workers, for each worker:
1. Add their quality value to the max heap and increment the total quality sum.
2. If max heap size is greater than `k`, we subtract the largest quality value from the sum and pop it from the max heap.
3. If max heap size equals `k`, we update the result with the minimum of the current result and the product of the total quality sum and the current worker's wage-to-quality ratio.

Finally, we return the lowest cost.


# Fair Candy Swap

- slug: fair-candy-swap
- difficulty: Easy

Alice and Bob have a different total number of candies. You are given two integer arrays `aliceSizes` and `bobSizes` where `aliceSizes[i]` is the number of candies of the `ith` box of candy that Alice has and `bobSizes[j]` is the number of candies of the `jth` box of candy that Bob has.

Since they are friends, they would like to exchange one candy box each so that after the exchange, they both have the same total amount of candy. The total amount of candy a person has is the sum of the number of candies in each box they have.

Return a_n integer array_ `answer` _where_ `answer[0]` _is the number of candies in the box that Alice must exchange, and_ `answer[1]` _is the number of candies in the box that Bob must exchange_. If there are multiple answers, you may **return any** one of them. It is guaranteed that at least one answer exists.

**Example 1:**

**Input:** aliceSizes = \[1,1\], bobSizes = \[2,2\]
**Output:** \[1,2\]

**Example 2:**

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

**Example 3:**

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

**Constraints:**

*   `1 <= aliceSizes.length, bobSizes.length <= 104`
*   `1 <= aliceSizes[i], bobSizes[j] <= 105`
*   Alice and Bob have a different total number of candies.
*   There will be at least one valid answer for the given input.

## A solution in Java

```java
public int mirrorReflection(int p, int q) {
    int m = p, n = q;
    int gcd;
    while (n != 0) {
        gcd = m % n;
        m = n;
        n = gcd;
    }

    if ((p / m) % 2 == 0) return 2;
    if ((q / m) % 2 == 0) return 0;
    return 1;
}
```
To solve this problem, we first determine the Lowest Common Multiple (LCM) of p and q. However, instead of finding LCM directly, it's simpler to first find the Greatest Common Divisor (GCD) and divide p and q by the GCD.

Next, we check if p divided by the GCD is an even number. If it is, the ray first meets receptor 2. If q divided by the GCD is even, the ray first meets receptor 0. Otherwise, the ray first meets receptor 1.

The algorithm remains the same across all languages, with only minor syntax differences between them. The key is to find the GCD and then further process p and q to identify which receptor the ray meets first.

## A solution in C++

```cpp
int mirrorReflection(int p, int q) {
    int m = p, n = q;
    int gcd;
    while (n) {
        gcd = m % n;
        m = n;
        n = gcd;
    }

    if ((p / m) % 2 == 0) return 2;
    if ((q / m) % 2 == 0) return 0;
    return 1;
}
```
To solve this problem, we first determine the Lowest Common Multiple (LCM) of p and q. However, instead of finding LCM directly, it's simpler to first find the Greatest Common Divisor (GCD) and divide p and q by the GCD.

Next, we check if p divided by the GCD is an even number. If it is, the ray first meets receptor 2. If q divided by the GCD is even, the ray first meets receptor 0. Otherwise, the ray first meets receptor 1.

The algorithm remains the same across all languages, with only minor syntax differences between them. The key is to find the GCD and then further process p and q to identify which receptor the ray meets first.

## A solution in Python

```python
def mirrorReflection(p, q):
    from math import gcd
    m = p // gcd(p, q)

    if m % 2 == 0:
        return 2
    if (q // gcd(p, q)) % 2 == 0:
        return 0
    return 1
```
To solve this problem, we first determine the Lowest Common Multiple (LCM) of p and q. However, instead of finding LCM directly, it's simpler to first find the Greatest Common Divisor (GCD) and divide p and q by the GCD.

Next, we check if p divided by the GCD is an even number. If it is, the ray first meets receptor 2. If q divided by the GCD is even, the ray first meets receptor 0. Otherwise, the ray first meets receptor 1.

The algorithm remains the same across all languages, with only minor syntax differences between them. The key is to find the GCD and then further process p and q to identify which receptor the ray meets first.

## A solution in Javascript

```javascript
function mirrorReflection(p, q) {
    function gcd(a, b) {
        return b === 0 ? a : gcd(b, a % b);
    }
    let m = p / gcd(p, q);

    if (m % 2 === 0) return 2;
    if ((q / gcd(p, q)) % 2 === 0) return 0;
    return 1;
}
```
To solve this problem, we first determine the Lowest Common Multiple (LCM) of p and q. However, instead of finding LCM directly, it's simpler to first find the Greatest Common Divisor (GCD) and divide p and q by the GCD.

Next, we check if p divided by the GCD is an even number. If it is, the ray first meets receptor 2. If q divided by the GCD is even, the ray first meets receptor 0. Otherwise, the ray first meets receptor 1.

The algorithm remains the same across all languages, with only minor syntax differences between them. The key is to find the GCD and then further process p and q to identify which receptor the ray meets first.


# Construct Binary Tree from Preorder and Postorder Traversal

- slug: construct-binary-tree-from-preorder-and-postorder-traversal
- difficulty: Medium

Given two integer arrays, `preorder` and `postorder` where `preorder` is the preorder traversal of a binary tree of **distinct** values and `postorder` is the postorder traversal of the same tree, reconstruct and return _the binary tree_.

If there exist multiple answers, you can **return any** of them.

**Example 1:**

**Input:** preorder = \[1,2,4,5,3,6,7\], postorder = \[4,5,2,6,7,3,1\]
**Output:** \[1,2,3,4,5,6,7\]

**Example 2:**

**Input:** preorder = \[1\], postorder = \[1\]
**Output:** \[1\]

**Constraints:**

*   `1 <= preorder.length <= 30`
*   `1 <= preorder[i] <= preorder.length`
*   All the values of `preorder` are **unique**.
*   `postorder.length == preorder.length`
*   `1 <= postorder[i] <= postorder.length`
*   All the values of `postorder` are **unique**.
*   It is guaranteed that `preorder` and `postorder` are the preorder traversal and postorder traversal of the same binary tree.

## A solution in Java

```java
public boolean areAlmostEqual(String s, String goal) {
    if (s.equals(goal)) return true;
    int count = 0;
    int index1 = -1, index2 = -1;
    for (int i = 0; i < s.length(); i++) {
        if (s.charAt(i) != goal.charAt(i)) {
            count++;
            if (index1 == -1) index1 = i;
            else index2 = i;
            if (count > 2) return false;
        }
    }
    return (count == 2 && s.charAt(index1) == goal.charAt(index2) && s.charAt(index2) == goal.charAt(index1));
}
```
We first check if both the strings are already equal. If yes, return true. Otherwise, initialize the count of differences, and two indices index1 and index2 to -1. Iterate through the strings, if a character of s is not equal to the corresponding character of goal, increment the count and update the indices. If the count exceeds 2, return false, as swapping only 2 characters cannot make the strings equal. Finally, return true if the count is 2, and swapping the characters at index1 and index2 makes the strings equal. Else, return false.

## A solution in C++

```cpp
bool areAlmostEqual(std::string s, std::string goal) {
    if (s == goal) return true;
    int count = 0;
    int index1 = -1, index2 = -1;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] != goal[i]) {
            count++;
            if (index1 == -1) index1 = i;
            else index2 = i;
            if (count > 2) return false;
        }
    }
    return (count == 2 && s[index1] == goal[index2] && s[index2] == goal[index1]);
}
```
We first check if both the strings are already equal. If yes, return true. Otherwise, initialize the count of differences, and two indices index1 and index2 to -1. Iterate through the strings, if a character of s is not equal to the corresponding character of goal, increment the count and update the indices. If the count exceeds 2, return false, as swapping only 2 characters cannot make the strings equal. Finally, return true if the count is 2, and swapping the characters at index1 and index2 makes the strings equal. Else, return false.

## A solution in Python

```python
def are_almost_equal(s, goal):
    if s == goal:
        return True
    count = 0
    index1, index2 = -1, -1
    for i in range(len(s)):
        if s[i] != goal[i]:
            count += 1
            if index1 == -1:
                index1 = i
            else:
                index2 = i
            if count > 2:
                return False
    return count == 2 and s[index1] == goal[index2] and s[index2] == goal[index1]
```
We first check if both the strings are already equal. If yes, return true. Otherwise, initialize the count of differences, and two indices index1 and index2 to -1. Iterate through the strings, if a character of s is not equal to the corresponding character of goal, increment the count and update the indices. If the count exceeds 2, return false, as swapping only 2 characters cannot make the strings equal. Finally, return true if the count is 2, and swapping the characters at index1 and index2 makes the strings equal. Else, return false.

## A solution in Javascript

```javascript
function areAlmostEqual(s, goal) {
    if (s === goal) return true;
    let count = 0;
    let index1 = -1, index2 = -1;
    for (let i = 0; i < s.length; i++) {
        if (s[i] !== goal[i]) {
            count++;
            if (index1 === -1) index1 = i;
            else index2 = i;
            if (count > 2) return false;
        }
    }
    return (count === 2 && s[index1] === goal[index2] && s[index2] === goal[index1]);
}
```
We first check if both the strings are already equal. If yes, return true. Otherwise, initialize the count of differences, and two indices index1 and index2 to -1. Iterate through the strings, if a character of s is not equal to the corresponding character of goal, increment the count and update the indices. If the count exceeds 2, return false, as swapping only 2 characters cannot make the strings equal. Finally, return true if the count is 2, and swapping the characters at index1 and index2 makes the strings equal. Else, return false.


# Find and Replace Pattern

- slug: find-and-replace-pattern
- difficulty: Medium

Given a list of strings `words` and a string `pattern`, return _a list of_ `words[i]` _that match_ `pattern`. You may return the answer in **any order**.

A word matches the pattern if there exists a permutation of letters `p` so that after replacing every letter `x` in the pattern with `p(x)`, we get the desired word.

Recall that a permutation of letters is a bijection from letters to letters: every letter maps to another letter, and no two letters map to the same letter.

**Example 1:**

**Input:** words = \[ "abc ", "deq ", "mee ", "aqq ", "dkd ", "ccc "\], pattern =  "abb "
**Output:** \[ "mee ", "aqq "\]
**Explanation:**  "mee " matches the pattern because there is a permutation {a -> m, b -> e, ...}.
 "ccc " does not match the pattern because {a -> c, b -> c, ...} is not a permutation, since a and b map to the same letter.

**Example 2:**

**Input:** words = \[ "a ", "b ", "c "\], pattern =  "a "
**Output:** \[ "a ", "b ", "c "\]

**Constraints:**

*   `1 <= pattern.length <= 20`
*   `1 <= words.length <= 50`
*   `words[i].length == pattern.length`
*   `pattern` and `words[i]` are lowercase English letters.

## A solution in Java

```java
public boolean lemonadeChange(int[] bills) {
    int five = 0, ten = 0;
    for (int bill : bills) {
        if (bill == 5)
            five++;
        else if (bill == 10) {
            if (five == 0) return false;
            five--;
            ten++;
        } else {
            if (ten > 0 && five > 0) {
                ten--;
                five--;
            } else if (five >= 3)
                five -= 3;
            else
                return false;
        }
    }
    return true;
}
```
We initialize two variables `five` and `ten` to count the number of $5 and $10 bills we have as change. Then we iterate through each customer's bill in the `bills` array. If they pay with a $5 bill, we just increment the `five` counter. If they pay with a $10 bill, we check if we have any $5 bills to give as change; if so, we decrement the `five` counter and increment the `ten` counter, otherwise we return false. If they pay with a $20 bill, we check if we have one $10 and one $5 bill or three $5 bills to provide as change; if so, we update the counters accordingly, otherwise we return false. If we successfully go through the whole array, we return true as we were able to provide change for every customer.

## A solution in C++

```cpp
bool lemonadeChange(std::vector<int>& bills) {
    int five = 0, ten = 0;
    for (int bill : bills) {
        if (bill == 5)
            five++;
        else if (bill == 10) {
            if (!five) return false;
            five--;
            ten++;
        } else {
            if (ten && five) {
                ten--;
                five--;
            } else if (five >= 3)
                five -= 3;
            else
                return false;
        }
    }
    return true;
}
```
We initialize two variables `five` and `ten` to count the number of $5 and $10 bills we have as change. Then we iterate through each customer's bill in the `bills` array. If they pay with a $5 bill, we just increment the `five` counter. If they pay with a $10 bill, we check if we have any $5 bills to give as change; if so, we decrement the `five` counter and increment the `ten` counter, otherwise we return false. If they pay with a $20 bill, we check if we have one $10 and one $5 bill or three $5 bills to provide as change; if so, we update the counters accordingly, otherwise we return false. If we successfully go through the whole array, we return true as we were able to provide change for every customer.

## A solution in Python

```python
def lemonadeChange(bills):
    five, ten = 0, 0
    for bill in bills:
        if bill == 5:
            five += 1
        elif bill == 10:
            if not five:
                return False
            five -= 1
            ten += 1
        else:
            if ten and five:
                ten -= 1
                five -= 1
            elif five >= 3:
                five -= 3
            else:
                return False
    return True
```
We initialize two variables `five` and `ten` to count the number of $5 and $10 bills we have as change. Then we iterate through each customer's bill in the `bills` array. If they pay with a $5 bill, we just increment the `five` counter. If they pay with a $10 bill, we check if we have any $5 bills to give as change; if so, we decrement the `five` counter and increment the `ten` counter, otherwise we return false. If they pay with a $20 bill, we check if we have one $10 and one $5 bill or three $5 bills to provide as change; if so, we update the counters accordingly, otherwise we return false. If we successfully go through the whole array, we return true as we were able to provide change for every customer.

## A solution in Javascript

```javascript
function lemonadeChange(bills) {
    let five = 0, ten = 0;
    for (let bill of bills) {
        if (bill === 5)
            five++;
        else if (bill === 10) {
            if (five === 0) return false;
            five--;
            ten++;
        } else {
            if (ten > 0 && five > 0) {
                ten--;
                five--;
            } else if (five >= 3)
                five -= 3;
            else
                return false;
        }
    }
    return true;
}
```
We initialize two variables `five` and `ten` to count the number of $5 and $10 bills we have as change. Then we iterate through each customer's bill in the `bills` array. If they pay with a $5 bill, we just increment the `five` counter. If they pay with a $10 bill, we check if we have any $5 bills to give as change; if so, we decrement the `five` counter and increment the `ten` counter, otherwise we return false. If they pay with a $20 bill, we check if we have one $10 and one $5 bill or three $5 bills to provide as change; if so, we update the counters accordingly, otherwise we return false. If we successfully go through the whole array, we return true as we were able to provide change for every customer.


# Sum of Subsequence Widths

- slug: sum-of-subsequence-widths
- difficulty: Hard

The **width** of a sequence is the difference between the maximum and minimum elements in the sequence.

Given an array of integers `nums`, return _the sum of the **widths** of all the non-empty **subsequences** of_ `nums`. Since the answer may be very large, return it **modulo** `109 + 7`.

A **subsequence** is a sequence that can be derived from an array by deleting some or no elements without changing the order of the remaining elements. For example, `[3,6,2,7]` is a subsequence of the array `[0,3,1,6,2,2,7]`.

**Example 1:**

**Input:** nums = \[2,1,3\]
**Output:** 6
Explanation: The subsequences are \[1\], \[2\], \[3\], \[2,1\], \[2,3\], \[1,3\], \[2,1,3\].
The corresponding widths are 0, 0, 0, 1, 1, 2, 2.
The sum of these widths is 6.

**Example 2:**

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

**Constraints:**

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

## A solution in Java

```java
public int matrixScore(int[][] grid) {
    int m = grid.length, n = grid[0].length;
    for (int i = 0; i < m; i++) {
        if (grid[i][0] == 0) {
            for (int j = 0; j < n; j++) {
                grid[i][j] = 1 - grid[i][j];
            }
        }
    }
    for (int j = 1; j < n; j++) {
        int count = 0;
        for (int i = 0; i < m; i++) {
            count += grid[i][j];
        }
        if (count <= m / 2) {
            for (int i = 0; i < m; i++) {
                grid[i][j] = 1 - grid[i][j];
            }
        }
    }
    int sum = 0;
    for (int i = 0; i < m; i++) {
        int num = 0;
        for (int j = 0; j < n; j++) {
            num = num * 2 + grid[i][j];
        }
        sum += num;
    }
    return sum;
}
```
The algorithm begins by looping through each row and checking if the first element is 0. If it is, we toggle the row values to ensure the row starts with 1. This way, we maximize the values of the binary numbers represented by each row.

Next, we loop through the columns (starting with the second), and for each column, we calculate the count of 1s. If the count is less than or equal to half the number of rows, we toggle the entire column.

Finally, we loop through the modified grid again, summing up the binary numbers represented by each row to get the highest possible score.

## A solution in C++

```cpp
int matrixScore(std::vector<std::vector<int>>& grid) {
    int m = grid.size(), n = grid[0].size();
    for(int i = 0; i < m; i++) {
        if(grid[i][0] == 0) {
            for(int j = 0; j < n; j++) {
                grid[i][j] = 1 - grid[i][j];
            }
        }
    }
    for(int j = 1; j < n; j++) {
        int count = 0;
        for(int i = 0; i < m; i++) {
            count += grid[i][j];
        }
        if(count <= m / 2) {
            for(int i = 0; i < m; i++) {
                grid[i][j] = 1 - grid[i][j];
            }
        }
    }
    int sum = 0;
    for(int i = 0; i < m; i++) {
        int num = 0;
        for(int j = 0; j < n; j++) {
            num = num * 2 + grid[i][j];
        }
        sum += num;
    }
    return sum;
}
```
The algorithm begins by looping through each row and checking if the first element is 0. If it is, we toggle the row values to ensure the row starts with 1. This way, we maximize the values of the binary numbers represented by each row.

Next, we loop through the columns (starting with the second), and for each column, we calculate the count of 1s. If the count is less than or equal to half the number of rows, we toggle the entire column.

Finally, we loop through the modified grid again, summing up the binary numbers represented by each row to get the highest possible score.

## A solution in Python

```python
def matrixScore(grid):
    m, n = len(grid), len(grid[0])
    for i in range(m):
        if grid[i][0] == 0:
            for j in range(n):
                grid[i][j] = 1 - grid[i][j]
    for j in range(1, n):
        count = sum(grid[i][j] for i in range(m))
        if count <= m // 2:
            for i in range(m):
                grid[i][j] = 1 - grid[i][j]
    return sum(sum(grid[i][j]*(1 << (n - 1 - j)) for j in range(n)) for i in range(m))
```
The algorithm begins by looping through each row and checking if the first element is 0. If it is, we toggle the row values to ensure the row starts with 1. This way, we maximize the values of the binary numbers represented by each row.

Next, we loop through the columns (starting with the second), and for each column, we calculate the count of 1s. If the count is less than or equal to half the number of rows, we toggle the entire column.

Finally, we loop through the modified grid again, summing up the binary numbers represented by each row to get the highest possible score.

## A solution in Javascript

```javascript
function matrixScore(grid) {
    const m = grid.length, n = grid[0].length;
    for (let i = 0; i < m; i++) {
        if (grid[i][0] === 0) {
            for (let j = 0; j < n; j++) {
                grid[i][j] = 1 - grid[i][j];
            }
        }
    }
    for (let j = 1; j < n; j++) {
        let count = 0;
        for (let i = 0; i < m; i++) {
            count += grid[i][j];
        }
        if (count <= m / 2) {
            for (let i = 0; i < m; i++) {
                grid[i][j] = 1 - grid[i][j];
            }
        }
    }
    let sum = 0;
    for (let i = 0; i < m; i++) {
        let num = 0;
        for (let j = 0; j < n; j++) {
            num = num * 2 + grid[i][j];
        }
        sum += num;
    }
    return sum;
}
```
The algorithm begins by looping through each row and checking if the first element is 0. If it is, we toggle the row values to ensure the row starts with 1. This way, we maximize the values of the binary numbers represented by each row.

Next, we loop through the columns (starting with the second), and for each column, we calculate the count of 1s. If the count is less than or equal to half the number of rows, we toggle the entire column.

Finally, we loop through the modified grid again, summing up the binary numbers represented by each row to get the highest possible score.


# Surface Area of 3D Shapes

- slug: surface-area-of-3d-shapes
- difficulty: Easy

You are given an `n x n` `grid` where you have placed some `1 x 1 x 1` cubes. Each value `v = grid[i][j]` represents a tower of `v` cubes placed on top of cell `(i, j)`.

After placing these cubes, you have decided to glue any directly adjacent cubes to each other, forming several irregular 3D shapes.

Return _the total surface area of the resulting shapes_.

**Note:** The bottom face of each shape counts toward its surface area.

**Example 1:**

**Input:** grid = \[\[1,2\],\[3,4\]\]
**Output:** 34

**Example 2:**

**Input:** grid = \[\[1,1,1\],\[1,0,1\],\[1,1,1\]\]
**Output:** 32

**Example 3:**

**Input:** grid = \[\[2,2,2\],\[2,1,2\],\[2,2,2\]\]
**Output:** 46

**Constraints:**

*   `n == grid.length == grid[i].length`
*   `1 <= n <= 50`
*   `0 <= grid[i][j] <= 50`

## A solution in Java

```java
import java.util.ArrayDeque;
import java.util.Deque;

public int shortestSubarray(int[] nums, int k) {
    int n = nums.length;
    int[] prefixSum = new int[n + 1];
    for (int i = 0; i < n; i++) prefixSum[i + 1] = prefixSum[i] + nums[i];

    int res = n + 1;
    Deque<Integer> dq = new ArrayDeque<>();
    for (int i = 0; i < n + 1; i++) {
        while (!dq.isEmpty() && prefixSum[i] - prefixSum[dq.peek()] >= k) {
            res = Math.min(res, i - dq.poll());
        }
        while (!dq.isEmpty() && prefixSum[i] <= prefixSum[dq.peekLast()]) {
            dq.pollLast();
        }
        dq.offer(i);
    }
    return res <= n ? res : -1;
}
```
The algorithm first calculates the prefix sum of the array. Then, it initializes a double-ended queue (deque) to store indices of the prefix sum. For each index of the calculated prefix sum, perform these steps:

1. Check if the current prefix sum minus the prefix sum at the front of the deque is greater than or equal to `k`. If true, update the result with the minimum value. This means we found a subarray that meets the requirement of sum >= k, so we remove the deque's front element to see if there's a shorter subarray.
2. In an increasing order within the deque, check if the current prefix sum is less than or equal to the prefix sum at the back of deque. If true, remove the last element. The goal here is to maintain each element of the deque in increasing order.
3. Add the index to the deque.

Finally, after iterating through all elements, check if the stored result is valid. If valid, return the result; otherwise, return -1. This logic is implemented in all 4 language solutions.

## A solution in C++

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

int shortestSubarray(vector<int>& nums, int k) {
    int n = nums.size();
    vector<int> prefix_sum(n + 1, 0);
    for (int i = 0; i < n; i++) prefix_sum[i + 1] = prefix_sum[i] + nums[i];

    int res = n + 1;
    deque<int> dq;
    for (int i = 0; i < n + 1; i++) {
        while (!dq.empty() && prefix_sum[i] - prefix_sum[dq.front()] >= k) {
            res = min(res, i - dq.front());
            dq.pop_front();
        }
        while (!dq.empty() && prefix_sum[i] <= prefix_sum[dq.back()]) {
            dq.pop_back();
        }
        dq.push_back(i);
    }
    return res <= n ? res : -1;
}
```
The algorithm first calculates the prefix sum of the array. Then, it initializes a double-ended queue (deque) to store indices of the prefix sum. For each index of the calculated prefix sum, perform these steps:

1. Check if the current prefix sum minus the prefix sum at the front of the deque is greater than or equal to `k`. If true, update the result with the minimum value. This means we found a subarray that meets the requirement of sum >= k, so we remove the deque's front element to see if there's a shorter subarray.
2. In an increasing order within the deque, check if the current prefix sum is less than or equal to the prefix sum at the back of deque. If true, remove the last element. The goal here is to maintain each element of the deque in increasing order.
3. Add the index to the deque.

Finally, after iterating through all elements, check if the stored result is valid. If valid, return the result; otherwise, return -1. This logic is implemented in all 4 language solutions.

## A solution in Python

```python
from collections import deque

def shortest_subarray(nums, k):
    n = len(nums)
    prefix_sum = [0] * (n + 1)
    for i in range(n):
        prefix_sum[i + 1] = prefix_sum[i] + nums[i]

    res = n + 1
    dq = deque()
    for i in range(n + 1):
        while dq and prefix_sum[i] - prefix_sum[dq[0]] >= k:
            res = min(res, i - dq.popleft())
        while dq and prefix_sum[i] <= prefix_sum[dq[-1]]:
            dq.pop()
        dq.append(i)

    return res if res <= n else -1
```
The algorithm first calculates the prefix sum of the array. Then, it initializes a double-ended queue (deque) to store indices of the prefix sum. For each index of the calculated prefix sum, perform these steps:

1. Check if the current prefix sum minus the prefix sum at the front of the deque is greater than or equal to `k`. If true, update the result with the minimum value. This means we found a subarray that meets the requirement of sum >= k, so we remove the deque's front element to see if there's a shorter subarray.
2. In an increasing order within the deque, check if the current prefix sum is less than or equal to the prefix sum at the back of deque. If true, remove the last element. The goal here is to maintain each element of the deque in increasing order.
3. Add the index to the deque.

Finally, after iterating through all elements, check if the stored result is valid. If valid, return the result; otherwise, return -1. This logic is implemented in all 4 language solutions.

## A solution in Javascript

```javascript
function shortestSubarray(nums, k) {
    const n = nums.length;
    const prefixSum = new Array(n + 1).fill(0);
    for (let i = 0; i < n; i++) prefixSum[i + 1] = prefixSum[i] + nums[i];

    let res = n + 1;
    const dq = [];
    for (let i = 0; i < n + 1; i++) {
        while (dq.length > 0 && prefixSum[i] - prefixSum[dq[0]] >= k) {
            res = Math.min(res, i - dq.shift());
        }
        while (dq.length > 0 && prefixSum[i] <= prefixSum[dq[dq.length - 1]]) {
            dq.pop();
        }
        dq.push(i);
    }
    return res <= n ? res : -1;
}
```
The algorithm first calculates the prefix sum of the array. Then, it initializes a double-ended queue (deque) to store indices of the prefix sum. For each index of the calculated prefix sum, perform these steps:

1. Check if the current prefix sum minus the prefix sum at the front of the deque is greater than or equal to `k`. If true, update the result with the minimum value. This means we found a subarray that meets the requirement of sum >= k, so we remove the deque's front element to see if there's a shorter subarray.
2. In an increasing order within the deque, check if the current prefix sum is less than or equal to the prefix sum at the back of deque. If true, remove the last element. The goal here is to maintain each element of the deque in increasing order.
3. Add the index to the deque.

Finally, after iterating through all elements, check if the stored result is valid. If valid, return the result; otherwise, return -1. This logic is implemented in all 4 language solutions.


# Groups of Special-Equivalent Strings

- slug: groups-of-special-equivalent-strings
- difficulty: Medium

You are given an array of strings of the same length `words`.

In one **move**, you can swap any two even indexed characters or any two odd indexed characters of a string `words[i]`.

Two strings `words[i]` and `words[j]` are **special-equivalent** if after any number of moves, `words[i] == words[j]`.

*   For example, `words[i] = "zzxy "` and `words[j] = "xyzz "` are **special-equivalent** because we may make the moves `"zzxy " -> "xzzy " -> "xyzz "`.

A **group of special-equivalent strings** from `words` is a non-empty subset of words such that:

*   Every pair of strings in the group are special equivalent, and
*   The group is the largest size possible (i.e., there is not a string `words[i]` not in the group such that `words[i]` is special-equivalent to every string in the group).

Return _the number of **groups of special-equivalent strings** from_ `words`.

**Example 1:**

**Input:** words = \[ "abcd ", "cdab ", "cbad ", "xyzz ", "zzxy ", "zzyx "\]
**Output:** 3
**Explanation:**
One group is \[ "abcd ",  "cdab ",  "cbad "\], since they are all pairwise special equivalent, and none of the other strings is all pairwise special equivalent to these.
The other two groups are \[ "xyzz ",  "zzxy "\] and \[ "zzyx "\].
Note that in particular,  "zzxy " is not special equivalent to  "zzyx ".

**Example 2:**

**Input:** words = \[ "abc ", "acb ", "bac ", "bca ", "cab ", "cba "\]
**Output:** 3

**Constraints:**

*   `1 <= words.length <= 1000`
*   `1 <= words[i].length <= 20`
*   `words[i]` consist of lowercase English letters.
*   All the strings are of the same length.

## A solution in Java

```java
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public List<Integer> findNodesAtDistanceK(TreeNode root, int targetVal, int k) {
    if (k < 0) return new ArrayList<>();
    Map<TreeNode, TreeNode> parentMap = new HashMap<>();
    Set<TreeNode> visited = new HashSet<>();
    TreeNode targetNode = initializeParentMap(root, null, targetVal, parentMap);

    List<Integer> result = new ArrayList<>();
    findNodesAtDistanceKHelper(targetNode, k, visited, parentMap, result);
    return result;
}

private TreeNode initializeParentMap(TreeNode node, TreeNode parent, int targetVal, Map<TreeNode, TreeNode> parentMap) {
    if (node == null) return null;
    if (node.val == targetVal) return node;
    parentMap.put(node, parent);
    TreeNode left = initializeParentMap(node.left, node, targetVal, parentMap);
    TreeNode right = initializeParentMap(node.right, node, targetVal, parentMap);
    return left != null ? left : right;
}

private void findNodesAtDistanceKHelper(TreeNode node, int k, Set<TreeNode> visited, Map<TreeNode, TreeNode> parentMap, List<Integer> result) {
    if (node == null || visited.contains(node)) return;
    visited.add(node);
    if (k == 0) {
        result.add(node.val);
        return;
    }

    findNodesAtDistanceKHelper(node.left, k-1, visited, parentMap, result);
    findNodesAtDistanceKHelper(node.right, k-1, visited, parentMap, result);
    findNodesAtDistanceKHelper(parentMap.get(node), k-1, visited, parentMap, result);
}
```
This algorithm first creates a mapping of each node to its parent. This is done through the `initializeParentMap()` function which also finds the `targetNode` as it traverses the tree. When running the function, the parent map is built, mapping a node to its parent, and the target node with the required value is found. Once we have the targetNode and parentMap, we start the search for nodes at distance k using DFS approach starting from the targetNode. We use the `findNodesAtDistanceKHelper()` function that takes the current node, distance k, visited set (to avoid infinite looping), and the parentMap. If k is 0, we add the node's value into the result array. If not, we continue DFS for the left and right children, and also the parent (using the parentMap), with the updated k value (k-1). Finally, the result array containing values of nodes at distance k is returned.

## A solution in C++

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

struct TreeNode {
  int val;
  TreeNode *left;
  TreeNode *right;
  TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

vector<int> findNodesAtDistanceK(TreeNode* root, int targetVal, int k) {
    if (k < 0) return {};
    unordered_map<TreeNode*, TreeNode*> parentMap;
    unordered_set<TreeNode*> visited;
    TreeNode* targetNode = nullptr;
    initializeParentMap(root, nullptr, targetVal, parentMap, targetNode);

    vector<int> result;
    findNodesAtDistanceKHelper(targetNode, k, visited, parentMap, result);
    return result;
}

void initializeParentMap(TreeNode* node, TreeNode* parent, int targetVal, unordered_map<TreeNode*, TreeNode*> &parentMap, TreeNode* &targetNode) {
    if (!node || targetNode) return;
    if (node->val == targetVal) targetNode = node;
    parentMap[node] = parent;
    initializeParentMap(node->left, node, targetVal, parentMap, targetNode);
    initializeParentMap(node->right, node, targetVal, parentMap, targetNode);
}

void findNodesAtDistanceKHelper(TreeNode* node, int k, unordered_set<TreeNode*> &visited, unordered_map<TreeNode*, TreeNode*> &parentMap, vector<int> &result) {
    if (!node || visited.count(node)) return;
    visited.insert(node);
    if (k == 0) {
        result.push_back(node->val);
        return;
    }

    findNodesAtDistanceKHelper(node->left, k-1, visited, parentMap, result);
    findNodesAtDistanceKHelper(node->right, k-1, visited, parentMap, result);
    findNodesAtDistanceKHelper(parentMap[node], k-1, visited, parentMap, result);
}
```
This algorithm first creates a mapping of each node to its parent. This is done through the `initializeParentMap()` function which also finds the `targetNode` as it traverses the tree. When running the function, the parent map is built, mapping a node to its parent, and the target node with the required value is found. Once we have the targetNode and parentMap, we start the search for nodes at distance k using DFS approach starting from the targetNode. We use the `findNodesAtDistanceKHelper()` function that takes the current node, distance k, visited set (to avoid infinite looping), and the parentMap. If k is 0, we add the node's value into the result array. If not, we continue DFS for the left and right children, and also the parent (using the parentMap), with the updated k value (k-1). Finally, the result array containing values of nodes at distance k is returned.

## A solution in Python

```python
from collections import defaultdict

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

def find_nodes_at_distance_k(root, target_val, k):
    if k < 0:
        return []

    parent_map = defaultdict(lambda: None)
    visited = set()
    target_node = initialize_parent_map(root, None, target_val, parent_map)

    result = []
    find_nodes_at_distance_k_helper(target_node, k, visited, parent_map, result)
    return result

def initialize_parent_map(node, parent, target_val, parent_map):
    if not node:
        return None
    if node.val == target_val:
        return node

    parent_map[node] = parent
    left = initialize_parent_map(node.left, node, target_val, parent_map)
    right = initialize_parent_map(node.right, node, target_val, parent_map)
    return left if left else right

def find_nodes_at_distance_k_helper(node, k, visited, parent_map, result):
    if not node or node in visited:
        return

    visited.add(node)
    if k == 0:
        result.append(node.val)
        return

    find_nodes_at_distance_k_helper(node.left, k-1, visited, parent_map, result)
    find_nodes_at_distance_k_helper(node.right, k-1, visited, parent_map, result)
    find_nodes_at_distance_k_helper(parent_map[node], k-1, visited, parent_map, result)
```
This algorithm first creates a mapping of each node to its parent. This is done through the `initializeParentMap()` function which also finds the `targetNode` as it traverses the tree. When running the function, the parent map is built, mapping a node to its parent, and the target node with the required value is found. Once we have the targetNode and parentMap, we start the search for nodes at distance k using DFS approach starting from the targetNode. We use the `findNodesAtDistanceKHelper()` function that takes the current node, distance k, visited set (to avoid infinite looping), and the parentMap. If k is 0, we add the node's value into the result array. If not, we continue DFS for the left and right children, and also the parent (using the parentMap), with the updated k value (k-1). Finally, the result array containing values of nodes at distance k is returned.

## A solution in Javascript

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

function findNodesAtDistanceK(root, targetVal, k) {
    if (k < 0) return [];

    let parentMap = new Map();
    let visited = new Set();
    let targetNode = initializeParentMap(root, null, targetVal, parentMap);

    let result = [];
    findNodesAtDistanceKHelper(targetNode, k, visited, parentMap, result);
    return result;
}

function initializeParentMap(node, parent, targetVal, parentMap) {
    if (!node) return null;
    if (node.val === targetVal) return node;

    parentMap.set(node, parent);
    let left = initializeParentMap(node.left, node, targetVal, parentMap);
    let right = initializeParentMap(node.right, node, targetVal, parentMap);
    return left ? left : right;
}

function findNodesAtDistanceKHelper(node, k, visited, parentMap, result) {
    if (!node || visited.has(node)) return;

    visited.add(node);
    if (k === 0) {
        result.push(node.val);
        return;
    }

    findNodesAtDistanceKHelper(node.left, k - 1, visited, parentMap, result);
    findNodesAtDistanceKHelper(node.right, k - 1, visited, parentMap, result);
    findNodesAtDistanceKHelper(parentMap.get(node), k - 1, visited, parentMap, result);
}
```
This algorithm first creates a mapping of each node to its parent. This is done through the `initializeParentMap()` function which also finds the `targetNode` as it traverses the tree. When running the function, the parent map is built, mapping a node to its parent, and the target node with the required value is found. Once we have the targetNode and parentMap, we start the search for nodes at distance k using DFS approach starting from the targetNode. We use the `findNodesAtDistanceKHelper()` function that takes the current node, distance k, visited set (to avoid infinite looping), and the parentMap. If k is 0, we add the node's value into the result array. If not, we continue DFS for the left and right children, and also the parent (using the parentMap), with the updated k value (k-1). Finally, the result array containing values of nodes at distance k is returned.