# Contain Virus

- slug: contain-virus
- difficulty: Hard

A virus is spreading rapidly, and your task is to quarantine the infected area by installing walls.

The world is modeled as an `m x n` binary grid `isInfected`, where `isInfected[i][j] == 0` represents uninfected cells, and `isInfected[i][j] == 1` represents cells contaminated with the virus. A wall (and only one wall) can be installed between any two **4-directionally** adjacent cells, on the shared boundary.

Every night, the virus spreads to all neighboring cells in all four directions unless blocked by a wall. Resources are limited. Each day, you can install walls around only one region (i.e., the affected area (continuous block of infected cells) that threatens the most uninfected cells the following night). There **will never be a tie**.

Return _the number of walls used to quarantine all the infected regions_. If the world will become fully infected, return the number of walls used.

**Example 1:**

**Input:** isInfected = \[\[0,1,0,0,0,0,0,1\],\[0,1,0,0,0,0,0,1\],\[0,0,0,0,0,0,0,1\],\[0,0,0,0,0,0,0,0\]\]
**Output:** 10
**Explanation:** There are 2 contaminated regions.
On the first day, add 5 walls to quarantine the viral region on the left. The board after the virus spreads is:

On the second day, add 5 walls to quarantine the viral region on the right. The virus is fully contained.

**Example 2:**

**Input:** isInfected = \[\[1,1,1\],\[1,0,1\],\[1,1,1\]\]
**Output:** 4
**Explanation:** Even though there is only one cell saved, there are 4 walls built.
Notice that walls are only built on the shared boundary of two different cells.

**Example 3:**

**Input:** isInfected = \[\[1,1,1,0,0,0,0,0,0\],\[1,0,1,0,1,1,1,1,1\],\[1,1,1,0,0,0,0,0,0\]\]
**Output:** 13
**Explanation:** The region on the left only builds two new walls.

**Constraints:**

*   `m == isInfected.length`
*   `n == isInfected[i].length`
*   `1 <= m, n <= 50`
*   `isInfected[i][j]` is either `0` or `1`.
*   There is always a contiguous viral region throughout the described process that will **infect strictly more uncontaminated squares** in the next round.

## A solution in Java

```java
import java.util.HashMap;

public String shortestCompletingWord(String licensePlate, String[] words) {
    HashMap<Character, Integer> target = new HashMap<>();
    for (char c : licensePlate.toCharArray()) {
        if (Character.isLetter(c)) {
            char lower_c = Character.toLowerCase(c);
            target.put(lower_c, target.getOrDefault(lower_c, 0) + 1);
        }
    }

    String result = null;
    for (String word : words) {
        HashMap<Character, Integer> current = new HashMap<>();
        for (char c : word.toCharArray())
            if (Character.isLetter(c)) {
                char lower_c = Character.toLowerCase(c);
                current.put(lower_c, current.getOrDefault(lower_c, 0) + 1);
            }

        boolean valid = true;
        for (char c : target.keySet()) {
            if (current.getOrDefault(c, 0) < target.get(c)) {
                valid = false;
                break;
            }
        }

        if (valid && (result == null || word.length() < result.length())) result = word;
    }

    return result;
}
```
1. We create an array `target` of length 26, representing the count of each letter in `licensePlate` (ignoring case, spaces, and numbers).
2. Then, for each `word` in `words`, we create a new array `current`, representing the count of each letter in `word` (ignoring case).
3. We check if every count in `target` is less than or equal to the corresponding count in `current`.
4. If it is true, and the `result` is empty or the `word` has shorter length than the current result, we update `result` with the current `word`.
5. We continue this process for all given `words`.
6. Finally, we return the `result` which is the shortest completing word.

## A solution in C++

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

std::string shortestCompletingWord(std::string licensePlate, std::vector<std::string> words) {
    std::vector<int> target(26, 0);
    for (char c : licensePlate)
        if (isalpha(c)) target[tolower(c) - 'a']++;

    std::string result;
    for (const std::string& word : words) {
        std::vector<int> current(26, 0);
        for (char c : word)
            if (isalpha(c)) current[tolower(c) - 'a']++;

        if (std::equal(target.begin(), target.end(), current.begin(), [](int a, int b){ return a <= b; }))
            if (result.empty() || word.size() < result.size()) result = word;
    }

    return result;
}
```
1. We create an array `target` of length 26, representing the count of each letter in `licensePlate` (ignoring case, spaces, and numbers).
2. Then, for each `word` in `words`, we create a new array `current`, representing the count of each letter in `word` (ignoring case).
3. We check if every count in `target` is less than or equal to the corresponding count in `current`.
4. If it is true, and the `result` is empty or the `word` has shorter length than the current result, we update `result` with the current `word`.
5. We continue this process for all given `words`.
6. Finally, we return the `result` which is the shortest completing word.

## A solution in Python

```python
def shortest_completing_word(license_plate, words):
    target = [0] * 26
    for c in license_plate:
        if c.isalpha():
            target[ord(c.lower()) - ord('a')] += 1

    result = ""
    for word in words:
        current = [0] * 26
        for c in word:
            if c.isalpha():
                current[ord(c.lower()) - ord('a')] += 1

        if all(a <= b for a, b in zip(target, current)) and (not result or len(word) < len(result)):
            result = word

    return result
```
1. We create an array `target` of length 26, representing the count of each letter in `licensePlate` (ignoring case, spaces, and numbers).
2. Then, for each `word` in `words`, we create a new array `current`, representing the count of each letter in `word` (ignoring case).
3. We check if every count in `target` is less than or equal to the corresponding count in `current`.
4. If it is true, and the `result` is empty or the `word` has shorter length than the current result, we update `result` with the current `word`.
5. We continue this process for all given `words`.
6. Finally, we return the `result` which is the shortest completing word.

## A solution in Javascript

```javascript
function shortestCompletingWord(licensePlate, words) {
    let target = Array(26).fill(0);
    for (let c of licensePlate)
        if (c.toLowerCase() != c.toUpperCase()) target[c.toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0)]++;

    let result = "";
    for (let word of words) {
        let current = Array(26).fill(0);
        for (let c of word)
            if (c.toLowerCase() != c.toUpperCase()) current[c.toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0)]++;

        if (target.every((a, i) => a <= current[i]) && (result === "" || word.length < result.length)) result = word;
    }

    return result;
}
```
1. We create an array `target` of length 26, representing the count of each letter in `licensePlate` (ignoring case, spaces, and numbers).
2. Then, for each `word` in `words`, we create a new array `current`, representing the count of each letter in `word` (ignoring case).
3. We check if every count in `target` is less than or equal to the corresponding count in `current`.
4. If it is true, and the `result` is empty or the `word` has shorter length than the current result, we update `result` with the current `word`.
5. We continue this process for all given `words`.
6. Finally, we return the `result` which is the shortest completing word.


# Number Of Corner Rectangles

- slug: number-of-corner-rectangles
- difficulty: Medium

Given an `m x n` integer matrix `grid` where each entry is only `0` or `1`, return _the number of **corner rectangles**_.

A **corner rectangle** is four distinct `1`'s on the grid that forms an axis-aligned rectangle. Note that only the corners need to have the value `1`. Also, all four `1`'s used must be distinct.

**Example 1:**

**Input:** grid = \[\[1,0,0,1,0\],\[0,0,1,0,1\],\[0,0,0,1,0\],\[1,0,1,0,1\]\]
**Output:** 1
**Explanation:** There is only one corner rectangle, with corners grid\[1\]\[2\], grid\[1\]\[4\], grid\[3\]\[2\], grid\[3\]\[4\].

**Example 2:**

**Input:** grid = \[\[1,1,1\],\[1,1,1\],\[1,1,1\]\]
**Output:** 9
**Explanation:** There are four 2x2 rectangles, four 2x3 and 3x2 rectangles, and one 3x3 rectangle.

**Example 3:**

**Input:** grid = \[\[1,1,1,1\]\]
**Output:** 0
**Explanation:** Rectangles must have four distinct corners.

**Constraints:**

*   `m == grid.length`
*   `n == grid[i].length`
*   `1 <= m, n <= 200`
*   `grid[i][j]` is either `0` or `1`.
*   The number of `1`'s in the grid is in the range `[1, 6000]`.

## A solution in Java

```java
public int countCornerRectangles(int[][] grid) {
    int count = 0;
    int m = grid.length;
    int n = grid[0].length;

    for (int i = 0; i < m - 1; i++) {
        for (int j = 0; j < n - 1; j++) {
            if (grid[i][j] == 1) {
                for (int k = i + 1; k < m; k++) {
                    for (int l = j + 1; l < n; l++) {
                        if (grid[k][l] == 1 && grid[i][l] == 1 && grid[k][j] == 1) {
                            count++;
                        }
                    }
                }
            }
        }
    }
    return count;
}
```
The algorithm iterates through each element of the grid, starting from the top-left corner to the bottom-right corner. For each element with value 1, it checks for another 1 in the same row but at a later column (forming a top corner of the rectangle) and another 1 in the same column but at a later row (forming a left corner of the rectangle). Then, it checks if the intersection point of these two corners (the bottom-right corner of the rectangle) is also 1. If all these conditions are met, it means a corner rectangle is formed, and the count is incremented. The final result is returned after iterating through all possible combinations.

Time complexity: O(m^2 * n^2), where m and n are the dimensions of the grid
Space complexity: O(1)

## A solution in C++

```cpp
int countCornerRectangles(vector<vector<int>>& grid) {
    int count = 0;
    int m = grid.size();
    int n = grid[0].size();

    for (int i = 0; i < m - 1; i++) {
        for (int j = 0; j < n - 1; j++) {
            if (grid[i][j] == 1) {
                for (int k = i + 1; k < m; k++) {
                    for (int l = j + 1; l < n; l++) {
                        if (grid[k][l] == 1 && grid[i][l] == 1 && grid[k][j] == 1) {
                            count++;
                        }
                    }
                }
            }
        }
    }
    return count;
}
```
The algorithm iterates through each element of the grid, starting from the top-left corner to the bottom-right corner. For each element with value 1, it checks for another 1 in the same row but at a later column (forming a top corner of the rectangle) and another 1 in the same column but at a later row (forming a left corner of the rectangle). Then, it checks if the intersection point of these two corners (the bottom-right corner of the rectangle) is also 1. If all these conditions are met, it means a corner rectangle is formed, and the count is incremented. The final result is returned after iterating through all possible combinations.

Time complexity: O(m^2 * n^2), where m and n are the dimensions of the grid
Space complexity: O(1)

## A solution in Python

```python
def countCornerRectangles(grid):
    count = 0
    m = len(grid)
    n = len(grid[0])

    for i in range(m - 1):
        for j in range(n - 1):
            if grid[i][j] == 1:
                for k in range(i + 1, m):
                    for l in range(j + 1, n):
                        if grid[k][l] == 1 and grid[i][l] == 1 and grid[k][j] == 1:
                            count += 1
    return count
```
The algorithm iterates through each element of the grid, starting from the top-left corner to the bottom-right corner. For each element with value 1, it checks for another 1 in the same row but at a later column (forming a top corner of the rectangle) and another 1 in the same column but at a later row (forming a left corner of the rectangle). Then, it checks if the intersection point of these two corners (the bottom-right corner of the rectangle) is also 1. If all these conditions are met, it means a corner rectangle is formed, and the count is incremented. The final result is returned after iterating through all possible combinations.

Time complexity: O(m^2 * n^2), where m and n are the dimensions of the grid
Space complexity: O(1)

## A solution in Javascript

```javascript
function countCornerRectangles(grid) {
    let count = 0;
    let m = grid.length;
    let n = grid[0].length;

    for (let i = 0; i < m - 1; i++) {
        for (let j = 0; j < n - 1; j++) {
            if (grid[i][j] === 1) {
                for (let k = i + 1; k < m; k++) {
                    for (let l = j + 1; l < n; l++) {
                        if (grid[k][l] === 1 && grid[i][l] === 1 && grid[k][j] === 1) {
                            count++;
                        }
                    }
                }
            }
        }
    }
    return count;
}
```
The algorithm iterates through each element of the grid, starting from the top-left corner to the bottom-right corner. For each element with value 1, it checks for another 1 in the same row but at a later column (forming a top corner of the rectangle) and another 1 in the same column but at a later row (forming a left corner of the rectangle). Then, it checks if the intersection point of these two corners (the bottom-right corner of the rectangle) is also 1. If all these conditions are met, it means a corner rectangle is formed, and the count is incremented. The final result is returned after iterating through all possible combinations.

Time complexity: O(m^2 * n^2), where m and n are the dimensions of the grid
Space complexity: O(1)


# IP to CIDR

- slug: ip-to-cidr
- difficulty: Medium

An **IP address** is a formatted 32-bit unsigned integer where each group of 8 bits is printed as a decimal number and the dot character `'.'` splits the groups.

*   For example, the binary number `00001111 10001000 11111111 01101011` (spaces added for clarity) formatted as an IP address would be `"15.136.255.107 "`.

A **CIDR block** is a format used to denote a specific set of IP addresses. It is a string consisting of a base IP address, followed by a slash, followed by a prefix length `k`. The addresses it covers are all the IPs whose **first `k` bits** are the same as the base IP address.

*   For example, `"123.45.67.89/20 "` is a CIDR block with a prefix length of `20`. Any IP address whose binary representation matches `01111011 00101101 0100xxxx xxxxxxxx`, where `x` can be either `0` or `1`, is in the set covered by the CIDR block.

You are given a start IP address `ip` and the number of IP addresses we need to cover `n`. Your goal is to use **as few CIDR blocks as possible** to cover all the IP addresses in the **inclusive** range `[ip, ip + n - 1]` **exactly**. No other IP addresses outside of the range should be covered.

Return _the **shortest** list of **CIDR blocks** that covers the range of IP addresses. If there are multiple answers, return **any** of them_.

**Example 1:**

**Input:** ip =  "255.0.0.7 ", n = 10
**Output:** \[ "255.0.0.7/32 ", "255.0.0.8/29 ", "255.0.0.16/32 "\]
**Explanation:**
The IP addresses that need to be covered are:
- 255.0.0.7  -> 11111111 00000000 00000000 00000111
- 255.0.0.8  -> 11111111 00000000 00000000 00001000
- 255.0.0.9  -> 11111111 00000000 00000000 00001001
- 255.0.0.10 -> 11111111 00000000 00000000 00001010
- 255.0.0.11 -> 11111111 00000000 00000000 00001011
- 255.0.0.12 -> 11111111 00000000 00000000 00001100
- 255.0.0.13 -> 11111111 00000000 00000000 00001101
- 255.0.0.14 -> 11111111 00000000 00000000 00001110
- 255.0.0.15 -> 11111111 00000000 00000000 00001111
- 255.0.0.16 -> 11111111 00000000 00000000 00010000
The CIDR block  "255.0.0.7/32 " covers the first address.
The CIDR block  "255.0.0.8/29 " covers the middle 8 addresses (binary format of 11111111 00000000 00000000 00001xxx).
The CIDR block  "255.0.0.16/32 " covers the last address.
Note that while the CIDR block  "255.0.0.0/28 " does cover all the addresses, it also includes addresses outside of the range, so we cannot use it.

**Example 2:**

**Input:** ip =  "117.145.102.62 ", n = 8
**Output:** \[ "117.145.102.62/31 ", "117.145.102.64/30 ", "117.145.102.68/31 "\]

**Constraints:**

*   `7 <= ip.length <= 15`
*   `ip` is a valid **IPv4** on the form `"a.b.c.d "` where `a`, `b`, `c`, and `d` are integers in the range `[0, 255]`.
*   `1 <= n <= 1000`
*   Every implied address `ip + x` (for `x < n`) will be a valid IPv4 address.

## A solution in Java

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

public List<String> ipToCIDR(String ip, int n) {
    String[] parts = ip.split("\\.");
    int start = (Integer.parseInt(parts[0]) << 24) + (Integer.parseInt(parts[1]) << 16) + (Integer.parseInt(parts[2]) << 8) + Integer.parseInt(parts[3]);
    int end = start + n - 1;

    List<String> ans = new ArrayList<>();
    while (start <= end) {
        int samePrefixBits = Integer.numberOfTrailingZeros(~(start & -start));
        while (((end - start) >> samePrefixBits) < 1)
            --samePrefixBits;
        int range = 1 << samePrefixBits;
        ans.add((start >> 24) + "." + ((start >> 16) & 255) + "." + ((start >> 8) & 255) + "." + (start & 255) + "/" + (32 - samePrefixBits));
        start += range;
    }

    return ans;
}
```
The algorithm first converts the given IP to an integer. Then iteratively, it finds the first CIDR block that covers the starting IP and all the subsequent IPs that have the same prefix bits as the starting IP address, without covering any address outside the range. Once the range of the CIDR block is found, the CIDR block is added to the result and the starting IP is updated to be the next address after the found range. This process is repeated until the whole range is covered.

For each step, we start by finding the number of bits with a one in the lowest bits of the current starting IP's binary representation. This tells us how many bits are different from the preceding IP(s). Then, we keep decreasing the number of bits (effectively increasing the range) until we find a range that covers at least the remaining IPs in the range. To avoid overstepping the range, we decrease the prefix bits if the maximum number of IPs covered by the current CIDR block is more than what's left. Finally, we add the CIDR block and update the starting IP. The algorithm terminates when the starting IP becomes greater than the end IP.

## A solution in C++

```cpp
#include <bitset>
#include <vector>
#include <string>
#include <sstream>
using namespace std;

vector<string> ipToCIDR(string ip, int n) {
    stringstream ss(ip);
    int a, b, c, d;
    char ch;
    ss >> a >> ch >> b >> ch >> c >> ch >> d;
    unsigned mask = 0xFFFFFFFF;
    unsigned start = (a << 24) + (b << 16) + (c << 8) + d;
    unsigned end = start + n - 1;

    vector<string> ans;
    while (start <= end) {
        int samePrefixBits = __builtin_ctz(~(start & -start));
        while ((mask >> samePrefixBits) & 1)
            ++samePrefixBits;
        while (((end - start) >> samePrefixBits) < 1)
            --samePrefixBits;
        unsigned range = 1 << samePrefixBits;
        stringstream res;
        res << (start >> 24) << "." << ((start >> 16) & 255) << "." << ((start >> 8) & 255) << "." << (start & 255) << "/" << (32 - samePrefixBits);
        ans.push_back(res.str());
        start += range;
    }

    return ans;
}
```
The algorithm first converts the given IP to an integer. Then iteratively, it finds the first CIDR block that covers the starting IP and all the subsequent IPs that have the same prefix bits as the starting IP address, without covering any address outside the range. Once the range of the CIDR block is found, the CIDR block is added to the result and the starting IP is updated to be the next address after the found range. This process is repeated until the whole range is covered.

For each step, we start by finding the number of bits with a one in the lowest bits of the current starting IP's binary representation. This tells us how many bits are different from the preceding IP(s). Then, we keep decreasing the number of bits (effectively increasing the range) until we find a range that covers at least the remaining IPs in the range. To avoid overstepping the range, we decrease the prefix bits if the maximum number of IPs covered by the current CIDR block is more than what's left. Finally, we add the CIDR block and update the starting IP. The algorithm terminates when the starting IP becomes greater than the end IP.

## A solution in Python

```python
def ipToCIDR(ip: str, n: int) -> List[str]:
    a, b, c, d = map(int, ip.split('.'))
    start = (a << 24) + (b << 16) + (c << 8) + d
    end = start + n - 1

    ans = []
    while start <= end:
        samePrefixBits = (~start & start).bit_length() - 1
        while ((end - start) >> samePrefixBits) < 1:
            samePrefixBits -= 1
        range = 1 << samePrefixBits
        ans.append(f"{start >> 24}.{(start >> 16) & 255}.{(start >> 8) & 255}.{start & 255}/{32 - samePrefixBits}")
        start += range

    return ans
```
The algorithm first converts the given IP to an integer. Then iteratively, it finds the first CIDR block that covers the starting IP and all the subsequent IPs that have the same prefix bits as the starting IP address, without covering any address outside the range. Once the range of the CIDR block is found, the CIDR block is added to the result and the starting IP is updated to be the next address after the found range. This process is repeated until the whole range is covered.

For each step, we start by finding the number of bits with a one in the lowest bits of the current starting IP's binary representation. This tells us how many bits are different from the preceding IP(s). Then, we keep decreasing the number of bits (effectively increasing the range) until we find a range that covers at least the remaining IPs in the range. To avoid overstepping the range, we decrease the prefix bits if the maximum number of IPs covered by the current CIDR block is more than what's left. Finally, we add the CIDR block and update the starting IP. The algorithm terminates when the starting IP becomes greater than the end IP.

## A solution in Javascript

```javascript
function ipToCIDR(ip, n) {
    const [a, b, c, d] = ip.split('.').map(Number);
    let start = (a << 24) + (b << 16) + (c << 8) + d;
    const end = start + n - 1;

    const ans = [];
    while (start <= end) {
        let samePrefixBits = Math.clz32(~(start & -start));
        while (((end - start) >> samePrefixBits) < 1)
            --samePrefixBits;
        const range = 1 << samePrefixBits;
        ans.push(`${(start >> 24)}.${((start >> 16) & 255)}.${((start >> 8) & 255)}.${(start & 255)}/${32 - samePrefixBits}`);
        start += range;
    }

    return ans;
}
```
The algorithm first converts the given IP to an integer. Then iteratively, it finds the first CIDR block that covers the starting IP and all the subsequent IPs that have the same prefix bits as the starting IP address, without covering any address outside the range. Once the range of the CIDR block is found, the CIDR block is added to the result and the starting IP is updated to be the next address after the found range. This process is repeated until the whole range is covered.

For each step, we start by finding the number of bits with a one in the lowest bits of the current starting IP's binary representation. This tells us how many bits are different from the preceding IP(s). Then, we keep decreasing the number of bits (effectively increasing the range) until we find a range that covers at least the remaining IPs in the range. To avoid overstepping the range, we decrease the prefix bits if the maximum number of IPs covered by the current CIDR block is more than what's left. Finally, we add the CIDR block and update the starting IP. The algorithm terminates when the starting IP becomes greater than the end IP.


# Open the Lock

- slug: open-the-lock
- difficulty: Medium

You have a lock in front of you with 4 circular wheels. Each wheel has 10 slots: `'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'`. The wheels can rotate freely and wrap around: for example we can turn `'9'` to be `'0'`, or `'0'` to be `'9'`. Each move consists of turning one wheel one slot.

The lock initially starts at `'0000'`, a string representing the state of the 4 wheels.

You are given a list of `deadends` dead ends, meaning if the lock displays any of these codes, the wheels of the lock will stop turning and you will be unable to open it.

Given a `target` representing the value of the wheels that will unlock the lock, return the minimum total number of turns required to open the lock, or -1 if it is impossible.

**Example 1:**

**Input:** deadends = \[ "0201 ", "0101 ", "0102 ", "1212 ", "2002 "\], target =  "0202 "
**Output:** 6
**Explanation:**
A sequence of valid moves would be  "0000 " ->  "1000 " ->  "1100 " ->  "1200 " ->  "1201 " ->  "1202 " ->  "0202 ".
Note that a sequence like  "0000 " ->  "0001 " ->  "0002 " ->  "0102 " ->  "0202 " would be invalid,
because the wheels of the lock become stuck after the display becomes the dead end  "0102 ".

**Example 2:**

**Input:** deadends = \[ "8888 "\], target =  "0009 "
**Output:** 1
**Explanation:** We can turn the last wheel in reverse to move from  "0000 " ->  "0009 ".

**Example 3:**

**Input:** deadends = \[ "8887 ", "8889 ", "8878 ", "8898 ", "8788 ", "8988 ", "7888 ", "9888 "\], target =  "8888 "
**Output:** -1
**Explanation:** We cannot reach the target without getting stuck.

**Constraints:**

*   `1 <= deadends.length <= 500`
*   `deadends[i].length == 4`
*   `target.length == 4`
*   target **will not be** in the list `deadends`.
*   `target` and `deadends[i]` consist of digits only.

## A solution in Java

```java
import java.util.*;

public int openLock(String[] deadends, String target) {
    Set<String> dead = new HashSet<>(Arrays.asList(deadends));
    Set<String> visited = new HashSet<>();
    Queue<String> q = new LinkedList<>();
    String start = "0000";

    if (dead.contains(start)) return -1;
    q.offer(start);
    visited.add(start);

    int moves = 0;
    while (!q.isEmpty()) {
        int levelSize = q.size();
        for (int i = 0; i < levelSize; i++) {
            String cur = q.poll();

            if (cur.equals(target)) return moves;

            for (int j = 0; j < 4; j++) {
                for (int k = -1; k <= 1; k += 2) {
                    String next = cur.substring(0, j) + (char)((cur.charAt(j) - '0' + k + 10) % 10 + '0') + cur.substring(j + 1);

                    if (!visited.contains(next) && !dead.contains(next)) {
                        visited.add(next);
                        q.offer(next);
                    }
                }
            }
        }
        moves++;
    }

    return -1;
}
```
The algorithm uses a Breadth-First Search (BFS) approach to explore all possible combinations of the lock. We start with the initial state "0000". At each level, we change each wheel with one slot forward and one slot backward, and check the resulting combinations. If the combination isn't in the deadends and hasn't been visited before, it is added to the queue for further exploration. We continue exploring until the target is found or the queue is empty. The BFS ensures that the minimum number of turns are returned because it explores states level by level, where each level represents a certain number of turns. If the target is not found after the search, we return -1 indicating a failure to unlock the lock.

## A solution in C++

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

int openLock(vector<string>& deadends, string target) {
    set<string> dead(deadends.begin(), deadends.end());
    set<string> visited;
    queue<string> q;
    string start = "0000";

    if (dead.find(start) != dead.end()) return -1;
    q.push(start);
    visited.insert(start);

    int moves = 0;
    while (!q.empty()) {
        int levelSize = q.size();
        for (int i = 0; i < levelSize; ++i) {
            string cur = q.front();
            q.pop();

            if (cur == target) return moves;

            for (int j = 0; j < 4; ++j) {
                for (int k = -1; k <= 1; k += 2) {
                    string next = cur;
                    next[j] = (next[j] - '0' + k + 10) % 10 + '0';

                    if (visited.find(next) == visited.end() && dead.find(next) == dead.end()) {
                        visited.insert(next);
                        q.push(next);
                    }
                }
            }
        }
        moves++;
    }

    return -1;
}
```
The algorithm uses a Breadth-First Search (BFS) approach to explore all possible combinations of the lock. We start with the initial state "0000". At each level, we change each wheel with one slot forward and one slot backward, and check the resulting combinations. If the combination isn't in the deadends and hasn't been visited before, it is added to the queue for further exploration. We continue exploring until the target is found or the queue is empty. The BFS ensures that the minimum number of turns are returned because it explores states level by level, where each level represents a certain number of turns. If the target is not found after the search, we return -1 indicating a failure to unlock the lock.

## A solution in Python

```python
from collections import deque

def openLock(deadends, target):
    dead = set(deadends)
    visited = set()
    q = deque(["0000"])

    if "0000" in dead:
        return -1

    visited.add("0000")
    moves = 0

    while q:
        level_size = len(q)
        for i in range(level_size):
            cur = q.popleft()

            if cur == target:
                return moves

            for j in range(4):
                for k in [-1, 1]:
                    next_val = cur[:j] + str((int(cur[j]) + k + 10) % 10) + cur[j + 1:]

                    if next_val not in visited and next_val not in dead:
                        visited.add(next_val)
                        q.append(next_val)

        moves += 1

    return -1
```
The algorithm uses a Breadth-First Search (BFS) approach to explore all possible combinations of the lock. We start with the initial state "0000". At each level, we change each wheel with one slot forward and one slot backward, and check the resulting combinations. If the combination isn't in the deadends and hasn't been visited before, it is added to the queue for further exploration. We continue exploring until the target is found or the queue is empty. The BFS ensures that the minimum number of turns are returned because it explores states level by level, where each level represents a certain number of turns. If the target is not found after the search, we return -1 indicating a failure to unlock the lock.

## A solution in Javascript

```javascript
var openLock = function(deadends, target) {
    const dead = new Set(deadends);
    const visited = new Set();
    const queue = ["0000"];

    if (dead.has("0000")) return -1;

    visited.add("0000");
    let moves = 0;

    while (queue.length) {
        let levelSize = queue.length;
        for (let i = 0; i < levelSize; i++) {
            let cur = queue.shift();

            if (cur === target) return moves;

            for (let j = 0; j < 4; j++) {
                for (let k = -1; k <= 1; k += 2) {
                    let next = cur.slice(0, j) + ((Number(cur[j]) + k + 10) % 10).toString() + cur.slice(j + 1);

                    if (!visited.has(next) && !dead.has(next)) {
                        visited.add(next);
                        queue.push(next);
                    }
                }
            }
        }
        moves++;
    }

    return -1;
};
```
The algorithm uses a Breadth-First Search (BFS) approach to explore all possible combinations of the lock. We start with the initial state "0000". At each level, we change each wheel with one slot forward and one slot backward, and check the resulting combinations. If the combination isn't in the deadends and hasn't been visited before, it is added to the queue for further exploration. We continue exploring until the target is found or the queue is empty. The BFS ensures that the minimum number of turns are returned because it explores states level by level, where each level represents a certain number of turns. If the target is not found after the search, we return -1 indicating a failure to unlock the lock.


# Cracking the Safe

- slug: cracking-the-safe
- difficulty: Hard

There is a safe protected by a password. The password is a sequence of `n` digits where each digit can be in the range `[0, k - 1]`.

The safe has a peculiar way of checking the password. When you enter in a sequence, it checks the **most recent** `n` **digits** that were entered each time you type a digit.

*   For example, the correct password is `"345 "` and you enter in `"012345 "`:
    *   After typing `0`, the most recent `3` digits is `"0 "`, which is incorrect.
    *   After typing `1`, the most recent `3` digits is `"01 "`, which is incorrect.
    *   After typing `2`, the most recent `3` digits is `"012 "`, which is incorrect.
    *   After typing `3`, the most recent `3` digits is `"123 "`, which is incorrect.
    *   After typing `4`, the most recent `3` digits is `"234 "`, which is incorrect.
    *   After typing `5`, the most recent `3` digits is `"345 "`, which is correct and the safe unlocks.

Return _any string of **minimum length** that will unlock the safe **at some point** of entering it_.

**Example 1:**

**Input:** n = 1, k = 2
**Output:**  "10 "
**Explanation:** The password is a single digit, so enter each digit.  "01 " would also unlock the safe.

**Example 2:**

**Input:** n = 2, k = 2
**Output:**  "01100 "
**Explanation:** For each possible password:
-  "00 " is typed in starting from the 4th digit.
-  "01 " is typed in starting from the 1st digit.
-  "10 " is typed in starting from the 3rd digit.
-  "11 " is typed in starting from the 2nd digit.
Thus  "01100 " will unlock the safe.  "10011 ", and  "11001 " would also unlock the safe.

**Constraints:**

*   `1 <= n <= 4`
*   `1 <= k <= 10`
*   `1 <= kn <= 4096`

## A solution in Java

```java
import java.util.*;

public int openLock(String[] deadends, String target) {
    Set<String> dead = new HashSet<>(Arrays.asList(deadends));
    Set<String> visited = new HashSet<>();
    Queue<String[]> wheelStates = new LinkedList<>();

    if (dead.contains("0000")) return -1;
    wheelStates.add(new String[]{"0000", "0"});
    visited.add("0000");

    while (!wheelStates.isEmpty()) {
        String[] currentStateTurn = wheelStates.poll();
        String currentState = currentStateTurn[0];
        int turns = Integer.parseInt(currentStateTurn[1]);

        if (currentState.equals(target)) return turns;

        for (int i = 0; i < 4; ++i) {
            char[] upStateArr = currentState.toCharArray();
            char[] downStateArr = currentState.toCharArray();
            upStateArr[i] = (char)(((upStateArr[i] - '0' + 1) % 10) + '0');
            downStateArr[i] = (char)(((downStateArr[i] - '0' + 9) % 10) + '0');
            String upState = new String(upStateArr);
            String downState = new String(downStateArr);

            if (!visited.contains(upState) && !dead.contains(upState)) {
                wheelStates.add(new String[]{upState, String.valueOf(turns + 1)});
                visited.add(upState);
            }

            if (!visited.contains(downState) && !dead.contains(downState)) {
                wheelStates.add(new String[]{downState, String.valueOf(turns + 1)});
                visited.add(downState);
            }
        }
    }
    return -1;
}
```
The algorithm is based on a breadth-first search. We create sets for deadends and visited states, and a queue of wheel states with the number of turns for each state. If the starting state "0000" is in deadends, we return -1, as there is no solution.

We iterate while wheelStates is not empty. On each iteration, we check if the current state is equal to the target state, and return the number of turns if they are equal. Then, for each wheel of the state, we calculate the up state and down state by adding 1 or subtracting 1 from its position respectively (modulo 10). After that, if up_state or down_state are not visited and not in deadends, we add them to wheelStates with turns + 1. Finally, we add up_state and down_state in visited states.

If there is no solution, return -1 when the wheelStates queue becomes empty.

## A solution in C++

```cpp
#include <vector>
#include <string>
#include <queue>
#include <unordered_set>

int openLock(std::vector<std::string> &deadends, std::string target) {
    std::unordered_set<std::string> dead(deadends.begin(), deadends.end());
    std::unordered_set<std::string> visited;
    std::queue<std::pair<std::string, int>> wheel_states;

    if (dead.find("0000") != dead.end()) return -1;
    wheel_states.push({"0000", 0});
    visited.insert("0000");

    while (!wheel_states.empty()) {
        auto [current_state, turns] = wheel_states.front(); wheel_states.pop();

        if (current_state == target) return turns;

        for (int i = 0; i < 4; ++i) {
            std::string up_state = current_state;
            std::string down_state = current_state;
            up_state[i] = (up_state[i] - '0' + 1) % 10 + '0';
            down_state[i] = (down_state[i] - '0' + 9) % 10 + '0';

            if (!visited.count(up_state) && !dead.count(up_state)) {
                wheel_states.push({up_state, turns + 1});
                visited.insert(up_state);
            }

            if (!visited.count(down_state) && !dead.count(down_state)) {
                wheel_states.push({down_state, turns + 1});
                visited.insert(down_state);
            }
        }
    }
    return -1;
}
```
The algorithm is based on a breadth-first search. We create sets for deadends and visited states, and a queue of wheel states with the number of turns for each state. If the starting state "0000" is in deadends, we return -1, as there is no solution.

We iterate while wheelStates is not empty. On each iteration, we check if the current state is equal to the target state, and return the number of turns if they are equal. Then, for each wheel of the state, we calculate the up state and down state by adding 1 or subtracting 1 from its position respectively (modulo 10). After that, if up_state or down_state are not visited and not in deadends, we add them to wheelStates with turns + 1. Finally, we add up_state and down_state in visited states.

If there is no solution, return -1 when the wheelStates queue becomes empty.

## A solution in Python

```python
from collections import deque

def openLock(deadends, target):
    dead = set(deadends)
    visited = set()
    wheel_states = deque([("0000", 0)])

    if "0000" in dead:
        return -1

    while wheel_states:
        current_state, turns = wheel_states.popleft()

        if current_state == target:
            return turns

        for i in range(4):
            up_state = current_state[:i] + str((int(current_state[i]) + 1) % 10) + current_state[i + 1:]
            down_state = current_state[:i] + str((int(current_state[i]) - 1) % 10) + current_state[i + 1:]

            if up_state not in visited and up_state not in dead:
                wheel_states.append((up_state, turns + 1))
                visited.add(up_state)

            if down_state not in visited and down_state not in dead:
                wheel_states.append((down_state, turns + 1))
                visited.add(down_state)

    return -1
```
The algorithm is based on a breadth-first search. We create sets for deadends and visited states, and a queue of wheel states with the number of turns for each state. If the starting state "0000" is in deadends, we return -1, as there is no solution.

We iterate while wheelStates is not empty. On each iteration, we check if the current state is equal to the target state, and return the number of turns if they are equal. Then, for each wheel of the state, we calculate the up state and down state by adding 1 or subtracting 1 from its position respectively (modulo 10). After that, if up_state or down_state are not visited and not in deadends, we add them to wheelStates with turns + 1. Finally, we add up_state and down_state in visited states.

If there is no solution, return -1 when the wheelStates queue becomes empty.

## A solution in Javascript

```javascript
function openLock(deadends, target) {
    const dead = new Set(deadends);
    const visited = new Set();
    const wheelStates = [["0000", 0]];

    if (dead.has("0000")) return -1;

    while (wheelStates.length > 0) {
        const [currentState, turns] = wheelStates.shift();

        if (currentState === target) return turns;

        for (let i = 0; i < 4; ++i) {
            const upState = currentState.slice(0, i) + ((parseInt(currentState[i]) + 1) % 10).toString() + currentState.slice(i + 1);
            const downState = currentState.slice(0, i) + ((parseInt(currentState[i]) - 1 + 10) % 10).toString() + currentState.slice(i + 1);

            if (!visited.has(upState) && !dead.has(upState)) {
                wheelStates.push([upState, turns + 1]);
                visited.add(upState);
            }

            if (!visited.has(downState) && !dead.has(downState)) {
                wheelStates.push([downState, turns + 1]);
                visited.add(downState);
            }
        }
    }
    return -1;
}
```
The algorithm is based on a breadth-first search. We create sets for deadends and visited states, and a queue of wheel states with the number of turns for each state. If the starting state "0000" is in deadends, we return -1, as there is no solution.

We iterate while wheelStates is not empty. On each iteration, we check if the current state is equal to the target state, and return the number of turns if they are equal. Then, for each wheel of the state, we calculate the up state and down state by adding 1 or subtracting 1 from its position respectively (modulo 10). After that, if up_state or down_state are not visited and not in deadends, we add them to wheelStates with turns + 1. Finally, we add up_state and down_state in visited states.

If there is no solution, return -1 when the wheelStates queue becomes empty.


# Reach a Number

- slug: reach-a-number
- difficulty: Medium

You are standing at position `0` on an infinite number line. There is a destination at position `target`.

You can make some number of moves `numMoves` so that:

*   On each move, you can either go left or right.
*   During the `ith` move (starting from `i == 1` to `i == numMoves`), you take `i` steps in the chosen direction.

Given the integer `target`, return _the **minimum** number of moves required (i.e., the minimum_ `numMoves`_) to reach the destination_.

**Example 1:**

**Input:** target = 2
**Output:** 3
**Explanation:**
On the 1st move, we step from 0 to 1 (1 step).
On the 2nd move, we step from 1 to -1 (2 steps).
On the 3rd move, we step from -1 to 2 (3 steps).

**Example 2:**

**Input:** target = 3
**Output:** 2
**Explanation:**
On the 1st move, we step from 0 to 1 (1 step).
On the 2nd move, we step from 1 to 3 (2 steps).

**Constraints:**

*   `-109 <= target <= 109`
*   `target != 0`

## A solution in Java

```java
public int reachNumber(int target) {
    target = Math.abs(target);
    int step = 0, sum = 0;
    while (sum < target) {
        step++;
        sum += step;
    }
    while ((sum - target) % 2 != 0) {
        step++;
        sum += step;
    }
    return step;
}
```
1. Calculate the absolute value of `target` since reaching a negative target can be achieved similarly to reaching a positive target.
2. Initialize the steps count `step` and a variable `sum` to store the sum of steps.
3. Keep adding steps to `sum` until the `sum` is greater than or equal to the target.
4. If the difference between the `sum` and the `target` is not divisible by 2, it means we haven't reached an even-numbered position or an odd-numbered position according to the parity of the `target`. If that's the case, increment `step` and add the new `step` to the `sum`.
5. Repeat step 4 until the difference between the `sum` and the `target` is divisible by 2.
6. Return the value of `step`.

## A solution in C++

```cpp
int reachNumber(int target) {
    target = abs(target);
    int step = 0, sum = 0;
    while (sum < target) {
        step++;
        sum += step;
    }
    while ((sum - target) % 2 != 0) {
        step++;
        sum += step;
    }
    return step;
}
```
1. Calculate the absolute value of `target` since reaching a negative target can be achieved similarly to reaching a positive target.
2. Initialize the steps count `step` and a variable `sum` to store the sum of steps.
3. Keep adding steps to `sum` until the `sum` is greater than or equal to the target.
4. If the difference between the `sum` and the `target` is not divisible by 2, it means we haven't reached an even-numbered position or an odd-numbered position according to the parity of the `target`. If that's the case, increment `step` and add the new `step` to the `sum`.
5. Repeat step 4 until the difference between the `sum` and the `target` is divisible by 2.
6. Return the value of `step`.

## A solution in Python

```python
def reachNumber(target: int) -> int:
    target = abs(target)
    step = 0
    sum = 0
    while sum < target:
        step += 1
        sum += step
    while (sum - target) % 2 != 0:
        step += 1
        sum += step
    return step
```
1. Calculate the absolute value of `target` since reaching a negative target can be achieved similarly to reaching a positive target.
2. Initialize the steps count `step` and a variable `sum` to store the sum of steps.
3. Keep adding steps to `sum` until the `sum` is greater than or equal to the target.
4. If the difference between the `sum` and the `target` is not divisible by 2, it means we haven't reached an even-numbered position or an odd-numbered position according to the parity of the `target`. If that's the case, increment `step` and add the new `step` to the `sum`.
5. Repeat step 4 until the difference between the `sum` and the `target` is divisible by 2.
6. Return the value of `step`.

## A solution in Javascript

```javascript
function reachNumber(target) {
    target = Math.abs(target);
    let step = 0, sum = 0;
    while (sum < target) {
        step++;
        sum += step;
    }
    while ((sum - target) % 2 != 0) {
        step++;
        sum += step;
    }
    return step;
}
```
1. Calculate the absolute value of `target` since reaching a negative target can be achieved similarly to reaching a positive target.
2. Initialize the steps count `step` and a variable `sum` to store the sum of steps.
3. Keep adding steps to `sum` until the `sum` is greater than or equal to the target.
4. If the difference between the `sum` and the `target` is not divisible by 2, it means we haven't reached an even-numbered position or an odd-numbered position according to the parity of the `target`. If that's the case, increment `step` and add the new `step` to the `sum`.
5. Repeat step 4 until the difference between the `sum` and the `target` is divisible by 2.
6. Return the value of `step`.


# Pour Water

- slug: pour-water
- difficulty: Medium

You are given an elevation map represents as an integer array `heights` where `heights[i]` representing the height of the terrain at index `i`. The width at each index is `1`. You are also given two integers `volume` and `k`. `volume` units of water will fall at index `k`.

Water first drops at the index `k` and rests on top of the highest terrain or water at that index. Then, it flows according to the following rules:

*   If the droplet would eventually fall by moving left, then move left.
*   Otherwise, if the droplet would eventually fall by moving right, then move right.
*   Otherwise, rise to its current position.

Here, **"eventually fall "** means that the droplet will eventually be at a lower level if it moves in that direction. Also, level means the height of the terrain plus any water in that column.

We can assume there is infinitely high terrain on the two sides out of bounds of the array. Also, there could not be partial water being spread out evenly on more than one grid block, and each unit of water has to be in exactly one block.

**Example 1:**

**Input:** heights = \[2,1,1,2,1,2,2\], volume = 4, k = 3
**Output:** \[2,2,2,3,2,2,2\]
**Explanation:**
The first drop of water lands at index k = 3. When moving left or right, the water can only move to the same level or a lower level. (By level, we mean the total height of the terrain plus any water in that column.)
Since moving left will eventually make it fall, it moves left. (A droplet  "made to fall " means go to a lower height than it was at previously.) Since moving left will not make it fall, it stays in place.

The next droplet falls at index k = 3. Since the new droplet moving left will eventually make it fall, it moves left. Notice that the droplet still preferred to move left, even though it could move right (and moving right makes it fall quicker.)

The third droplet falls at index k = 3. Since moving left would not eventually make it fall, it tries to move right. Since moving right would eventually make it fall, it moves right.

Finally, the fourth droplet falls at index k = 3. Since moving left would not eventually make it fall, it tries to move right. Since moving right would not eventually make it fall, it stays in place.

**Example 2:**

**Input:** heights = \[1,2,3,4\], volume = 2, k = 2
**Output:** \[2,3,3,4\]
**Explanation:** The last droplet settles at index 1, since moving further left would not cause it to eventually fall to a lower height.

**Example 3:**

**Input:** heights = \[3,1,3\], volume = 5, k = 1
**Output:** \[4,4,4\]

**Constraints:**

*   `1 <= heights.length <= 100`
*   `0 <= heights[i] <= 99`
*   `0 <= volume <= 2000`
*   `0 <= k < heights.length`

## A solution in Java

```java
public int minMoves(int target) {
    target = Math.abs(target);
    int step = 0;
    int sum = 0;
    while (sum < target || (sum - target) % 2 != 0) {
        step++;
        sum += step;
    }
    return step;
}
```
The algorithm works as follows:
1. Make sure the target is a positive integer by taking its absolute value.
2. Initialize the `step` and `sum` variables to 0.
3. Keep incrementing the `step` value by 1 and add it to the `sum` until the following condition is satisfied: `(sum >= target) && ((sum - target) % 2 == 0)`
4. Return the minimum number of steps required to reach the destination, which will be the value of `step` at the end of the loop.

## A solution in C++

```cpp
int min_moves(int target) {
    target = abs(target);
    int step = 0;
    int sum = 0;
    while (sum < target || (sum - target) % 2 == 1) {
        step++;
        sum += step;
    }
    return step;
}
```
The algorithm works as follows:
1. Make sure the target is a positive integer by taking its absolute value.
2. Initialize the `step` and `sum` variables to 0.
3. Keep incrementing the `step` value by 1 and add it to the `sum` until the following condition is satisfied: `(sum >= target) && ((sum - target) % 2 == 0)`
4. Return the minimum number of steps required to reach the destination, which will be the value of `step` at the end of the loop.

## A solution in Python

```python
def min_moves(target: int) -> int:
    target = abs(target)
    step = 0
    total = 0
    while total < target or (total - target) % 2 != 0:
        step += 1
        total += step
    return step
```
The algorithm works as follows:
1. Make sure the target is a positive integer by taking its absolute value.
2. Initialize the `step` and `sum` variables to 0.
3. Keep incrementing the `step` value by 1 and add it to the `sum` until the following condition is satisfied: `(sum >= target) && ((sum - target) % 2 == 0)`
4. Return the minimum number of steps required to reach the destination, which will be the value of `step` at the end of the loop.

## A solution in Javascript

```javascript
function minMoves(target) {
    target = Math.abs(target);
    let step = 0;
    let sum = 0;
    while (sum < target || (sum - target) % 2 !== 0) {
        step++;
        sum += step;
    }
    return step;
}
```
The algorithm works as follows:
1. Make sure the target is a positive integer by taking its absolute value.
2. Initialize the `step` and `sum` variables to 0.
3. Keep incrementing the `step` value by 1 and add it to the `sum` until the following condition is satisfied: `(sum >= target) && ((sum - target) % 2 == 0)`
4. Return the minimum number of steps required to reach the destination, which will be the value of `step` at the end of the loop.


# Pyramid Transition Matrix

- slug: pyramid-transition-matrix
- difficulty: Medium

You are stacking blocks to form a pyramid. Each block has a color, which is represented by a single letter. Each row of blocks contains **one less block** than the row beneath it and is centered on top.

To make the pyramid aesthetically pleasing, there are only specific **triangular patterns** that are allowed. A triangular pattern consists of a **single block** stacked on top of **two blocks**. The patterns are given as a list of three-letter strings `allowed`, where the first two characters of a pattern represent the left and right bottom blocks respectively, and the third character is the top block.

*   For example, `"ABC "` represents a triangular pattern with a `'C'` block stacked on top of an `'A'` (left) and `'B'` (right) block. Note that this is different from `"BAC "` where `'B'` is on the left bottom and `'A'` is on the right bottom.

You start with a bottom row of blocks `bottom`, given as a single string, that you **must** use as the base of the pyramid.

Given `bottom` and `allowed`, return `true` _if you can build the pyramid all the way to the top such that **every triangular pattern** in the pyramid is in_ `allowed`_, or_ `false` _otherwise_.

**Example 1:**

**Input:** bottom =  "BCD ", allowed = \[ "BCC ", "CDE ", "CEA ", "FFF "\]
**Output:** true
**Explanation:** The allowed triangular patterns are shown on the right.
Starting from the bottom (level 3), we can build  "CE " on level 2 and then build  "A " on level 1.
There are three triangular patterns in the pyramid, which are  "BCC ",  "CDE ", and  "CEA ". All are allowed.

**Example 2:**

**Input:** bottom =  "AAAA ", allowed = \[ "AAB ", "AAC ", "BCD ", "BBE ", "DEF "\]
**Output:** false
**Explanation:** The allowed triangular patterns are shown on the right.
Starting from the bottom (level 4), there are multiple ways to build level 3, but trying all the possibilites, you will get always stuck before building level 1.

**Constraints:**

*   `2 <= bottom.length <= 6`
*   `0 <= allowed.length <= 216`
*   `allowed[i].length == 3`
*   The letters in all input strings are from the set `{'A', 'B', 'C', 'D', 'E', 'F'}`.
*   All the values of `allowed` are **unique**.

## A solution in Java

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

public boolean pyramidTransition(String bottom, List<String> allowed) {
    Map<String, List<Character>> mapping = new HashMap<>();
    for (String s : allowed) {
        mapping.computeIfAbsent(s.substring(0, 2), k -> new ArrayList<>()).add(s.charAt(2));
    }
    return pyramidTransitionHelper(bottom, "", 0, mapping);
}

private boolean pyramidTransitionHelper(String bottom, String top, int idx, Map<String, List<Character>> mapping) {
    if (bottom.length() == 1) return true;
    if (idx == bottom.length() - 1) return pyramidTransitionHelper(top, "", 0, mapping);
    String key = bottom.substring(idx, idx + 2);
    if (!mapping.containsKey(key)) return false;
    for (Character c : mapping.get(key)) {
        if (pyramidTransitionHelper(bottom, top + c, idx + 1, mapping)) return true;
    }
    return false;
}
```
We first create a mapping from two-character keys to the list of possible top characters for a triangle. Then, we use a recursive helper function to build the pyramid. If the bottom row's length reaches 1, it means the pyramid is complete and we return true. If the index reaches the bottom length minus 1, we have just completed one level of the pyramid and need to continue for the next level. At each step, we try different allowed triangles and continue the recursion. If any allowed character leads to a successful pyramid, we return true. If there is no possible combination left, we return false.

## A solution in C++

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

bool pyramidTransitionHelper(std::string& bottom, std::string& top, int idx, std::unordered_map<std::string, std::vector<char>>& mapping) {
    if (bottom.length() == 1) return true;
    if (idx == bottom.length() - 1) return pyramidTransitionHelper(top, "", 0, mapping);
    std::string key = bottom.substr(idx, 2);
    if (mapping.find(key) == mapping.end()) return false;
    for (char c : mapping[key]) {
        top.push_back(c);
        if (pyramidTransitionHelper(bottom, top, idx + 1, mapping)) return true;
        top.pop_back();
    }
    return false;
}

bool pyramidTransition(std::string bottom, std::vector<std::string>& allowed) {
    std::unordered_map<std::string, std::vector<char>> mapping;
    for (const auto& s : allowed) mapping[s.substr(0, 2)].push_back(s[2]);
    return pyramidTransitionHelper(bottom, "", 0, mapping);
}
```
We first create a mapping from two-character keys to the list of possible top characters for a triangle. Then, we use a recursive helper function to build the pyramid. If the bottom row's length reaches 1, it means the pyramid is complete and we return true. If the index reaches the bottom length minus 1, we have just completed one level of the pyramid and need to continue for the next level. At each step, we try different allowed triangles and continue the recursion. If any allowed character leads to a successful pyramid, we return true. If there is no possible combination left, we return false.

## A solution in Python

```python
def pyramid_transition(bottom, allowed):
    mapping = {}
    for s in allowed:
        key = s[:2]
        if key not in mapping:
            mapping[key] = []
        mapping[key].append(s[2])
    return pyramid_transition_helper(bottom, "", 0, mapping)

def pyramid_transition_helper(bottom, top, idx, mapping):
    if len(bottom) == 1:
        return True
    if idx == len(bottom) - 1:
        return pyramid_transition_helper(top, "", 0, mapping)
    key = bottom[idx:idx + 2]
    if key not in mapping:
        return False
    for c in mapping[key]:
        if pyramid_transition_helper(bottom, top + c, idx + 1, mapping):
            return True
    return False
```
We first create a mapping from two-character keys to the list of possible top characters for a triangle. Then, we use a recursive helper function to build the pyramid. If the bottom row's length reaches 1, it means the pyramid is complete and we return true. If the index reaches the bottom length minus 1, we have just completed one level of the pyramid and need to continue for the next level. At each step, we try different allowed triangles and continue the recursion. If any allowed character leads to a successful pyramid, we return true. If there is no possible combination left, we return false.

## A solution in Javascript

```javascript
function pyramidTransition(bottom, allowed) {
    const mapping = {};
    for (const s of allowed) {
        const key = s.substr(0, 2);
        if (!(key in mapping)) mapping[key] = [];
        mapping[key].push(s[2]);
    }
    return pyramidTransitionHelper(bottom, '', 0, mapping);
}

function pyramidTransitionHelper(bottom, top, idx, mapping) {
    if (bottom.length === 1) return true;
    if (idx === bottom.length - 1) return pyramidTransitionHelper(top, '', 0, mapping);
    const key = bottom.substr(idx, 2);
    if (!(key in mapping)) return false;
    for (const c of mapping[key]) {
        if (pyramidTransitionHelper(bottom, top + c, idx + 1, mapping)) return true;
    }
    return false;
}
```
We first create a mapping from two-character keys to the list of possible top characters for a triangle. Then, we use a recursive helper function to build the pyramid. If the bottom row's length reaches 1, it means the pyramid is complete and we return true. If the index reaches the bottom length minus 1, we have just completed one level of the pyramid and need to continue for the next level. At each step, we try different allowed triangles and continue the recursion. If any allowed character leads to a successful pyramid, we return true. If there is no possible combination left, we return false.


# Set Intersection Size At Least Two

- slug: set-intersection-size-at-least-two
- difficulty: Hard

You are given a 2D integer array `intervals` where `intervals[i] = [starti, endi]` represents all the integers from `starti` to `endi` inclusively.

A **containing set** is an array `nums` where each interval from `intervals` has **at least two** integers in `nums`.

*   For example, if `intervals = [[1,3], [3,7], [8,9]]`, then `[1,2,4,7,8,9]` and `[2,3,4,8,9]` are **containing sets**.

Return _the minimum possible size of a containing set_.

**Example 1:**

**Input:** intervals = \[\[1,3\],\[3,7\],\[8,9\]\]
**Output:** 5
**Explanation:** let nums = \[2, 3, 4, 8, 9\].
It can be shown that there cannot be any containing array of size 4.

**Example 2:**

**Input:** intervals = \[\[1,3\],\[1,4\],\[2,5\],\[3,5\]\]
**Output:** 3
**Explanation:** let nums = \[2, 3, 4\].
It can be shown that there cannot be any containing array of size 2.

**Example 3:**

**Input:** intervals = \[\[1,2\],\[2,3\],\[2,4\],\[4,5\]\]
**Output:** 5
**Explanation:** let nums = \[1, 2, 3, 4, 5\].
It can be shown that there cannot be any containing array of size 4.

**Constraints:**

*   `1 <= intervals.length <= 3000`
*   `intervals[i].length == 2`
*   `0 <= starti < endi <= 108`

## A solution in Java

```java
import java.util.*;

public boolean pyramidTransition(String bottom, List<String> allowed) {
    Map<String, List<Character>> mapping = new HashMap<>();
    for (String s : allowed) {
        String key = s.substring(0, 2);
        if (!mapping.containsKey(key)) {
            mapping.put(key, new ArrayList<>());
        }
        mapping.get(key).add(s.charAt(2));
    }
    return dfs("", bottom, mapping);
}

public boolean dfs(String curr, String bottom, Map<String, List<Character>> mapping) {
    if (bottom.length() == 1) return true;
    for (int i = 0; i < bottom.length() - 1; ++i) {
        if (!mapping.containsKey(bottom.substring(i, i + 2))) return false;
    }
    curr = "";
    for (int i = 0; i < bottom.length() - 1; ++i) {
        curr += mapping.get(bottom.substring(i, i + 2)).get(0);
    }
    return dfs(curr, curr, mapping);
}
```
1. Create a mapping, with the allowed patterns, which maps bottom two characters of allowed string to their respective top character.
2. Define a function dfs, which loops through the current bottom to find the mapping for the subsequent row.
3. If it can create a subsequent row fully from the mappings without any error, it calls the dfs again recursively with the new row as the bottom row.
4. If, finally, a single character row(bottom.length==1) is formed at the top, it returns true; otherwise, it returns false.
5. Call dfs with the original bottom row and return the result.

## A solution in C++

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

bool dfs(std::string curr, std::string bottom, std::unordered_map<std::string, std::vector<char>>& mapping) {
    if (bottom.size() == 1) return true;

    for (int i = 0; i < bottom.size() - 1; ++i) {
        std::string s = bottom.substr(i, 2);
        if (mapping.count(s) == 0) return false;
    }

    curr = "";
    for (int i = 0; i < bottom.size() - 1; ++i) {
        curr += mapping[bottom.substr(i, 2)][0];
    }

    return dfs(curr, curr, mapping);
}

bool pyramidTransition(std::string bottom, std::vector<std::string>& allowed) {
    std::unordered_map<std::string, std::vector<char>> mapping;
    for (std::string& s : allowed) {
        mapping[s.substr(0, 2)].emplace_back(s[2]);
    }
    return dfs("", bottom, mapping);
}
```
1. Create a mapping, with the allowed patterns, which maps bottom two characters of allowed string to their respective top character.
2. Define a function dfs, which loops through the current bottom to find the mapping for the subsequent row.
3. If it can create a subsequent row fully from the mappings without any error, it calls the dfs again recursively with the new row as the bottom row.
4. If, finally, a single character row(bottom.length==1) is formed at the top, it returns true; otherwise, it returns false.
5. Call dfs with the original bottom row and return the result.

## A solution in Python

```python
from collections import defaultdict

def pyramidTransition(bottom, allowed):
    mapping = defaultdict(list)
    for s in allowed:
        mapping[s[:2]].append(s[2])
    return dfs("", bottom, mapping)

def dfs(curr, bottom, mapping):
    if len(bottom) == 1:
        return True
    for i in range(len(bottom) - 1):
        if bottom[i:i+2] not in mapping:
            return False
    curr = "".join(mapping[bottom[i:i + 2]][0] for i in range(len(bottom) - 1))
    return dfs(curr, curr, mapping)
```
1. Create a mapping, with the allowed patterns, which maps bottom two characters of allowed string to their respective top character.
2. Define a function dfs, which loops through the current bottom to find the mapping for the subsequent row.
3. If it can create a subsequent row fully from the mappings without any error, it calls the dfs again recursively with the new row as the bottom row.
4. If, finally, a single character row(bottom.length==1) is formed at the top, it returns true; otherwise, it returns false.
5. Call dfs with the original bottom row and return the result.

## A solution in Javascript

```javascript
function pyramidTransition(bottom, allowed) {
    const mapping = {};
    for (const s of allowed) {
        const key = s.slice(0, 2);
        if (!(key in mapping)) {
            mapping[key] = [];
        }
        mapping[key].push(s[2]);
    }
    return dfs("", bottom, mapping);
}

function dfs(curr, bottom, mapping) {
    if (bottom.length === 1) {
        return true;
    }
    for (let i = 0; i < bottom.length - 1; ++i) {
        if (!(bottom.slice(i, i + 2) in mapping)) {
            return false;
        }
    }
    curr = "";
    for (let i = 0; i < bottom.length - 1; ++i) {
        curr += mapping[bottom.slice(i, i + 2)][0];
    }
    return dfs(curr, curr, mapping);
}
```
1. Create a mapping, with the allowed patterns, which maps bottom two characters of allowed string to their respective top character.
2. Define a function dfs, which loops through the current bottom to find the mapping for the subsequent row.
3. If it can create a subsequent row fully from the mappings without any error, it calls the dfs again recursively with the new row as the bottom row.
4. If, finally, a single character row(bottom.length==1) is formed at the top, it returns true; otherwise, it returns false.
5. Call dfs with the original bottom row and return the result.


# Bold Words in String

- slug: bold-words-in-string
- difficulty: Medium

Given an array of keywords `words` and a string `s`, make all appearances of all keywords `words[i]` in `s` bold. Any letters between **and** tags become bold.

Return `s` _after adding the bold tags_. The returned string should use the least number of tags possible, and the tags should form a valid combination.

**Example 1:**

**Input:** words = \[ "ab ", "bc "\], s =  "aabcd "
**Output:**  "a**abc**d "
**Explanation:** Note that returning ` "a**a**b**c**d "` would use more tags, so it is incorrect.

**Example 2:**

**Input:** words = \[ "ab ", "cb "\], s =  "aabcd "
**Output:**  "a**ab**cd "

**Constraints:**

*   `1 <= s.length <= 500`
*   `0 <= words.length <= 50`
*   `1 <= words[i].length <= 10`
*   `s` and `words[i]` consist of lowercase English letters.

**Note:** This question is the same as 616: [https://leetcode.com/problems/add-bold-tag-in-string/](https://leetcode.com/problems/add-bold-tag-in-string/)

## A solution in Java

```java
import java.util.List;

public String addBoldTag(List<String> words, String s) {
    boolean[] bold = new boolean[s.length()];
    for (String word : words) {
        int pos = s.indexOf(word);
        while (pos != -1) {
            for (int i = pos; i < pos + word.length(); i++) {
                bold[i] = true;
            }
            pos = s.indexOf(word, pos + 1);
        }
    }

    StringBuilder result = new StringBuilder();
    for (int i = 0; i < s.length(); i++) {
        if (bold[i] && (i == 0 || !bold[i - 1])) result.append("<b>");
        result.append(s.charAt(i));
        if (bold[i] && (i == s.length() - 1 || !bold[i + 1])) result.append("</b>");
    }

    return result.toString();
}
```
1. Create an array `bold` of boolean values, same length as `s`, initially set to `false`.
2. For each `word` in `words`, find its indices in `s`. For each index found, set the corresponding elements in `bold` to `true`.
3. Create an empty result string. Iterate through `s` and concatenate each character to the result string. If the character is marked as bold and the previous character is not marked as bold, prepend a `<b>` tag. If the character is marked as bold and the next character is not marked as bold, append a `</b>` tag.
4. Return the result string with bold tags inserted.

## A solution in C++

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

std::string addBoldTag(std::vector<std::string>& words, std::string s) {
    std::vector<bool> bold(s.size(), false);
    for (std::string word : words) {
        int pos = s.find(word);
        while (pos != std::string::npos) {
            for (int i = pos; i < pos + word.size(); i++) {
                bold[i] = true;
            }
            pos = s.find(word, pos + 1);
        }
    }

    std::string result = "";
    for (int i = 0; i < s.size(); i++) {
        if (bold[i] && (i == 0 || !bold[i - 1])) result += "<b>";
        result += s[i];
        if (bold[i] && (i == s.size() - 1 || !bold[i + 1])) result += "</b>";
    }

    return result;
}
```
1. Create an array `bold` of boolean values, same length as `s`, initially set to `false`.
2. For each `word` in `words`, find its indices in `s`. For each index found, set the corresponding elements in `bold` to `true`.
3. Create an empty result string. Iterate through `s` and concatenate each character to the result string. If the character is marked as bold and the previous character is not marked as bold, prepend a `<b>` tag. If the character is marked as bold and the next character is not marked as bold, append a `</b>` tag.
4. Return the result string with bold tags inserted.

## A solution in Python

```python
def addBoldTag(words, s):
    bold = [False] * len(s)
    for word in words:
        pos = s.find(word)
        while pos != -1:
            for i in range(pos, pos + len(word)):
                bold[i] = True
            pos = s.find(word, pos + 1)

    result = []
    for i in range(len(s)):
        if bold[i] and (i == 0 or not bold[i - 1]):
            result.append("<b>")
        result.append(s[i])
        if bold[i] and (i == len(s) - 1 or not bold[i + 1]):
            result.append("</b>")

    return "".join(result)
```
1. Create an array `bold` of boolean values, same length as `s`, initially set to `false`.
2. For each `word` in `words`, find its indices in `s`. For each index found, set the corresponding elements in `bold` to `true`.
3. Create an empty result string. Iterate through `s` and concatenate each character to the result string. If the character is marked as bold and the previous character is not marked as bold, prepend a `<b>` tag. If the character is marked as bold and the next character is not marked as bold, append a `</b>` tag.
4. Return the result string with bold tags inserted.

## A solution in Javascript

```javascript
function addBoldTag(words, s) {
    const bold = new Array(s.length).fill(false);
    for (const word of words) {
        let pos = s.indexOf(word);
        while (pos !== -1) {
            for (let i = pos; i < pos + word.length; i++) {
                bold[i] = true;
            }
            pos = s.indexOf(word, pos + 1);
        }
    }

    let result = "";
    for (let i = 0; i < s.length; i++) {
        if (bold[i] && (i === 0 || !bold[i - 1])) result += "<b>";
        result += s[i];
        if (bold[i] && (i === s.length - 1 || !bold[i + 1])) result += "</b>";
    }

    return result;
}
```
1. Create an array `bold` of boolean values, same length as `s`, initially set to `false`.
2. For each `word` in `words`, find its indices in `s`. For each index found, set the corresponding elements in `bold` to `true`.
3. Create an empty result string. Iterate through `s` and concatenate each character to the result string. If the character is marked as bold and the previous character is not marked as bold, prepend a `<b>` tag. If the character is marked as bold and the next character is not marked as bold, append a `</b>` tag.
4. Return the result string with bold tags inserted.


# Employee Free Time

- slug: employee-free-time
- difficulty: Hard

We are given a list `schedule` of employees, which represents the working time for each employee.

Each employee has a list of non-overlapping `Intervals`, and these intervals are in sorted order.

Return the list of finite intervals representing **common, positive-length free time** for _all_ employees, also in sorted order.

(Even though we are representing `Intervals` in the form `[x, y]`, the objects inside are `Intervals`, not lists or arrays. For example, `schedule[0][0].start = 1`, `schedule[0][0].end = 2`, and `schedule[0][0][0]` is not defined). Also, we wouldn't include intervals like \[5, 5\] in our answer, as they have zero length.

**Example 1:**

**Input:** schedule = \[\[\[1,2\],\[5,6\]\],\[\[1,3\]\],\[\[4,10\]\]\]
**Output:** \[\[3,4\]\]
**Explanation:** There are a total of three employees, and all common
free time intervals would be \[-inf, 1\], \[3, 4\], \[10, inf\].
We discard any intervals that contain inf as they aren't finite.

**Example 2:**

**Input:** schedule = \[\[\[1,3\],\[6,7\]\],\[\[2,4\]\],\[\[2,5\],\[9,12\]\]\]
**Output:** \[\[5,6\],\[7,9\]\]

**Constraints:**

*   `1 <= schedule.length , schedule[i].length <= 50`
*   `0 <= schedule[i].start < schedule[i].end <= 10^8`

## A solution in Java

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

public int minSetSize(int[][] intervals) {
    Arrays.sort(intervals, Comparator.comparingInt(a -> a[0]));
    int n = intervals.length;
    int end = intervals[0][1];
    int count = 1;

    for (int i = 1; i < n; i++) {
        if (end < intervals[i][0]) {
            end = intervals[i][1];
            count++;
        } else {
            end = Math.min(end, intervals[i][1]);
        }
    }
    return count * 2;
}
```
1. Sort the intervals by their starting point.
2. Initialize `end` to the end of the first interval and set `count` to 1.
3. Loop through the intervals from the second interval onwards.
   - If the current `end` is less than the starting point of the current interval, set `end` to the end of the current interval and increment `count`.
   - Otherwise, set `end` to the minimum of the current `end` and the end of the current interval.
4. Return `count * 2` to ensure that the intersection of S with A has a size of at least two.

## A solution in C++

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

int minSetSize(std::vector<std::pair<int, int>> intervals) {
    std::sort(intervals.begin(), intervals.end());
    int n = intervals.size();
    int end = intervals[0].second;
    int count = 1;

    for (int i = 1; i < n; i++) {
        if (end < intervals[i].first) {
            end = intervals[i].second;
            count++;
        } else {
            end = std::min(end, intervals[i].second);
        }
    }
    return count * 2;
}
```
1. Sort the intervals by their starting point.
2. Initialize `end` to the end of the first interval and set `count` to 1.
3. Loop through the intervals from the second interval onwards.
   - If the current `end` is less than the starting point of the current interval, set `end` to the end of the current interval and increment `count`.
   - Otherwise, set `end` to the minimum of the current `end` and the end of the current interval.
4. Return `count * 2` to ensure that the intersection of S with A has a size of at least two.

## A solution in Python

```python
def min_set_size(intervals):
    intervals.sort()
    n = len(intervals)
    end = intervals[0][1]
    count = 1

    for i in range(1, n):
        if end < intervals[i][0]:
            end = intervals[i][1]
            count += 1
        else:
            end = min(end, intervals[i][1])
    return count * 2
```
1. Sort the intervals by their starting point.
2. Initialize `end` to the end of the first interval and set `count` to 1.
3. Loop through the intervals from the second interval onwards.
   - If the current `end` is less than the starting point of the current interval, set `end` to the end of the current interval and increment `count`.
   - Otherwise, set `end` to the minimum of the current `end` and the end of the current interval.
4. Return `count * 2` to ensure that the intersection of S with A has a size of at least two.

## A solution in Javascript

```javascript
function minSetSize(intervals) {
    intervals.sort((a, b) => a[0] - b[0]);
    const n = intervals.length;
    let end = intervals[0][1];
    let count = 1;

    for (let i = 1; i < n; i++) {
        if (end < intervals[i][0]) {
            end = intervals[i][1];
            count++;
        } else {
            end = Math.min(end, intervals[i][1]);
        }
    }
    return count * 2;
}
```
1. Sort the intervals by their starting point.
2. Initialize `end` to the end of the first interval and set `count` to 1.
3. Loop through the intervals from the second interval onwards.
   - If the current `end` is less than the starting point of the current interval, set `end` to the end of the current interval and increment `count`.
   - Otherwise, set `end` to the minimum of the current `end` and the end of the current interval.
4. Return `count * 2` to ensure that the intersection of S with A has a size of at least two.


# Find Anagram Mappings

- slug: find-anagram-mappings
- difficulty: Easy

You are given two integer arrays `nums1` and `nums2` where `nums2` is **an anagram** of `nums1`. Both arrays may contain duplicates.

Return _an index mapping array_ `mapping` _from_ `nums1` _to_ `nums2` _where_ `mapping[i] = j` _means the_ `ith` _element in_ `nums1` _appears in_ `nums2` _at index_ `j`. If there are multiple answers, return **any of them**.

An array `a` is **an anagram** of an array `b` means `b` is made by randomizing the order of the elements in `a`.

**Example 1:**

**Input:** nums1 = \[12,28,46,32,50\], nums2 = \[50,12,32,46,28\]
**Output:** \[1,4,3,2,0\]
**Explanation:** As mapping\[0\] = 1 because the 0th element of nums1 appears at nums2\[1\], and mapping\[1\] = 4 because the 1st element of nums1 appears at nums2\[4\], and so on.

**Example 2:**

**Input:** nums1 = \[84,46\], nums2 = \[84,46\]
**Output:** \[0,1\]

**Constraints:**

*   `1 <= nums1.length <= 100`
*   `nums2.length == nums1.length`
*   `0 <= nums1[i], nums2[i] <= 105`
*   `nums2` is an anagram of `nums1`.

## A solution in Java

```java
import java.util.*;

public int[] anagramMappings(int[] nums1, int[] nums2) {
    HashMap<Integer, Integer> num_map = new HashMap<>();
    for (int i = 0; i < nums2.length; i++) {
        num_map.put(nums2[i], i);
    }
    int[] mapping = new int[nums1.length];
    for (int i = 0; i < nums1.length; i++) {
        mapping[i] = num_map.get(nums1[i]);
    }
    return mapping;
}
```
The algorithm involves creating a mapping between each value in `nums2` and its index, using a hash map. Then, for each element in `nums1`, get its corresponding index in `nums2` and append that index value into the resulting mapping. This approach has a linear computation complexity (O(n)), as iterating over both `nums1` and `nums2` only occurs once.

## A solution in C++

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

vector<int> anagramMappings(vector<int>& nums1, vector<int>& nums2) {
    unordered_map<int, int> num_map;
    for (int i = 0; i < nums2.size(); i++) {
        num_map[nums2[i]] = i;
    }
    vector<int> mapping(nums1.size());
    for (int i = 0; i < nums1.size(); i++) {
        mapping[i] = num_map[nums1[i]];
    }
    return mapping;
}
```
The algorithm involves creating a mapping between each value in `nums2` and its index, using a hash map. Then, for each element in `nums1`, get its corresponding index in `nums2` and append that index value into the resulting mapping. This approach has a linear computation complexity (O(n)), as iterating over both `nums1` and `nums2` only occurs once.

## A solution in Python

```python
def anagramMappings(nums1, nums2):
    num_map = {num: i for i, num in enumerate(nums2)}
    mapping = [num_map[num] for num in nums1]
    return mapping
```
The algorithm involves creating a mapping between each value in `nums2` and its index, using a hash map. Then, for each element in `nums1`, get its corresponding index in `nums2` and append that index value into the resulting mapping. This approach has a linear computation complexity (O(n)), as iterating over both `nums1` and `nums2` only occurs once.

## A solution in Javascript

```javascript
function anagramMappings(nums1, nums2) {
    let num_map = new Map();
    for (let i = 0; i < nums2.length; i++) {
        num_map.set(nums2[i], i);
    }
    let mapping = new Array(nums1.length);
    for (let i = 0; i < nums1.length; i++) {
        mapping[i] = num_map.get(nums1[i]);
    }
    return mapping;
}
```
The algorithm involves creating a mapping between each value in `nums2` and its index, using a hash map. Then, for each element in `nums1`, get its corresponding index in `nums2` and append that index value into the resulting mapping. This approach has a linear computation complexity (O(n)), as iterating over both `nums1` and `nums2` only occurs once.


# Special Binary String

- slug: special-binary-string
- difficulty: Hard

**Special binary strings** are binary strings with the following two properties:

*   The number of `0`'s is equal to the number of `1`'s.
*   Every prefix of the binary string has at least as many `1`'s as `0`'s.

You are given a **special binary** string `s`.

A move consists of choosing two consecutive, non-empty, special substrings of `s`, and swapping them. Two strings are consecutive if the last character of the first string is exactly one index before the first character of the second string.

Return _the lexicographically largest resulting string possible after applying the mentioned operations on the string_.

**Example 1:**

**Input:** s =  "11011000 "
**Output:**  "11100100 "
**Explanation:** The strings  "10 " \[occuring at s\[1\]\] and  "1100 " \[at s\[3\]\] are swapped.
This is the lexicographically largest string possible after some number of swaps.

**Example 2:**

**Input:** s =  "10 "
**Output:**  "10 "

**Constraints:**

*   `1 <= s.length <= 50`
*   `s[i]` is either `'0'` or `'1'`.
*   `s` is a special binary string.

## A solution in Java

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

public String makeLargestSpecial(String s) {
    int count = 0;
    int i = 0;
    List<String> subs = new ArrayList<>();

    for (int j = 0; j < s.length(); j++) {
        if (s.charAt(j) == '1') count++;
        else count--;

        if (count == 0) {
            subs.add("1" + makeLargestSpecial(s.substring(i+1, j)) + "0");
            i = j + 1;
        }
    }

    Collections.sort(subs, Collections.reverseOrder());
    StringBuilder res = new StringBuilder();
    for (String sub : subs) {
        res.append(sub);
    }
    return res.toString();
}
```
The algorithm starts by initializing some variables. `count` tracks the balance of 1's and 0's in the special binary string, and `i` tracks the starting index for extracting subproblems.

Iterating through the input string `s`, the algorithm updates `count`, incrementing it if the current character is '1' and decrementing if it's '0'. Whenever `count` becomes zero, it means that the current substring from index `i + 1` to index `j` is a valid special binary string. We proceed with the following steps:

1. Extract the substring from index `i + 1` to index `j`.
2. Recursively apply the function `makeLargestSpecial()` on the extracted substring.
3. Concatenate the string "1" before and the string "0" after the result and add the resulting string into a list of substrings called `subs`.
4. Update the `i` variable to the next index after `j`.

After processing the entire input string in this way, we have several special binary substrings in `subs`. We sort the substrings in decreasing (non-ascending) order and concatenate them together to form the largest lexicographically possible string as the final result.

## A solution in C++

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

std::string makeLargestSpecial(std::string s) {
    int count = 0, i = 0;
    std::vector<std::string> subs;

    for (int j = 0; j < s.size(); j++) {
        if (s[j] == '1') count++;
        else count--;

        if (count == 0) {
            subs.push_back('1' + makeLargestSpecial(s.substr(i+1, j-i-1)) + '0');
            i = j + 1;
        }
    }

    std::sort(subs.rbegin(), subs.rend());
    std::string res;
    for (const auto& sub : subs) {
        res += sub;
    }
    return res;
}
```
The algorithm starts by initializing some variables. `count` tracks the balance of 1's and 0's in the special binary string, and `i` tracks the starting index for extracting subproblems.

Iterating through the input string `s`, the algorithm updates `count`, incrementing it if the current character is '1' and decrementing if it's '0'. Whenever `count` becomes zero, it means that the current substring from index `i + 1` to index `j` is a valid special binary string. We proceed with the following steps:

1. Extract the substring from index `i + 1` to index `j`.
2. Recursively apply the function `makeLargestSpecial()` on the extracted substring.
3. Concatenate the string "1" before and the string "0" after the result and add the resulting string into a list of substrings called `subs`.
4. Update the `i` variable to the next index after `j`.

After processing the entire input string in this way, we have several special binary substrings in `subs`. We sort the substrings in decreasing (non-ascending) order and concatenate them together to form the largest lexicographically possible string as the final result.

## A solution in Python

```python
def makeLargestSpecial(s: str) -> str:
    count, i = 0, 0
    subs = []

    for j in range(len(s)):
        if s[j] == '1':
            count += 1
        else:
            count -= 1

        if count == 0:
            subs.append("1" + makeLargestSpecial(s[i+1:j]) + "0")
            i = j + 1

    subs.sort(reverse=True)
    return "".join(subs)
```
The algorithm starts by initializing some variables. `count` tracks the balance of 1's and 0's in the special binary string, and `i` tracks the starting index for extracting subproblems.

Iterating through the input string `s`, the algorithm updates `count`, incrementing it if the current character is '1' and decrementing if it's '0'. Whenever `count` becomes zero, it means that the current substring from index `i + 1` to index `j` is a valid special binary string. We proceed with the following steps:

1. Extract the substring from index `i + 1` to index `j`.
2. Recursively apply the function `makeLargestSpecial()` on the extracted substring.
3. Concatenate the string "1" before and the string "0" after the result and add the resulting string into a list of substrings called `subs`.
4. Update the `i` variable to the next index after `j`.

After processing the entire input string in this way, we have several special binary substrings in `subs`. We sort the substrings in decreasing (non-ascending) order and concatenate them together to form the largest lexicographically possible string as the final result.

## A solution in Javascript

```javascript
function makeLargestSpecial(s) {
    let count = 0, i = 0;
    let subs = [];

    for (let j = 0; j < s.length; j++) {
        if (s[j] === '1') count++;
        else count--;

        if (count === 0) {
            subs.push("1" + makeLargestSpecial(s.slice(i+1, j)) + "0");
            i = j + 1;
        }
    }

    subs.sort((a, b) => b.localeCompare(a));
    return subs.join('');
}
```
The algorithm starts by initializing some variables. `count` tracks the balance of 1's and 0's in the special binary string, and `i` tracks the starting index for extracting subproblems.

Iterating through the input string `s`, the algorithm updates `count`, incrementing it if the current character is '1' and decrementing if it's '0'. Whenever `count` becomes zero, it means that the current substring from index `i + 1` to index `j` is a valid special binary string. We proceed with the following steps:

1. Extract the substring from index `i + 1` to index `j`.
2. Recursively apply the function `makeLargestSpecial()` on the extracted substring.
3. Concatenate the string "1" before and the string "0" after the result and add the resulting string into a list of substrings called `subs`.
4. Update the `i` variable to the next index after `j`.

After processing the entire input string in this way, we have several special binary substrings in `subs`. We sort the substrings in decreasing (non-ascending) order and concatenate them together to form the largest lexicographically possible string as the final result.


# Prime Number of Set Bits in Binary Representation

- slug: prime-number-of-set-bits-in-binary-representation
- difficulty: Easy

Given two integers `left` and `right`, return _the **count** of numbers in the **inclusive** range_ `[left, right]` _having a **prime number of set bits** in their binary representation_.

Recall that the **number of set bits** an integer has is the number of `1`'s present when written in binary.

*   For example, `21` written in binary is `10101`, which has `3` set bits.

**Example 1:**

**Input:** left = 6, right = 10
**Output:** 4
**Explanation:**
6  -> 110 (2 set bits, 2 is prime)
7  -> 111 (3 set bits, 3 is prime)
8  -> 1000 (1 set bit, 1 is not prime)
9  -> 1001 (2 set bits, 2 is prime)
10 -> 1010 (2 set bits, 2 is prime)
4 numbers have a prime number of set bits.

**Example 2:**

**Input:** left = 10, right = 15
**Output:** 5
**Explanation:**
10 -> 1010 (2 set bits, 2 is prime)
11 -> 1011 (3 set bits, 3 is prime)
12 -> 1100 (2 set bits, 2 is prime)
13 -> 1101 (3 set bits, 3 is prime)
14 -> 1110 (3 set bits, 3 is prime)
15 -> 1111 (4 set bits, 4 is not prime)
5 numbers have a prime number of set bits.

**Constraints:**

*   `1 <= left <= right <= 106`
*   `0 <= right - left <= 104`

## A solution in Java

```java
class Solution {
    boolean isPrime(int n) {
        if (n <= 1) return false;
        if (n <= 3) return true;
        if (n % 2 == 0 || n % 3 == 0) return false;
        for (int i = 5; i * i <= n; i += 6)
            if (n % i == 0 || n % (i + 2) == 0) return false;
        return true;
    }

    public int countPrimeSetBits(int left, int right) {
        int count = 0;
        for (int i = left; i <= right; ++i)
            count += isPrime(Integer.bitCount(i)) ? 1 : 0;
        return count;
    }
}
```
The algorithm first defines a helper function `isPrime` to check if a given number is a prime number. Then, in the main `countPrimeSetBits` function, we iterate through the given range `[left, right]`. For each number, we count the number of 1's in its binary representation and check for primality of that count. If the count is a prime number, we increment the final count of numbers with prime set bits.

## A solution in C++

```cpp
#include <bitset>

bool isPrime(int n) {
    if (n <= 1) return false;
    if (n <= 3) return true;
    if (n % 2 == 0 || n % 3 == 0) return false;
    for (int i = 5; i * i <= n; i += 6)
        if (n % i == 0 || n % (i + 2) == 0) return false;
    return true;
}

int countPrimeSetBits(int left, int right) {
    int count = 0;
    for (int i = left; i <= right; ++i)
        count += isPrime(std::bitset<32>(i).count());
    return count;
}
```
The algorithm first defines a helper function `isPrime` to check if a given number is a prime number. Then, in the main `countPrimeSetBits` function, we iterate through the given range `[left, right]`. For each number, we count the number of 1's in its binary representation and check for primality of that count. If the count is a prime number, we increment the final count of numbers with prime set bits.

## A solution in Python

```python
def is_prime(n: int) -> bool:
    if n <= 1:
        return False
    if n <= 3:
        return True
    if n % 2 == 0 or n % 3 == 0:
        return False
    i = 5
    while i * i <= n:
        if n % i == 0 or n % (i + 2) == 0:
            return False
        i += 6
    return True

def count_prime_set_bits(left: int, right: int) -> int:
    return sum(is_prime(bin(i).count('1')) for i in range(left, right + 1))
```
The algorithm first defines a helper function `isPrime` to check if a given number is a prime number. Then, in the main `countPrimeSetBits` function, we iterate through the given range `[left, right]`. For each number, we count the number of 1's in its binary representation and check for primality of that count. If the count is a prime number, we increment the final count of numbers with prime set bits.

## A solution in Javascript

```javascript
function isPrime(n) {
    if (n <= 1) return false;
    if (n <= 3) return true;
    if (n % 2 === 0 || n % 3 === 0) return false;
    for (let i = 5; i * i <= n; i += 6)
        if (n % i === 0 || n % (i + 2) === 0) return false;
    return true;
}

function countPrimeSetBits(left, right) {
    let count = 0;
    for (let i = left; i <= right; ++i)
        count += isPrime(i.toString(2).split('1').length - 1) ? 1 : 0;
    return count;
}
```
The algorithm first defines a helper function `isPrime` to check if a given number is a prime number. Then, in the main `countPrimeSetBits` function, we iterate through the given range `[left, right]`. For each number, we count the number of 1's in its binary representation and check for primality of that count. If the count is a prime number, we increment the final count of numbers with prime set bits.