# K Inverse Pairs Array

- slug: k-inverse-pairs-array
- difficulty: Hard

For an integer array `nums`, an **inverse pair** is a pair of integers `[i, j]` where `0 <= i < j < nums.length` and `nums[i] > nums[j]`.

Given two integers n and k, return the number of different arrays consist of numbers from `1` to `n` such that there are exactly `k` **inverse pairs**. Since the answer can be huge, return it **modulo** `109 + 7`.

**Example 1:**

**Input:** n = 3, k = 0
**Output:** 1
**Explanation:** Only the array \[1,2,3\] which consists of numbers from 1 to 3 has exactly 0 inverse pairs.

**Example 2:**

**Input:** n = 3, k = 1
**Output:** 2
**Explanation:** The array \[1,3,2\] and \[2,1,3\] have exactly 1 inverse pair.

**Constraints:**

*   `1 <= n <= 1000`
*   `0 <= k <= 1000`

## A solution in Java

```java
public int kInversePairs(int n, int k) {
    int mod = 1000000007;
    int[][] dp = new int[n + 1][k + 1];
    for (int i = 1; i <= n; i++) {
        dp[i][0] = 1;
        for (int j = 1; j <= k; j++) {
            dp[i][j] = (dp[i][j - 1] + dp[i - 1][j]) % mod;
            if (j - i >= 0) {
                dp[i][j] = (dp[i][j] - dp[i - 1][j - i] + mod) % mod;
            }
        }
    }
    return dp[n][k];
}
```
We use dynamic programming to solve this problem. We create a 2D array dp where `dp[i][j]` represents the number of arrays with `i` elements having `j` inverse pairs. We initialize `dp[i][0]` to 1 for all `i`.

For each `i` and `j`, we update the value of `dp[i][j]` using the following relation:

`dp[i][j] = dp[i][j - 1] + dp[i - 1][j]`

If there are enough elements (i.e., `j - i >= 0`) to form an inverse pair, we subtract the number of inverse pairs using `dp[i - 1][j - i]`. After updating the value, we ensure that the result stays within the given range by taking the modulo with 10^9 + 7.

Finally, we return the value at `dp[n][k]`, which represents the number of arrays with `n` (1 to n) elements having exactly `k` inverse pairs.

## A solution in C++

```cpp
int kInversePairs(int n, int k) {
    int mod = 1e9 + 7;
    vector<vector<int>> dp(n + 1, vector<int>(k + 1, 0));
    for (int i = 1; i <= n; ++i) {
        dp[i][0] = 1;
        for (int j = 1; j <= k; ++j) {
            dp[i][j] = (dp[i][j - 1] + dp[i - 1][j]) % mod;
            if (j - i >= 0) {
                dp[i][j] = (dp[i][j] - dp[i - 1][j - i] + mod) % mod;
            }
        }
    }
    return dp[n][k];
}
```
We use dynamic programming to solve this problem. We create a 2D array dp where `dp[i][j]` represents the number of arrays with `i` elements having `j` inverse pairs. We initialize `dp[i][0]` to 1 for all `i`.

For each `i` and `j`, we update the value of `dp[i][j]` using the following relation:

`dp[i][j] = dp[i][j - 1] + dp[i - 1][j]`

If there are enough elements (i.e., `j - i >= 0`) to form an inverse pair, we subtract the number of inverse pairs using `dp[i - 1][j - i]`. After updating the value, we ensure that the result stays within the given range by taking the modulo with 10^9 + 7.

Finally, we return the value at `dp[n][k]`, which represents the number of arrays with `n` (1 to n) elements having exactly `k` inverse pairs.

## A solution in Python

```python
def kInversePairs(n: int, k: int) -> int:
    mod = 10**9 + 7
    dp = [[0] * (k + 1) for _ in range(n + 1)]
    for i in range(1, n + 1):
        dp[i][0] = 1
        for j in range(1, k + 1):
            dp[i][j] = (dp[i][j - 1] + dp[i - 1][j]) % mod
            if j - i >= 0:
                dp[i][j] = (dp[i][j] - dp[i - 1][j - i] + mod) % mod
    return dp[n][k]
```
We use dynamic programming to solve this problem. We create a 2D array dp where `dp[i][j]` represents the number of arrays with `i` elements having `j` inverse pairs. We initialize `dp[i][0]` to 1 for all `i`.

For each `i` and `j`, we update the value of `dp[i][j]` using the following relation:

`dp[i][j] = dp[i][j - 1] + dp[i - 1][j]`

If there are enough elements (i.e., `j - i >= 0`) to form an inverse pair, we subtract the number of inverse pairs using `dp[i - 1][j - i]`. After updating the value, we ensure that the result stays within the given range by taking the modulo with 10^9 + 7.

Finally, we return the value at `dp[n][k]`, which represents the number of arrays with `n` (1 to n) elements having exactly `k` inverse pairs.

## A solution in Javascript

```javascript
function kInversePairs(n, k) {
    const mod = 1e9 + 7;
    const dp = Array.from({ length: n + 1 }, () => Array(k + 1).fill(0));
    for (let i = 1; i <= n; ++i) {
        dp[i][0] = 1;
        for (let j = 1; j <= k; ++j) {
            dp[i][j] = (dp[i][j - 1] + dp[i - 1][j]) % mod;
            if (j - i >= 0) {
                dp[i][j] = (dp[i][j] - dp[i - 1][j - i] + mod) % mod;
            }
        }
    }
    return dp[n][k];
}
```
We use dynamic programming to solve this problem. We create a 2D array dp where `dp[i][j]` represents the number of arrays with `i` elements having `j` inverse pairs. We initialize `dp[i][0]` to 1 for all `i`.

For each `i` and `j`, we update the value of `dp[i][j]` using the following relation:

`dp[i][j] = dp[i][j - 1] + dp[i - 1][j]`

If there are enough elements (i.e., `j - i >= 0`) to form an inverse pair, we subtract the number of inverse pairs using `dp[i - 1][j - i]`. After updating the value, we ensure that the result stays within the given range by taking the modulo with 10^9 + 7.

Finally, we return the value at `dp[n][k]`, which represents the number of arrays with `n` (1 to n) elements having exactly `k` inverse pairs.


# Course Schedule III

- slug: course-schedule-iii
- difficulty: Hard

There are `n` different online courses numbered from `1` to `n`. You are given an array `courses` where `courses[i] = [durationi, lastDayi]` indicate that the `ith` course should be taken **continuously** for `durationi` days and must be finished before or on `lastDayi`.

You will start on the `1st` day and you cannot take two or more courses simultaneously.

Return _the maximum number of courses that you can take_.

**Example 1:**

**Input:** courses = \[\[100,200\],\[200,1300\],\[1000,1250\],\[2000,3200\]\]
**Output:** 3
Explanation:
There are totally 4 courses, but you can take 3 courses at most:
First, take the 1st course, it costs 100 days so you will finish it on the 100th day, and ready to take the next course on the 101st day.
Second, take the 3rd course, it costs 1000 days so you will finish it on the 1100th day, and ready to take the next course on the 1101st day.
Third, take the 2nd course, it costs 200 days so you will finish it on the 1300th day.
The 4th course cannot be taken now, since you will finish it on the 3300th day, which exceeds the closed date.

**Example 2:**

**Input:** courses = \[\[1,2\]\]
**Output:** 1

**Example 3:**

**Input:** courses = \[\[3,2\],\[4,3\]\]
**Output:** 0

**Constraints:**

*   `1 <= courses.length <= 104`
*   `1 <= durationi, lastDayi <= 104`

## A solution in Java

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

public int scheduleCourse(int[][] courses) {
    Arrays.sort(courses, (a, b) -> a[1] - b[1]);

    PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
    int time = 0;

    for (int[] course : courses) {
        time += course[0];
        pq.offer(course[0]);

        if (time > course[1]) {
            time -= pq.poll();
        }
    }

    return pq.size();
}
```
1. Sort the courses based on their deadline (lastDay).
2. Create a max-heap (priority queue) to store the course durations.
3. Initialize a variable `time` to track the current time (start at 0).
4. Iterate through the sorted courses:
   a. Add the duration to the `time`.
   b. Push the duration to the max-heap.
   c. If the `time` is greater than the course's deadline, then remove the longest duration from max-heap and subtract it from `time`.
5. Return the size of the max-heap, which represents the number of courses that can be taken.

By sorting the courses by deadline and using a max-heap to store durations, we can efficiently determine which courses to take and which to drop when the deadline is not met. This greedy approach ensures that at each iteration, the optimal solution is reached up to the current course.

## A solution in C++

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

int scheduleCourse(std::vector<std::vector<int>>& courses) {
    std::sort(courses.begin(), courses.end(), [](const std::vector<int>& a, const std::vector<int>& b) {
        return a[1] < b[1];
    });

    std::priority_queue<int> pq;
    int time = 0;

    for (const auto& course : courses) {
        time += course[0];
        pq.push(course[0]);

        if (time > course[1]) {
            time -= pq.top();
            pq.pop();
        }
    }

    return pq.size();
}
```
1. Sort the courses based on their deadline (lastDay).
2. Create a max-heap (priority queue) to store the course durations.
3. Initialize a variable `time` to track the current time (start at 0).
4. Iterate through the sorted courses:
   a. Add the duration to the `time`.
   b. Push the duration to the max-heap.
   c. If the `time` is greater than the course's deadline, then remove the longest duration from max-heap and subtract it from `time`.
5. Return the size of the max-heap, which represents the number of courses that can be taken.

By sorting the courses by deadline and using a max-heap to store durations, we can efficiently determine which courses to take and which to drop when the deadline is not met. This greedy approach ensures that at each iteration, the optimal solution is reached up to the current course.

## A solution in Python

```python
import heapq

def scheduleCourse(courses):
    courses.sort(key=lambda x: x[1])
    curr_time, duration_sum = 0, []

    for duration, deadline in courses:
        curr_time += duration
        heapq.heappush(duration_sum, -duration)

        if curr_time > deadline:
            curr_time += heapq.heappop(duration_sum)

    return len(duration_sum)
```
1. Sort the courses based on their deadline (lastDay).
2. Create a max-heap (priority queue) to store the course durations.
3. Initialize a variable `time` to track the current time (start at 0).
4. Iterate through the sorted courses:
   a. Add the duration to the `time`.
   b. Push the duration to the max-heap.
   c. If the `time` is greater than the course's deadline, then remove the longest duration from max-heap and subtract it from `time`.
5. Return the size of the max-heap, which represents the number of courses that can be taken.

By sorting the courses by deadline and using a max-heap to store durations, we can efficiently determine which courses to take and which to drop when the deadline is not met. This greedy approach ensures that at each iteration, the optimal solution is reached up to the current course.

## A solution in Javascript

```javascript
function scheduleCourse(courses) {
    courses.sort((a, b) => a[1] - b[1]);

    const pq = new PriorityQueue((a, b) => b - a);
    let time = 0;

    for (const course of courses) {
        time += course[0];
        pq.push(course[0]);

        if (time > course[1]) {
            time -= pq.pop();
        }
    }

    return pq.size();
}

class PriorityQueue {
    constructor(comparator) {
        this.data = [];
        this.comparator = comparator;
    }

    push(item) {
        this.data.push(item);
        this.data.sort(this.comparator);
    }

    pop() {
        return this.data.shift();
    }

    size() {
        return this.data.length;
    }
}
```
1. Sort the courses based on their deadline (lastDay).
2. Create a max-heap (priority queue) to store the course durations.
3. Initialize a variable `time` to track the current time (start at 0).
4. Iterate through the sorted courses:
   a. Add the duration to the `time`.
   b. Push the duration to the max-heap.
   c. If the `time` is greater than the course's deadline, then remove the longest duration from max-heap and subtract it from `time`.
5. Return the size of the max-heap, which represents the number of courses that can be taken.

By sorting the courses by deadline and using a max-heap to store durations, we can efficiently determine which courses to take and which to drop when the deadline is not met. This greedy approach ensures that at each iteration, the optimal solution is reached up to the current course.


# Design Excel Sum Formula

- slug: design-excel-sum-formula
- difficulty: Hard

Design the basic function of **Excel** and implement the function of the sum formula.

Implement the `Excel` class:

*   `Excel(int height, char width)` Initializes the object with the `height` and the `width` of the sheet. The sheet is an integer matrix `mat` of size `height x width` with the row index in the range `[1, height]` and the column index in the range `['A', width]`. All the values should be **zero** initially.
*   `void set(int row, char column, int val)` Changes the value at `mat[row][column]` to be `val`.
*   `int get(int row, char column)` Returns the value at `mat[row][column]`.
*   `int sum(int row, char column, List numbers)` Sets the value at `mat[row][column]` to be the sum of cells represented by `numbers` and returns the value at `mat[row][column]`. This sum formula **should exist** until this cell is overlapped by another value or another sum formula. `numbers[i]` could be on the format:
    *   `"ColRow "` that represents a single cell.
        *   For example, `"F7 "` represents the cell `mat[7]['F']`.
    *   `"ColRow1:ColRow2 "` that represents a range of cells. The range will always be a rectangle where `"ColRow1 "` represent the position of the top-left cell, and `"ColRow2 "` represents the position of the bottom-right cell.
        *   For example, `"B3:F7 "` represents the cells `mat[i][j]` for `3 <= i <= 7` and `'B' <= j <= 'F'`.

**Note:** You could assume that there will not be any circular sum reference.

*   For example, `mat[1]['A'] == sum(1, "B ")` and `mat[1]['B'] == sum(1, "A ")`.

**Example 1:**

**Input**
\[ "Excel ",  "set ",  "sum ",  "set ",  "get "\]
\[\[3,  "C "\], \[1,  "A ", 2\], \[3,  "C ", \[ "A1 ",  "A1:B2 "\]\], \[2,  "B ", 2\], \[3,  "C "\]\]
**Output**
\[null, null, 4, null, 6\]

**Explanation**
Excel excel = new Excel(3,  "C ");
 // construct a 3\*3 2D array with all zero.
 //   A B C
 // 1 0 0 0
 // 2 0 0 0
 // 3 0 0 0
excel.set(1,  "A ", 2);
 // set mat\[1\]\[ "A "\] to be 2.
 //   A B C
 // 1 2 0 0
 // 2 0 0 0
 // 3 0 0 0
excel.sum(3,  "C ", \[ "A1 ",  "A1:B2 "\]); // return 4
 // set mat\[3\]\[ "C "\] to be the sum of value at mat\[1\]\[ "A "\] and the values sum of the rectangle range whose top-left cell is mat\[1\]\[ "A "\] and bottom-right cell is mat\[2\]\[ "B "\].
 //   A B C
 // 1 2 0 0
 // 2 0 0 0
 // 3 0 0 4
excel.set(2,  "B ", 2);
 // set mat\[2\]\[ "B "\] to be 2. Note mat\[3\]\[ "C "\] should also be changed.
 //   A B C
 // 1 2 0 0
 // 2 0 2 0
 // 3 0 0 6
excel.get(3,  "C "); // return 6

**Constraints:**

*   `1 <= height <= 26`
*   `'A' <= width <= 'Z'`
*   `1 <= row <= height`
*   `'A' <= column <= width`
*   `-100 <= val <= 100`
*   `1 <= numbers.length <= 5`
*   `numbers[i]` has the format `"ColRow "` or `"ColRow1:ColRow2 "`.
*   At most `100` calls will be made to `set`, `get`, and `sum`.

## A solution in Java

```java
import java.util.*;

class Excel {

    int[][] mat;
    Map<String, List<String>> formulas;

    public Excel(int height, char width) {
        mat = new int[height][width - 'A' + 1];
        formulas = new HashMap<>();
    }

    public void set(int row, char column, int val) {
        String pos = String.format("%c%d", column, row);
        formulas.remove(pos);
        mat[row - 1][column - 'A'] = val;
    }

    public int get(int row, char column) {
        String pos = String.format("%c%d", column, row);
        if (formulas.containsKey(pos)) {
            return sum(row, column, formulas.get(pos));
        }
        return mat[row - 1][column - 'A'];
    }

    public int sum(int row, char column, List<String> numbers) {
        int total = 0;
        for (String num : numbers) {
            if (num.contains(":")) {
                String[] parts = num.split(":");
                int startRow = Integer.parseInt(parts[0].substring(1));
                int endRow = Integer.parseInt(parts[1].substring(1));
                char startCol = parts[0].charAt(0);
                char endCol = parts[1].charAt(0);
                for (int r = startRow; r <= endRow; r++) {
                    for (char c = startCol; c <= endCol; c++) {
                        total += get(r, c);
                    }
                }
            } else {
                total += get(Integer.parseInt(num.substring(1)), num.charAt(0));
            }
        }
        set(row, column, total);
        formulas.put(String.format("%c%d", column, row), numbers);
        return total;
    }
}
```
The algorithm for this problem involves using a 2D array (matrix) to represent the values in the Excel sheet and a hashmap (formulas) to store sum formulas for cells in the Excel sheet. When using the 'set' method, the cell value in the matrix is set to the input value and any existing sum formula for the cell is removed. When using the 'get' method, the method first checks if a sum formula exists for the cell in focus. If it does, it returns the result of the sum formula without updating the matrix; otherwise, it returns the value in the matrix for the cell. When using the 'sum' method, the algorithm iterates through the input 'numbers', summing up the corresponding cell values based on the range given by either a single cell reference or a range of cells. The sum total is then set as the cell value in the matrix and the formula is stored in the 'formulas' hashmap. The sum total is returned as the result.

## A solution in C++

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

using namespace std;

class Excel {
public:
    vector<vector<int>> mat;
    unordered_map<string, pair<string, vector<string>>> formulas;

    Excel(int height, char width) {
        mat.resize(height, vector<int>(width - 'A' + 1));
    }

    void set(int row, char column, int val) {
        row--; column -= 'A';
        string pos = string(1, column + 'A') + to_string(row + 1);
        formulas.erase(pos);
        mat[row][column] = val;
    }

    int get(int row, char column) {
        row--; column -= 'A';
        string pos = string(1, column + 'A') + to_string(row + 1);
        if (formulas.count(pos)) {
            int sum = 0;
            for (string &r : formulas[pos].second) {
                auto x = r.find(':');
                if (x == string::npos) {
                    int rRow = stoi(r.substr(1)) - 1;
                    int rCol = r[0] - 'A';
                    sum += get(rRow + 1, rCol + 'A');
                } else {
                    int r1Row = stoi(r.substr(1, x - 1)) - 1;
                    int r1Col = r[0] - 'A';
                    int r2Row = stoi(r.substr(x + 2)) - 1;
                    int r2Col = r[x + 1] - 'A';
                    for (int i = r1Row; i <= r2Row; ++i)
                        for (int j = r1Col; j <= r2Col; ++j)
                            sum += get(i + 1, j + 'A');
                }
            }
            return sum;
        }
        return mat[row][column];
    }

    int sum(int row, char column, vector<string> numbers) {
        int total = 0;
        string pos = string(1, column) + to_string(row);
        for (auto &num : numbers) total += get(stoi(num.substr(1)), num[0]);
        formulas[pos] = make_pair(pos, numbers);
        set(row, column, total);
        return total;
    }
};
```
The algorithm for this problem involves using a 2D array (matrix) to represent the values in the Excel sheet and a hashmap (formulas) to store sum formulas for cells in the Excel sheet. When using the 'set' method, the cell value in the matrix is set to the input value and any existing sum formula for the cell is removed. When using the 'get' method, the method first checks if a sum formula exists for the cell in focus. If it does, it returns the result of the sum formula without updating the matrix; otherwise, it returns the value in the matrix for the cell. When using the 'sum' method, the algorithm iterates through the input 'numbers', summing up the corresponding cell values based on the range given by either a single cell reference or a range of cells. The sum total is then set as the cell value in the matrix and the formula is stored in the 'formulas' hashmap. The sum total is returned as the result.

## A solution in Python

```python
class Excel:

    def __init__(self, height: int, width: str):
        self.mat = [[0] * (ord(width) - ord('A') + 1) for _ in range(height)]
        self.formulas = {}

    def set(self, row: int, column: str, val: int) -> None:
        pos = column + str(row)
        if pos in self.formulas:
            del self.formulas[pos]
        self.mat[row - 1][ord(column) - ord('A')] = val

    def get(self, row: int, column: str) -> int:
        pos = column + str(row)
        if pos in self.formulas:
            return self.sum(row, column, self.formulas[pos])
        return self.mat[row - 1][ord(column) - ord('A')]

    def sum(self, row: int, column: str, numbers) -> int:
        total = 0
        for num in numbers:
            if ':' in num:
                start, end = num.split(':')
                start_row, end_row = int(start[1:]), int(end[1:])
                start_col, end_col = start[0], end[0]
                for r in range(start_row, end_row + 1):
                    for c in range(ord(start_col), ord(end_col) + 1):
                        total += self.get(r, chr(c))
            else:
                total += self.get(int(num[1:]), num[0])
        self.set(row, column, total)
        self.formulas[column + str(row)] = numbers
        return total
```
The algorithm for this problem involves using a 2D array (matrix) to represent the values in the Excel sheet and a hashmap (formulas) to store sum formulas for cells in the Excel sheet. When using the 'set' method, the cell value in the matrix is set to the input value and any existing sum formula for the cell is removed. When using the 'get' method, the method first checks if a sum formula exists for the cell in focus. If it does, it returns the result of the sum formula without updating the matrix; otherwise, it returns the value in the matrix for the cell. When using the 'sum' method, the algorithm iterates through the input 'numbers', summing up the corresponding cell values based on the range given by either a single cell reference or a range of cells. The sum total is then set as the cell value in the matrix and the formula is stored in the 'formulas' hashmap. The sum total is returned as the result.

## A solution in Javascript

```javascript
class Excel {
    constructor(height, width) {
        this.mat = new Array(height).fill(null).map(() => new Array(width.charCodeAt(0)-'A'.charCodeAt(0)+1).fill(0));
        this.formulas = {};
    }

    set(row, column, val) {
        let pos = column + row.toString();
        delete this.formulas[pos];
        this.mat[row - 1][column.charCodeAt(0) - 'A'.charCodeAt(0)] = val;
    }

    get(row, column) {
        let pos = column + row.toString();
        if (pos in this.formulas) {
            return this.sum(row, column, this.formulas[pos]);
        }
        return this.mat[row - 1][column.charCodeAt(0) - 'A'.charCodeAt(0)];
    }

    sum(row, column, numbers) {
        let total = 0;
        for (let num of numbers) {
            if (num.includes(':')) {
                let parts = num.split(':');
                let startRow = parseInt(parts[0].substring(1));
                let endRow = parseInt(parts[1].substring(1));
                let startCol = parts[0].charAt(0);
                let endCol = parts[1].charAt(0);
                for (let r = startRow; r <= endRow; r++) {
                    for (let c = startCol.charCodeAt(0); c <= endCol.charCodeAt(0); c++) {
                        total += this.get(r, String.fromCharCode(c));
                    }
                }
            } else {
                total += this.get(parseInt(num.substring(1)), num.charAt(0));
            }
        }
        this.set(row, column, total);
        this.formulas[column + row.toString()] = numbers;
        return total;
    }
}
```
The algorithm for this problem involves using a 2D array (matrix) to represent the values in the Excel sheet and a hashmap (formulas) to store sum formulas for cells in the Excel sheet. When using the 'set' method, the cell value in the matrix is set to the input value and any existing sum formula for the cell is removed. When using the 'get' method, the method first checks if a sum formula exists for the cell in focus. If it does, it returns the result of the sum formula without updating the matrix; otherwise, it returns the value in the matrix for the cell. When using the 'sum' method, the algorithm iterates through the input 'numbers', summing up the corresponding cell values based on the range given by either a single cell reference or a range of cells. The sum total is then set as the cell value in the matrix and the formula is stored in the 'formulas' hashmap. The sum total is returned as the result.


# Smallest Range Covering Elements from K Lists

- slug: smallest-range-covering-elements-from-k-lists
- difficulty: Hard

You have `k` lists of sorted integers in **non-decreasing order**. Find the **smallest** range that includes at least one number from each of the `k` lists.

We define the range `[a, b]` is smaller than range `[c, d]` if `b - a < d - c` **or** `a < c` if `b - a == d - c`.

**Example 1:**

**Input:** nums = \[\[4,10,15,24,26\],\[0,9,12,20\],\[5,18,22,30\]\]
**Output:** \[20,24\]
**Explanation:**
List 1: \[4, 10, 15, 24,26\], 24 is in range \[20,24\].
List 2: \[0, 9, 12, 20\], 20 is in range \[20,24\].
List 3: \[5, 18, 22, 30\], 22 is in range \[20,24\].

**Example 2:**

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

**Constraints:**

*   `nums.length == k`
*   `1 <= k <= 3500`
*   `1 <= nums[i].length <= 50`
*   `-105 <= nums[i][j] <= 105`
*   `nums[i]` is sorted in **non-decreasing** order.

## A solution in Java

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

public int[] smallestRange(List<List<Integer>> nums) {
    PriorityQueue<int[]> minHeap = new PriorityQueue<>(Comparator.comparingInt(a -> a[0]));

    int maxVal = Integer.MIN_VALUE;
    for (int i = 0; i < nums.size(); i++) {
        minHeap.offer(new int[] {nums.get(i).get(0), i});
        maxVal = Math.max(maxVal, nums.get(i).get(0));
    }

    List<Integer> listIndices = new ArrayList<>();
    for (int i = 0; i < nums.size(); i++) {
        listIndices.add(0);
    }
    int minRange = Integer.MAX_VALUE;
    int start = -1, end = -1;

    while (minHeap.size() == nums.size()) {
        int[] entry = minHeap.poll();
        int val = entry[0];
        int listIdx = entry[1];
        int range = maxVal - val;

        if (range < minRange) {
            minRange = range;
            start = val;
            end = maxVal;
        }

        listIndices.set(listIdx, listIndices.get(listIdx) + 1);
        if (listIndices.get(listIdx) < nums.get(listIdx).size()) {
            int newVal = nums.get(listIdx).get(listIndices.get(listIdx));
            minHeap.offer(new int[] {newVal, listIdx});
            maxVal = Math.max(maxVal, newVal);
        }
    }

    return new int[] {start, end};
}
```
1. The algorithm starts by initializing a min heap, listIndices, maxVal, and the range [start, end].
2. Then, for each list in nums, we add the first element and its index into the min heap and update maxVal when necessary. Meanwhile, we fill listIndices with zeros.
3. We loop as long as min heap size is equal to the number of lists. Within the loop:
   a. We get the smallest value and its list index from the min heap.
   b. If it produces a smaller range, we update the range [start, end].
   c. We increment the relevant list index and update the current value when necessary.
   d. We push the newVal along with its listIdx into the min heap and update maxVal if needed.
4. Finally, the updated range is returned.

## A solution in C++

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

std::pair<int, int> smallestRange(std::vector<std::vector<int>>& nums) {
    auto listComparator = [](const auto& a, const auto& b) {
        return a.first > b.first;
    };

    std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, decltype(listComparator)> minHeap(listComparator);

    int maxVal = std::numeric_limits<int>::min();
    for (int i = 0; i < nums.size(); i++) {
        minHeap.push({nums[i][0], i});
        maxVal = std::max(maxVal, nums[i][0]);
    }

    std::vector<int> listIndices(nums.size(), 0);
    int minRange = std::numeric_limits<int>::max();
    int start = -1, end = -1;

    while (minHeap.size() == nums.size()) {
        auto entry = minHeap.top();
        minHeap.pop();
        int val = entry.first;
        int listIdx = entry.second;
        int range = maxVal - val;

        if (range < minRange) {
            minRange = range;
            start = val;
            end = maxVal;
        }

        listIndices[listIdx]++;
        if (listIndices[listIdx] < nums[listIdx].size()) {
            int newVal = nums[listIdx][listIndices[listIdx]];
            minHeap.push({newVal, listIdx});
            maxVal = std::max(maxVal, newVal);
        }
    }

    return {start, end};
}
```
1. The algorithm starts by initializing a min heap, listIndices, maxVal, and the range [start, end].
2. Then, for each list in nums, we add the first element and its index into the min heap and update maxVal when necessary. Meanwhile, we fill listIndices with zeros.
3. We loop as long as min heap size is equal to the number of lists. Within the loop:
   a. We get the smallest value and its list index from the min heap.
   b. If it produces a smaller range, we update the range [start, end].
   c. We increment the relevant list index and update the current value when necessary.
   d. We push the newVal along with its listIdx into the min heap and update maxVal if needed.
4. Finally, the updated range is returned.

## A solution in Python

```python
import heapq

def smallestRange(nums):
    minHeap = []
    maxVal = -1e9

    for i, lst in enumerate(nums):
        heapq.heappush(minHeap, (lst[0], i))
        maxVal = max(maxVal, lst[0])

    listIndices = [0] * len(nums)
    minRange = 1e9
    start, end = -1, -1

    while len(minHeap) == len(nums):
        val, listIdx = heapq.heappop(minHeap)
        range_ = maxVal - val

        if range_ < minRange:
            minRange = range_
            start, end = val, maxVal

        listIndices[listIdx] += 1
        if listIndices[listIdx] < len(nums[listIdx]):
            newVal = nums[listIdx][listIndices[listIdx]]
            heapq.heappush(minHeap, (newVal, listIdx))
            maxVal = max(maxVal, newVal)

    return [start, end]
```
1. The algorithm starts by initializing a min heap, listIndices, maxVal, and the range [start, end].
2. Then, for each list in nums, we add the first element and its index into the min heap and update maxVal when necessary. Meanwhile, we fill listIndices with zeros.
3. We loop as long as min heap size is equal to the number of lists. Within the loop:
   a. We get the smallest value and its list index from the min heap.
   b. If it produces a smaller range, we update the range [start, end].
   c. We increment the relevant list index and update the current value when necessary.
   d. We push the newVal along with its listIdx into the min heap and update maxVal if needed.
4. Finally, the updated range is returned.

## A solution in Javascript

```javascript
function smallestRange(nums) {
    const minHeap = [],
          listIndices = Array(nums.length).fill(0);

    let maxVal = -Infinity;

    for (let i = 0; i < nums.length; i++) {
        minHeap.push([nums[i][0], i]);
        maxVal = Math.max(maxVal, nums[i][0]);
    }
    minHeap.sort(([a], [b]) => a - b);

    let minRange = Infinity,
        start = -1,
        end = -1;

    while (minHeap.length === nums.length) {
        const [val, listIdx] = minHeap.shift();
        const range = maxVal - val;

        if (range < minRange) {
            minRange = range;
            start = val;
            end = maxVal;
        }

        listIndices[listIdx]++;
        if (listIndices[listIdx] < nums[listIdx].length) {
            const newVal = nums[listIdx][listIndices[listIdx]];
            minHeap.push([newVal, listIdx]);
            minHeap.sort(([a], [b]) => a - b);
            maxVal = Math.max(maxVal, newVal);
        }
    }

    return [start, end];
}
```
1. The algorithm starts by initializing a min heap, listIndices, maxVal, and the range [start, end].
2. Then, for each list in nums, we add the first element and its index into the min heap and update maxVal when necessary. Meanwhile, we fill listIndices with zeros.
3. We loop as long as min heap size is equal to the number of lists. Within the loop:
   a. We get the smallest value and its list index from the min heap.
   b. If it produces a smaller range, we update the range [start, end].
   c. We increment the relevant list index and update the current value when necessary.
   d. We push the newVal along with its listIdx into the min heap and update maxVal if needed.
4. Finally, the updated range is returned.


# Sum of Square Numbers

- slug: sum-of-square-numbers
- difficulty: Medium

Given a non-negative integer `c`, decide whether there're two integers `a` and `b` such that `a2 + b2 = c`.

**Example 1:**

**Input:** c = 5
**Output:** true
**Explanation:** 1 \* 1 + 2 \* 2 = 5

**Example 2:**

**Input:** c = 3
**Output:** false

**Constraints:**

*   `0 <= c <= 231 - 1`

## A solution in Java

```java
class Solution {
    public boolean judgeSquareSum(int c) {
        for (int a = 0; a <= Math.sqrt(c); ++a) {
            int b = (int) Math.sqrt(c - a * a);
            if (a * a + b * b == c) {
                return true;
            }
        }
        return false;
    }
}
```
1. Initialize a variable `a` with a value of 0.
2. Iterate through each possible value of `a` until the square root of `c`.
3. For each value of `a`, calculate the square root of `c - a * a`, rounding down to an integer value (using floor function).
4. Check if a² + b² equals c, if yes, return true, indicating the existence of integers `a` and `b`.
5. If the loop is completed without finding such pair of integers, return false.

## A solution in C++

```cpp
#include <cmath>

bool judgeSquareSum(int c) {
    for (int a = 0; a <= sqrt(c); ++a) {
        int b = sqrt(c - a * a);
        if (a * a + b * b == c) {
            return true;
        }
    }
    return false;
}
```
1. Initialize a variable `a` with a value of 0.
2. Iterate through each possible value of `a` until the square root of `c`.
3. For each value of `a`, calculate the square root of `c - a * a`, rounding down to an integer value (using floor function).
4. Check if a² + b² equals c, if yes, return true, indicating the existence of integers `a` and `b`.
5. If the loop is completed without finding such pair of integers, return false.

## A solution in Python

```python
def judge_square_sum(c):
    for a in range(int(c ** 0.5) + 1):
        b = int((c - a * a) ** 0.5)
        if a * a + b * b == c:
            return True
    return False
```
1. Initialize a variable `a` with a value of 0.
2. Iterate through each possible value of `a` until the square root of `c`.
3. For each value of `a`, calculate the square root of `c - a * a`, rounding down to an integer value (using floor function).
4. Check if a² + b² equals c, if yes, return true, indicating the existence of integers `a` and `b`.
5. If the loop is completed without finding such pair of integers, return false.

## A solution in Javascript

```javascript
function judgeSquareSum(c) {
    for (let a = 0; a <= Math.sqrt(c); ++a) {
        let b = Math.floor(Math.sqrt(c - a * a));
        if (a * a + b * b === c) {
            return true;
        }
    }
    return false;
}
```
1. Initialize a variable `a` with a value of 0.
2. Iterate through each possible value of `a` until the square root of `c`.
3. For each value of `a`, calculate the square root of `c - a * a`, rounding down to an integer value (using floor function).
4. Check if a² + b² equals c, if yes, return true, indicating the existence of integers `a` and `b`.
5. If the loop is completed without finding such pair of integers, return false.


# Find the Derangement of An Array

- slug: find-the-derangement-of-an-array
- difficulty: Medium

In combinatorial mathematics, a **derangement** is a permutation of the elements of a set, such that no element appears in its original position.

You are given an integer `n`. There is originally an array consisting of `n` integers from `1` to `n` in ascending order, return _the number of **derangements** it can generate_. Since the answer may be huge, return it **modulo** `109 + 7`.

**Example 1:**

**Input:** n = 3
**Output:** 2
**Explanation:** The original array is \[1,2,3\]. The two derangements are \[2,3,1\] and \[3,1,2\].

**Example 2:**

**Input:** n = 2
**Output:** 1

**Constraints:**

*   `1 <= n <= 106`

## A solution in Java

```java
public int findDerangement(int n) {
    final int MOD = 1000000007;
    long[] dp = new long[n + 1];
    dp[2] = 1;
    for (int i = 3; i <= n; ++i) {
        dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]) % MOD;
    }
    return (int)dp[n];
}
```
To find the number of derangements, we can use the mathematical formula:

    D(n) = (n - 1) * [D(n - 1) + D(n - 2)]

Here, `D(n)` represents the number of derangements of length `n`. The base cases are D(1) = 0 and D(2) = 1.

We initialize a dynamic programming (DP) array `dp` where `dp[i]` represents the number of derangements of i elements.

The algorithm goes as follows:

1. Start a for-loop (for C++/Java: i = 3, for Python/JavaScript: i = range(3, n + 1))
2. For each value of i, calculate `dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]) % MOD`
3. Return the value of `dp[n]` as the final answer.

The result will be the number of derangements with elements up to n.

## A solution in C++

```cpp
int findDerangement(int n) {
    long MOD = 1e9 + 7;
    vector<long> dp(n + 1, 0);
    dp[2] = 1;
    for (int i = 3; i <= n; ++i) {
        dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]) % MOD;
    }
    return (int)dp[n];
}
```
To find the number of derangements, we can use the mathematical formula:

    D(n) = (n - 1) * [D(n - 1) + D(n - 2)]

Here, `D(n)` represents the number of derangements of length `n`. The base cases are D(1) = 0 and D(2) = 1.

We initialize a dynamic programming (DP) array `dp` where `dp[i]` represents the number of derangements of i elements.

The algorithm goes as follows:

1. Start a for-loop (for C++/Java: i = 3, for Python/JavaScript: i = range(3, n + 1))
2. For each value of i, calculate `dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]) % MOD`
3. Return the value of `dp[n]` as the final answer.

The result will be the number of derangements with elements up to n.

## A solution in Python

```python
def findDerangement(n: int) -> int:
    MOD = 10**9 + 7
    dp = [0] * (n + 1)
    dp[2] = 1
    for i in range(3, n + 1):
        dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]) % MOD
    return dp[n]
```
To find the number of derangements, we can use the mathematical formula:

    D(n) = (n - 1) * [D(n - 1) + D(n - 2)]

Here, `D(n)` represents the number of derangements of length `n`. The base cases are D(1) = 0 and D(2) = 1.

We initialize a dynamic programming (DP) array `dp` where `dp[i]` represents the number of derangements of i elements.

The algorithm goes as follows:

1. Start a for-loop (for C++/Java: i = 3, for Python/JavaScript: i = range(3, n + 1))
2. For each value of i, calculate `dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]) % MOD`
3. Return the value of `dp[n]` as the final answer.

The result will be the number of derangements with elements up to n.

## A solution in Javascript

```javascript
function findDerangement(n) {
    const MOD = 1000000007;
    let dp = new Array(n + 1).fill(0);
    dp[2] = 1;
    for (let i = 3; i <= n; ++i) {
        dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]) % MOD;
    }
    return dp[n];
}
```
To find the number of derangements, we can use the mathematical formula:

    D(n) = (n - 1) * [D(n - 1) + D(n - 2)]

Here, `D(n)` represents the number of derangements of length `n`. The base cases are D(1) = 0 and D(2) = 1.

We initialize a dynamic programming (DP) array `dp` where `dp[i]` represents the number of derangements of i elements.

The algorithm goes as follows:

1. Start a for-loop (for C++/Java: i = 3, for Python/JavaScript: i = range(3, n + 1))
2. For each value of i, calculate `dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]) % MOD`
3. Return the value of `dp[n]` as the final answer.

The result will be the number of derangements with elements up to n.


# Design Log Storage System

- slug: design-log-storage-system
- difficulty: Medium

You are given several logs, where each log contains a unique ID and timestamp. Timestamp is a string that has the following format: `Year:Month:Day:Hour:Minute:Second`, for example, `2017:01:01:23:59:59`. All domains are zero-padded decimal numbers.

Implement the `LogSystem` class:

*   `LogSystem()` Initializes the `LogSystem` object.
*   `void put(int id, string timestamp)` Stores the given log `(id, timestamp)` in your storage system.
*   `int[] retrieve(string start, string end, string granularity)` Returns the IDs of the logs whose timestamps are within the range from `start` to `end` inclusive. `start` and `end` all have the same format as `timestamp`, and `granularity` means how precise the range should be (i.e. to the exact `Day`, `Minute`, etc.). For example, `start = "2017:01:01:23:59:59 "`, `end = "2017:01:02:23:59:59 "`, and `granularity = "Day "` means that we need to find the logs within the inclusive range from **Jan. 1st 2017** to **Jan. 2nd 2017**, and the `Hour`, `Minute`, and `Second` for each log entry can be ignored.

**Example 1:**

**Input**
\[ "LogSystem ",  "put ",  "put ",  "put ",  "retrieve ",  "retrieve "\]
\[\[\], \[1,  "2017:01:01:23:59:59 "\], \[2,  "2017:01:01:22:59:59 "\], \[3,  "2016:01:01:00:00:00 "\], \[ "2016:01:01:01:01:01 ",  "2017:01:01:23:00:00 ",  "Year "\], \[ "2016:01:01:01:01:01 ",  "2017:01:01:23:00:00 ",  "Hour "\]\]
**Output**
\[null, null, null, null, \[3, 2, 1\], \[2, 1\]\]

**Explanation**
LogSystem logSystem = new LogSystem();
logSystem.put(1,  "2017:01:01:23:59:59 ");
logSystem.put(2,  "2017:01:01:22:59:59 ");
logSystem.put(3,  "2016:01:01:00:00:00 ");

// return \[3,2,1\], because you need to return all logs between 2016 and 2017.
logSystem.retrieve( "2016:01:01:01:01:01 ",  "2017:01:01:23:00:00 ",  "Year ");

// return \[2,1\], because you need to return all logs between Jan. 1, 2016 01:XX:XX and Jan. 1, 2017 23:XX:XX.
// Log 3 is not returned because Jan. 1, 2016 00:00:00 comes before the start of the range.
logSystem.retrieve( "2016:01:01:01:01:01 ",  "2017:01:01:23:00:00 ",  "Hour ");

**Constraints:**

*   `1 <= id <= 500`
*   `2000 <= Year <= 2017`
*   `1 <= Month <= 12`
*   `1 <= Day <= 31`
*   `0 <= Hour <= 23`
*   `0 <= Minute, Second <= 59`
*   `granularity` is one of the values `[ "Year ", "Month ", "Day ", "Hour ", "Minute ", "Second "]`.
*   At most `500` calls will be made to `put` and `retrieve`.

## A solution in Java

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

class LogSystem {
    Map<String, Integer> logs;
    Map<String, Integer> timeGranularity;

    public LogSystem() {
        logs = new HashMap<>();
        timeGranularity = new HashMap<>();
        String[] granularities = {"Year", "Month", "Day", "Hour", "Minute", "Second"};
        for (int i = 0; i < granularities.length; i++) {
            timeGranularity.put(granularities[i], i);
        }
    }

    public void put(int id, String timestamp) {
        logs.put(timestamp, id);
    }

    public List<Integer> retrieve(String start, String end, String granularity) {
        List<Integer> res = new ArrayList<>();
        int sizeSubstring = new int[]{4, 7, 10, 13, 16, 19}[timeGranularity.get(granularity)];

        for (Map.Entry<String, Integer> entry : logs.entrySet()) {
            String key = entry.getKey();
            if (start.substring(0, sizeSubstring).compareTo(key.substring(0, sizeSubstring)) <= 0
                    && end.substring(0, sizeSubstring).compareTo(key.substring(0, sizeSubstring)) >= 0) {
                res.add(entry.getValue());
            }
        }
        return res;
    }
}
```
The algorithm creates a data structure `logs` to store logs, and two helper data structures for handling the logic of granularities: `time_granularity` maps granularity names to indexes and `size_map` maps the indexes to the length of the timestamps according to the given granularity. These two data structures are used to compute the substring size needed in the `retrieve` function.

The `put` function simply adds a log entry to the `logs` structure.

The `retrieve` function iterates through the `logs` structure and checks if the portion of the timestamp that corresponds to the given granularity falls within the specified range. If yes, it adds the corresponding ID to the result list.

## A solution in C++

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

class LogSystem {
public:
    LogSystem() {
    }

    void put(int id, std::string timestamp) {
        logs[timestamp] = id;
    }

    std::vector<int> retrieve(std::string start, std::string end, std::string granularity) {
        std::vector<int> res;
        std::string min_timestamp, max_timestamp;
        int size_map[] = {4, 7, 10, 13, 16, 19};
        std::map<std::string, int> time_granularity = {{"Year", 0}, {"Month", 1}, {"Day", 2}, {"Hour", 3}, {"Minute", 4}, {"Second", 5}};
        int size_substring = size_map[time_granularity[granularity]];

        min_timestamp = start.substr(0, size_substring);
        max_timestamp = end.substr(0, size_substring);

        for (const auto &x : logs) {
            if (min_timestamp <= x.first.substr(0, size_substring) && max_timestamp >= x.first.substr(0, size_substring)) {
                res.push_back(x.second);
            }
        }
        return res;
    }

private:
    std::map<std::string, int> logs;
};
```
The algorithm creates a data structure `logs` to store logs, and two helper data structures for handling the logic of granularities: `time_granularity` maps granularity names to indexes and `size_map` maps the indexes to the length of the timestamps according to the given granularity. These two data structures are used to compute the substring size needed in the `retrieve` function.

The `put` function simply adds a log entry to the `logs` structure.

The `retrieve` function iterates through the `logs` structure and checks if the portion of the timestamp that corresponds to the given granularity falls within the specified range. If yes, it adds the corresponding ID to the result list.

## A solution in Python

```python
class LogSystem:

    def __init__(self):
        self.logs = {}
        self.time_granularity = {
            "Year": 0, "Month": 1, "Day": 2, "Hour": 3, "Minute": 4, "Second": 5
        }
        self.size_map = [4, 7, 10, 13, 16, 19]

    def put(self, id: int, timestamp: str) -> None:
        self.logs[timestamp] = id

    def retrieve(self, start: str, end: str, granularity: str) -> list[int]:
        size_substring = self.size_map[self.time_granularity[granularity]]
        res = []

        for k, v in self.logs.items():
            if start[:size_substring] <= k[:size_substring] <= end[:size_substring]:
                res.append(v)

        return res
```
The algorithm creates a data structure `logs` to store logs, and two helper data structures for handling the logic of granularities: `time_granularity` maps granularity names to indexes and `size_map` maps the indexes to the length of the timestamps according to the given granularity. These two data structures are used to compute the substring size needed in the `retrieve` function.

The `put` function simply adds a log entry to the `logs` structure.

The `retrieve` function iterates through the `logs` structure and checks if the portion of the timestamp that corresponds to the given granularity falls within the specified range. If yes, it adds the corresponding ID to the result list.

## A solution in Javascript

```javascript
class LogSystem {
    constructor() {
        this.logs = new Map();
        this.timeGranularity = new Map([['Year', 0], ['Month', 1], ['Day', 2], ['Hour', 3], ['Minute', 4], ['Second', 5]]);
        this.sizeMap = [4, 7, 10, 13, 16, 19];
    }

    put(id, timestamp) {
        this.logs.set(timestamp, id);
    }

    retrieve(start, end, granularity) {
        const sizeSubstring = this.sizeMap[this.timeGranularity.get(granularity)];
        let res = [];

        for (const [k, v] of this.logs.entries()) {
            if (k.substring(0, sizeSubstring) >= start.substring(0, sizeSubstring) && k.substring(0, sizeSubstring) <= end.substring(0, sizeSubstring)) {
                res.push(v);
            }
        }
        return res;
    }
}
```
The algorithm creates a data structure `logs` to store logs, and two helper data structures for handling the logic of granularities: `time_granularity` maps granularity names to indexes and `size_map` maps the indexes to the length of the timestamps according to the given granularity. These two data structures are used to compute the substring size needed in the `retrieve` function.

The `put` function simply adds a log entry to the `logs` structure.

The `retrieve` function iterates through the `logs` structure and checks if the portion of the timestamp that corresponds to the given granularity falls within the specified range. If yes, it adds the corresponding ID to the result list.


# Exclusive Time of Functions

- slug: exclusive-time-of-functions
- difficulty: Medium

On a **single-threaded** CPU, we execute a program containing `n` functions. Each function has a unique ID between `0` and `n-1`.

Function calls are **stored in a [call stack](https://en.wikipedia.org/wiki/Call_stack)**: when a function call starts, its ID is pushed onto the stack, and when a function call ends, its ID is popped off the stack. The function whose ID is at the top of the stack is **the current function being executed**. Each time a function starts or ends, we write a log with the ID, whether it started or ended, and the timestamp.

You are given a list `logs`, where `logs[i]` represents the `ith` log message formatted as a string `"{function_id}:{ "start " | "end "}:{timestamp} "`. For example, `"0:start:3 "` means a function call with function ID `0` **started at the beginning** of timestamp `3`, and `"1:end:2 "` means a function call with function ID `1` **ended at the end** of timestamp `2`. Note that a function can be called **multiple times, possibly recursively**.

A function's **exclusive time** is the sum of execution times for all function calls in the program. For example, if a function is called twice, one call executing for `2` time units and another call executing for `1` time unit, the **exclusive time** is `2 + 1 = 3`.

Return _the **exclusive time** of each function in an array, where the value at the_ `ith` _index represents the exclusive time for the function with ID_ `i`.

**Example 1:**

**Input:** n = 2, logs = \[ "0:start:0 ", "1:start:2 ", "1:end:5 ", "0:end:6 "\]
**Output:** \[3,4\]
**Explanation:**
Function 0 starts at the beginning of time 0, then it executes 2 for units of time and reaches the end of time 1.
Function 1 starts at the beginning of time 2, executes for 4 units of time, and ends at the end of time 5.
Function 0 resumes execution at the beginning of time 6 and executes for 1 unit of time.
So function 0 spends 2 + 1 = 3 units of total time executing, and function 1 spends 4 units of total time executing.

**Example 2:**

**Input:** n = 1, logs = \[ "0:start:0 ", "0:start:2 ", "0:end:5 ", "0:start:6 ", "0:end:6 ", "0:end:7 "\]
**Output:** \[8\]
**Explanation:**
Function 0 starts at the beginning of time 0, executes for 2 units of time, and recursively calls itself.
Function 0 (recursive call) starts at the beginning of time 2 and executes for 4 units of time.
Function 0 (initial call) resumes execution then immediately calls itself again.
Function 0 (2nd recursive call) starts at the beginning of time 6 and executes for 1 unit of time.
Function 0 (initial call) resumes execution at the beginning of time 7 and executes for 1 unit of time.
So function 0 spends 2 + 4 + 1 + 1 = 8 units of total time executing.

**Example 3:**

**Input:** n = 2, logs = \[ "0:start:0 ", "0:start:2 ", "0:end:5 ", "1:start:6 ", "1:end:6 ", "0:end:7 "\]
**Output:** \[7,1\]
**Explanation:**
Function 0 starts at the beginning of time 0, executes for 2 units of time, and recursively calls itself.
Function 0 (recursive call) starts at the beginning of time 2 and executes for 4 units of time.
Function 0 (initial call) resumes execution then immediately calls function 1.
Function 1 starts at the beginning of time 6, executes 1 unit of time, and ends at the end of time 6.
Function 0 resumes execution at the beginning of time 6 and executes for 2 units of time.
So function 0 spends 2 + 4 + 1 = 7 units of total time executing, and function 1 spends 1 unit of total time executing.

**Constraints:**

*   `1 <= n <= 100`
*   `1 <= logs.length <= 500`
*   `0 <= function_id < n`
*   `0 <= timestamp <= 109`
*   No two start events will happen at the same timestamp.
*   No two end events will happen at the same timestamp.
*   Each function has an `"end "` log for each `"start "` log.

## A solution in Java

```java
import java.util.List;
import java.util.Stack;

public int[] exclusiveTime(int n, List<String> logs) {
    int[] res = new int[n];
    Stack<Integer> stack = new Stack<>();
    int prevTime = 0;

    for (String log : logs) {
        String[] parts = log.split(":");
        int id = Integer.parseInt(parts[0]);
        String type = parts[1];
        int time = Integer.parseInt(parts[2]);

        if (type.equals("start")) {
            if (!stack.isEmpty()) {
                res[stack.peek()] += time - prevTime;
            }
            stack.push(id);
            prevTime = time;
        } else {
            res[stack.pop()] += time - prevTime + 1;
            prevTime = time + 1;
        }
    }

    return res;
}
```
The algorithm uses a stack to keep track of the active function calls. We iterate through the logs and parse each log to obtain the `id`, `type`, and `timestamp`.

If the current log type is "start", we check if the stack is not empty, and if so, we update the result entry for the function at the top of the stack by adding the time elapsed since the previous timestamp, `time - prev_time`. Then we push the new function's ID onto the stack and update the `prev_time` to the current `time`.

If the current log type is "end", we update the result entry for the function at the top of the stack by adding the time elapsed plus one, `time - prev_time + 1`. Then we pop the function's ID off the stack and update the `prev_time` to `time + 1`.

After processing all logs, the result array contains the exclusive time for each function.

## A solution in C++

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

std::vector<int> exclusiveTime(int n, std::vector<std::string>& logs) {
    std::vector<int> res(n, 0);
    std::stack<int> s;
    int prev_time = 0;

    for (const auto& log : logs) {
        auto colon1 = log.find(':');
        auto colon2 = log.rfind(':');

        int id = std::stoi(log.substr(0, colon1));
        std::string type = log.substr(colon1 + 1, colon2 - colon1 - 1);
        int time = std::stoi(log.substr(colon2 + 1));

        if (type == "start") {
            if (!s.empty()) {
                res[s.top()] += time - prev_time;
            }
            s.push(id);
            prev_time = time;
        } else {
            res[s.top()] += time - prev_time + 1;
            s.pop();
            prev_time = time + 1;
        }
    }

    return res;
}
```
The algorithm uses a stack to keep track of the active function calls. We iterate through the logs and parse each log to obtain the `id`, `type`, and `timestamp`.

If the current log type is "start", we check if the stack is not empty, and if so, we update the result entry for the function at the top of the stack by adding the time elapsed since the previous timestamp, `time - prev_time`. Then we push the new function's ID onto the stack and update the `prev_time` to the current `time`.

If the current log type is "end", we update the result entry for the function at the top of the stack by adding the time elapsed plus one, `time - prev_time + 1`. Then we pop the function's ID off the stack and update the `prev_time` to `time + 1`.

After processing all logs, the result array contains the exclusive time for each function.

## A solution in Python

```python
def exclusiveTime(n, logs):
    res = [0] * n
    stack = []
    prev_time = 0

    for log in logs:
        parts = log.split(':')
        id = int(parts[0])
        type = parts[1]
        time = int(parts[2])

        if type == "start":
            if stack:
                res[stack[-1]] += time - prev_time
            stack.append(id)
            prev_time = time
        else:
            res[stack.pop()] += time - prev_time + 1
            prev_time = time + 1

    return res
```
The algorithm uses a stack to keep track of the active function calls. We iterate through the logs and parse each log to obtain the `id`, `type`, and `timestamp`.

If the current log type is "start", we check if the stack is not empty, and if so, we update the result entry for the function at the top of the stack by adding the time elapsed since the previous timestamp, `time - prev_time`. Then we push the new function's ID onto the stack and update the `prev_time` to the current `time`.

If the current log type is "end", we update the result entry for the function at the top of the stack by adding the time elapsed plus one, `time - prev_time + 1`. Then we pop the function's ID off the stack and update the `prev_time` to `time + 1`.

After processing all logs, the result array contains the exclusive time for each function.

## A solution in Javascript

```javascript
function exclusiveTime(n, logs) {
    const res = new Array(n).fill(0);
    const stack = [];
    let prevTime = 0;

    for (const log of logs) {
        const parts = log.split(':');
        const id = parseInt(parts[0]);
        const type = parts[1];
        const time = parseInt(parts[2]);

        if (type === "start") {
            if (stack.length > 0) {
                res[stack[stack.length - 1]] += time - prevTime;
            }
            stack.push(id);
            prevTime = time;
        } else {
            res[stack.pop()] += time - prevTime + 1;
            prevTime = time + 1;
        }
    }

    return res;
}
```
The algorithm uses a stack to keep track of the active function calls. We iterate through the logs and parse each log to obtain the `id`, `type`, and `timestamp`.

If the current log type is "start", we check if the stack is not empty, and if so, we update the result entry for the function at the top of the stack by adding the time elapsed since the previous timestamp, `time - prev_time`. Then we push the new function's ID onto the stack and update the `prev_time` to the current `time`.

If the current log type is "end", we update the result entry for the function at the top of the stack by adding the time elapsed plus one, `time - prev_time + 1`. Then we pop the function's ID off the stack and update the `prev_time` to `time + 1`.

After processing all logs, the result array contains the exclusive time for each function.


# Average of Levels in Binary Tree

- slug: average-of-levels-in-binary-tree
- difficulty: Easy

Given the `root` of a binary tree, return _the average value of the nodes on each level in the form of an array_. Answers within `10-5` of the actual answer will be accepted.

**Example 1:**

**Input:** root = \[3,9,20,null,null,15,7\]
**Output:** \[3.00000,14.50000,11.00000\]
Explanation: The average value of nodes on level 0 is 3, on level 1 is 14.5, and on level 2 is 11.
Hence return \[3, 14.5, 11\].

**Example 2:**

**Input:** root = \[3,9,20,15,7\]
**Output:** \[3.00000,14.50000,11.00000\]

**Constraints:**

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

## A solution in Java

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

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

public List<Double> averageOfLevels(TreeNode root) {
    List<Double> result = new ArrayList<>();
    Queue<TreeNode> queue = new LinkedList<>();
    queue.add(root);

    while (!queue.isEmpty()) {
        long sum = 0;
        int count = 0;
        Queue<TreeNode> temp = new LinkedList<>();
        while (!queue.isEmpty()) {
            TreeNode currentNode = queue.poll();
            sum += currentNode.val;
            count++;
            if (currentNode.left != null) temp.add(currentNode.left);
            if (currentNode.right != null) temp.add(currentNode.right);
        }
        queue = temp;
        result.add((1.0 * sum) / count);
    }

    return result;
}
```
The algorithm uses a Breadth First Search (BFS) approach to solve this problem. A queue data structure is used to keep track of the tree nodes at each level. The algorithm iterates through each level of the binary tree, summing the values of all the nodes at the current level, and dividing by the number of nodes in that level to get the average. The result is added to a vector (C++), list (Java, Python), or array (JavaScript) and returned once the queue is empty, meaning all levels have been traversed.

## A solution in C++

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

using namespace std;

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

vector<double> averageOfLevels(TreeNode* root) {
    vector<double> result;
    queue<TreeNode*> q;
    q.push(root);

    while (!q.empty()) {
        long long sum = 0;
        int count = 0;
        queue<TreeNode*> temp;
        while (!q.empty()) {
            TreeNode* n = q.front();
            q.pop();
            sum += n->val;
            count++;
            if (n->left) temp.push(n->left);
            if (n->right) temp.push(n->right);
        }
        q = temp;
        result.push_back(static_cast<double>(sum) / count);
    }

    return result;
}
```
The algorithm uses a Breadth First Search (BFS) approach to solve this problem. A queue data structure is used to keep track of the tree nodes at each level. The algorithm iterates through each level of the binary tree, summing the values of all the nodes at the current level, and dividing by the number of nodes in that level to get the average. The result is added to a vector (C++), list (Java, Python), or array (JavaScript) and returned once the queue is empty, meaning all levels have been traversed.

## A solution in Python

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

def averageOfLevels(root: TreeNode):
    result = []
    queue = [root]

    while queue:
        sum_ = 0
        count = 0
        temp = []
        while queue:
            node = queue.pop(0)
            sum_ += node.val
            count += 1
            if node.left: temp.append(node.left)
            if node.right: temp.append(node.right)
        queue = temp
        result.append(sum_ / count)

    return result
```
The algorithm uses a Breadth First Search (BFS) approach to solve this problem. A queue data structure is used to keep track of the tree nodes at each level. The algorithm iterates through each level of the binary tree, summing the values of all the nodes at the current level, and dividing by the number of nodes in that level to get the average. The result is added to a vector (C++), list (Java, Python), or array (JavaScript) and returned once the queue is empty, meaning all levels have been traversed.

## A solution in Javascript

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

function averageOfLevels(root) {
    let result = [];
    let queue = [root];

    while (queue.length > 0) {
        let sum = 0;
        let count = 0;
        let temp = [];
        while (queue.length > 0) {
            let currentNode = queue.shift();
            sum += currentNode.val;
            count++;
            if (currentNode.left !== null) temp.push(currentNode.left);
            if (currentNode.right !== null) temp.push(currentNode.right);
        }
        queue = temp;
        result.push(sum / count);
    }

    return result;
}
```
The algorithm uses a Breadth First Search (BFS) approach to solve this problem. A queue data structure is used to keep track of the tree nodes at each level. The algorithm iterates through each level of the binary tree, summing the values of all the nodes at the current level, and dividing by the number of nodes in that level to get the average. The result is added to a vector (C++), list (Java, Python), or array (JavaScript) and returned once the queue is empty, meaning all levels have been traversed.


# Shopping Offers

- slug: shopping-offers
- difficulty: Medium

In LeetCode Store, there are `n` items to sell. Each item has a price. However, there are some special offers, and a special offer consists of one or more different kinds of items with a sale price.

You are given an integer array `price` where `price[i]` is the price of the `ith` item, and an integer array `needs` where `needs[i]` is the number of pieces of the `ith` item you want to buy.

You are also given an array `special` where `special[i]` is of size `n + 1` where `special[i][j]` is the number of pieces of the `jth` item in the `ith` offer and `special[i][n]` (i.e., the last integer in the array) is the price of the `ith` offer.

Return _the lowest price you have to pay for exactly certain items as given, where you could make optimal use of the special offers_. You are not allowed to buy more items than you want, even if that would lower the overall price. You could use any of the special offers as many times as you want.

**Example 1:**

**Input:** price = \[2,5\], special = \[\[3,0,5\],\[1,2,10\]\], needs = \[3,2\]
**Output:** 14
**Explanation:** There are two kinds of items, A and B. Their prices are $2 and $5 respectively.
In special offer 1, you can pay $5 for 3A and 0B
In special offer 2, you can pay $10 for 1A and 2B.
You need to buy 3A and 2B, so you may pay $10 for 1A and 2B (special offer #2), and $4 for 2A.

**Example 2:**

**Input:** price = \[2,3,4\], special = \[\[1,1,0,4\],\[2,2,1,9\]\], needs = \[1,2,1\]
**Output:** 11
**Explanation:** The price of A is $2, and $3 for B, $4 for C.
You may pay $4 for 1A and 1B, and $9 for 2A ,2B and 1C.
You need to buy 1A ,2B and 1C, so you may pay $4 for 1A and 1B (special offer #1), and $3 for 1B, $4 for 1C.
You cannot add more items, though only $9 for 2A ,2B and 1C.

**Constraints:**

*   `n == price.length == needs.length`
*   `1 <= n <= 6`
*   `0 <= price[i], needs[i] <= 10`
*   `1 <= special.length <= 100`
*   `special[i].length == n + 1`
*   `0 <= special[i][j] <= 50`

## A solution in Java

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

public int shoppingOffers(List<Integer> price, List<List<Integer>> special, List<Integer> needs) {
    return shoppingOffersHelper(price, special, needs, 0);
}

private int shoppingOffersHelper(List<Integer> price, List<List<Integer>> special, List<Integer> needs, int index) {
    if (index == special.size()) {
        int sum = 0;
        for (int i = 0; i < needs.size(); ++i) {
            sum += price.get(i) * needs.get(i);
        }
        return sum;
    }

    int no_offer = shoppingOffersHelper(price, special, needs, index + 1);
    boolean can_apply_offer = true;
    for (int i = 0; i < needs.size(); ++i) {
        needs.set(i, needs.get(i) - special.get(index).get(i));
        if (needs.get(i) < 0) can_apply_offer = false;
    }

    int with_offer = Integer.MAX_VALUE;
    if (can_apply_offer) {
        int offer_cost = special.get(index).get(needs.size()) + shoppingOffersHelper(price, special, needs, index);
        with_offer = Math.min(no_offer, offer_cost);
    }

    for (int i = 0; i < needs.size(); ++i) {
        needs.set(i, needs.get(i) + special.get(index).get(i));
    }

    return can_apply_offer ? with_offer : no_offer;
}
```
The algorithm uses backtracking to solve the problem. We go through each special offer and recursively compute the cost of applying or not applying the offer. When no more offers are available, we compute the cost of buying the remaining items at their regular price.

We first define a helper function that takes the index of the current special offer as its argument:

1. If the index equals the number of special offers, this means that we have checked all special offers, and we should calculate the cost of buying the remaining items at their regular price. We return the sum of the price multiplied by the required number of items for each item.

2. Calculate the cost of not applying the current special offer by calling the helper function recursively with the next special offer.

3. Check if we can apply the current special offer. To do this, we subtract the number of items in the special offer from the required number of items. If any value in the `needs` array becomes negative, this means that the current special offer does not satisfy the shopping requirements, and we cannot apply it.

4. If the current special offer is applicable, we calculate the cost of applying it by adding the cost of the offer to the cost of applying the subsequent special offers. We then calculate the minimum cost between applying and not applying the current special offer.

5. Update the `needs` array by adding the number of items in the special offer to the required number of items. This is necessary because we subtracted these values earlier when checking if we could apply the offer.

6. If we can apply the current special offer, return the minimum cost between applying and not applying it. Otherwise, return the cost of not applying it.

Finally, we call the helper function with the initial value of 0 to solve the problem from the first special offer.

## A solution in C++

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

int shoppingOffersHelper(vector<int>& price, vector<vector<int>>& special, vector<int>& needs, int index) {
    if (index == special.size()) {
        int sum = 0;
        for (int i = 0; i < needs.size(); ++i) {
            sum += price[i] * needs[i];
        }
        return sum;
    }

    int no_offer = shoppingOffersHelper(price, special, needs, index + 1);
    bool can_apply_offer = true;
    for (int i = 0; i < needs.size(); ++i) {
        needs[i] -= special[index][i];
        if (needs[i] < 0) can_apply_offer = false;
    }

    int with_offer = INT_MAX;
    if (can_apply_offer) {
        int offer_cost = special[index][needs.size()] + shoppingOffersHelper(price, special, needs, index);
        with_offer = min(no_offer, offer_cost);
    }

    for (int i = 0; i < needs.size(); ++i) {
        needs[i] += special[index][i];
    }

    return can_apply_offer ? with_offer : no_offer;
}

int shoppingOffers(vector<int>& price, vector<vector<int>>& special, vector<int>& needs) {
    return shoppingOffersHelper(price, special, needs, 0);
}
```
The algorithm uses backtracking to solve the problem. We go through each special offer and recursively compute the cost of applying or not applying the offer. When no more offers are available, we compute the cost of buying the remaining items at their regular price.

We first define a helper function that takes the index of the current special offer as its argument:

1. If the index equals the number of special offers, this means that we have checked all special offers, and we should calculate the cost of buying the remaining items at their regular price. We return the sum of the price multiplied by the required number of items for each item.

2. Calculate the cost of not applying the current special offer by calling the helper function recursively with the next special offer.

3. Check if we can apply the current special offer. To do this, we subtract the number of items in the special offer from the required number of items. If any value in the `needs` array becomes negative, this means that the current special offer does not satisfy the shopping requirements, and we cannot apply it.

4. If the current special offer is applicable, we calculate the cost of applying it by adding the cost of the offer to the cost of applying the subsequent special offers. We then calculate the minimum cost between applying and not applying the current special offer.

5. Update the `needs` array by adding the number of items in the special offer to the required number of items. This is necessary because we subtracted these values earlier when checking if we could apply the offer.

6. If we can apply the current special offer, return the minimum cost between applying and not applying it. Otherwise, return the cost of not applying it.

Finally, we call the helper function with the initial value of 0 to solve the problem from the first special offer.

## A solution in Python

```python
from typing import List

def shoppingOffers(price: List[int], special: List[List[int]], needs: List[int]) -> int:
    def helper(index):
        if index == len(special):
            return sum(needs[i] * price[i] for i in range(len(needs)))

        no_offer = helper(index + 1)
        can_apply_offer = True
        for i in range(len(needs)):
            needs[i] -= special[index][i]
            if needs[i] < 0:
                can_apply_offer = False

        with_offer = float('inf')
        if can_apply_offer:
            offer_cost = special[index][-1] + helper(index)
            with_offer = min(no_offer, offer_cost)

        for i in range(len(needs)):
            needs[i] += special[index][i]

        return with_offer if can_apply_offer else no_offer

    return helper(0)
```
The algorithm uses backtracking to solve the problem. We go through each special offer and recursively compute the cost of applying or not applying the offer. When no more offers are available, we compute the cost of buying the remaining items at their regular price.

We first define a helper function that takes the index of the current special offer as its argument:

1. If the index equals the number of special offers, this means that we have checked all special offers, and we should calculate the cost of buying the remaining items at their regular price. We return the sum of the price multiplied by the required number of items for each item.

2. Calculate the cost of not applying the current special offer by calling the helper function recursively with the next special offer.

3. Check if we can apply the current special offer. To do this, we subtract the number of items in the special offer from the required number of items. If any value in the `needs` array becomes negative, this means that the current special offer does not satisfy the shopping requirements, and we cannot apply it.

4. If the current special offer is applicable, we calculate the cost of applying it by adding the cost of the offer to the cost of applying the subsequent special offers. We then calculate the minimum cost between applying and not applying the current special offer.

5. Update the `needs` array by adding the number of items in the special offer to the required number of items. This is necessary because we subtracted these values earlier when checking if we could apply the offer.

6. If we can apply the current special offer, return the minimum cost between applying and not applying it. Otherwise, return the cost of not applying it.

Finally, we call the helper function with the initial value of 0 to solve the problem from the first special offer.

## A solution in Javascript

```javascript
function shoppingOffers(price, special, needs) {
    function helper(index) {
        if (index === special.length) {
            return needs.reduce((sum, curr, i) => sum + curr * price[i], 0);
        }

        let no_offer = helper(index + 1);
        let can_apply_offer = true;
        for (let i = 0; i < needs.length; ++i) {
            needs[i] -= special[index][i];
            if (needs[i] < 0) can_apply_offer = false;
        }

        let with_offer = Infinity;
        if (can_apply_offer) {
            let offer_cost = special[index][needs.length] + helper(index);
            with_offer = Math.min(no_offer, offer_cost);
        }

        for (let i = 0; i < needs.length; ++i) {
            needs[i] += special[index][i];
        }

        return can_apply_offer ? with_offer : no_offer;
    }

    return helper(0);
}
```
The algorithm uses backtracking to solve the problem. We go through each special offer and recursively compute the cost of applying or not applying the offer. When no more offers are available, we compute the cost of buying the remaining items at their regular price.

We first define a helper function that takes the index of the current special offer as its argument:

1. If the index equals the number of special offers, this means that we have checked all special offers, and we should calculate the cost of buying the remaining items at their regular price. We return the sum of the price multiplied by the required number of items for each item.

2. Calculate the cost of not applying the current special offer by calling the helper function recursively with the next special offer.

3. Check if we can apply the current special offer. To do this, we subtract the number of items in the special offer from the required number of items. If any value in the `needs` array becomes negative, this means that the current special offer does not satisfy the shopping requirements, and we cannot apply it.

4. If the current special offer is applicable, we calculate the cost of applying it by adding the cost of the offer to the cost of applying the subsequent special offers. We then calculate the minimum cost between applying and not applying the current special offer.

5. Update the `needs` array by adding the number of items in the special offer to the required number of items. This is necessary because we subtracted these values earlier when checking if we could apply the offer.

6. If we can apply the current special offer, return the minimum cost between applying and not applying it. Otherwise, return the cost of not applying it.

Finally, we call the helper function with the initial value of 0 to solve the problem from the first special offer.


# Decode Ways II

- slug: decode-ways-ii
- difficulty: Hard

A message containing letters from `A-Z` can be **encoded** into numbers using the following mapping:

'A' ->  "1 "
'B' ->  "2 "
...
'Z' ->  "26 "

To **decode** an encoded message, all the digits must be grouped then mapped back into letters using the reverse of the mapping above (there may be multiple ways). For example, `"11106 "` can be mapped into:

*   `"AAJF "` with the grouping `(1 1 10 6)`
*   `"KJF "` with the grouping `(11 10 6)`

Note that the grouping `(1 11 06)` is invalid because `"06 "` cannot be mapped into `'F'` since `"6 "` is different from `"06 "`.

**In addition** to the mapping above, an encoded message may contain the `'*'` character, which can represent any digit from `'1'` to `'9'` (`'0'` is excluded). For example, the encoded message `"1* "` may represent any of the encoded messages `"11 "`, `"12 "`, `"13 "`, `"14 "`, `"15 "`, `"16 "`, `"17 "`, `"18 "`, or `"19 "`. Decoding `"1* "` is equivalent to decoding **any** of the encoded messages it can represent.

Given a string `s` consisting of digits and `'*'` characters, return _the **number** of ways to **decode** it_.

Since the answer may be very large, return it **modulo** `109 + 7`.

**Example 1:**

**Input:** s =  "\* "
**Output:** 9
**Explanation:** The encoded message can represent any of the encoded messages  "1 ",  "2 ",  "3 ",  "4 ",  "5 ",  "6 ",  "7 ",  "8 ", or  "9 ".
Each of these can be decoded to the strings  "A ",  "B ",  "C ",  "D ",  "E ",  "F ",  "G ",  "H ", and  "I " respectively.
Hence, there are a total of 9 ways to decode  "\* ".

**Example 2:**

**Input:** s =  "1\* "
**Output:** 18
**Explanation:** The encoded message can represent any of the encoded messages  "11 ",  "12 ",  "13 ",  "14 ",  "15 ",  "16 ",  "17 ",  "18 ", or  "19 ".
Each of these encoded messages have 2 ways to be decoded (e.g.  "11 " can be decoded to  "AA " or  "K ").
Hence, there are a total of 9 \* 2 = 18 ways to decode  "1\* ".

**Example 3:**

**Input:** s =  "2\* "
**Output:** 15
**Explanation:** The encoded message can represent any of the encoded messages  "21 ",  "22 ",  "23 ",  "24 ",  "25 ",  "26 ",  "27 ",  "28 ", or  "29 ".
 "21 ",  "22 ",  "23 ",  "24 ",  "25 ", and  "26 " have 2 ways of being decoded, but  "27 ",  "28 ", and  "29 " only have 1 way.
Hence, there are a total of (6 \* 2) + (3 \* 1) = 12 + 3 = 15 ways to decode  "2\* ".

**Constraints:**

*   `1 <= s.length <= 105`
*   `s[i]` is a digit or `'*'`.

## A solution in Java

```java
public int numDecodings(String s) {
    final int MOD = 1_000_000_007;
    int n = s.length();
    long[] dp = new long[n + 1];
    dp[0] = 1;
    dp[1] = s.charAt(0) == '*' ? 9 : (s.charAt(0) == '0' ? 0 : 1);

    for (int i = 2; i <= n; ++i) {
        char c = s.charAt(i - 1);
        char prevC = s.charAt(i - 2);

        if (c == '*') {
            dp[i] = 9 * dp[i - 1];
            if (prevC == '1') dp[i] += 9 * dp[i - 2];
            else if (prevC == '2') dp[i] += 6 * dp[i - 2];
            else if (prevC == '*') dp[i] += 15 * dp[i - 2];
        } else {
            dp[i] = (c != '0') ? dp[i - 1] : 0;
            int num = Integer.parseInt(s.substring(i - 2, i));
            if (prevC == '1' || (prevC == '2' && num <= 26)) dp[i] += dp[i - 2];
            else if (prevC == '*') dp[i] += (num <= 26 && num >= 10) ? 2 * dp[i - 2] : dp[i - 2];
        }
        dp[i] %= MOD;
    }
    return (int) dp[n];
}
```
The algorithm uses dynamic programming to calculate the number of ways to decode the string. The idea is to iterate over the characters of the string and, for each character `'c'`, calculate how many ways to decode the string up to the position of `'c'`.

We will use an array `dp`, where `dp[i]` holds the number of ways to decode the string up to position `i`. The base cases are `dp[0] = 1` and `dp[1]` is assigned depending on whether the first character is a star or not.

In each step, we will consider pairs of characters: the current character `'c'` and the previous character `'prevC'`. If `'c'` is a star, it can be replaced with any digit from '1' to '9', so we need to calculate how many ways we can decode each possibility. Similarly, we need to handle the case when `'c'` is not a star but `'prevC'` is.

Finally, we update the number of ways to decode the string at each position, taking care of the modulo operation to avoid integer overflow issues.

The final answer will be the number of ways to decode the entire string, which is stored in `dp[n]`.

## A solution in C++

```cpp
int numDecodings(const std::string& s) {
    const int MOD = 1e9 + 7;
    int n = s.size();
    std::vector<long long> dp(n + 1, 0);
    dp[0] = 1;
    dp[1] = s[0] == '*' ? 9 : (s[0] == '0' ? 0 : 1);

    for (int i = 2; i <= n; ++i) {
        if (s[i - 1] == '*') {
            dp[i] = 9 * dp[i - 1];
            if (s[i - 2] == '1') dp[i] += 9 * dp[i - 2];
            else if (s[i - 2] == '2') dp[i] += 6 * dp[i - 2];
            else if (s[i - 2] == '*') dp[i] += 15 * dp[i - 2];
        } else {
            dp[i] = (s[i - 1] != '0') ? dp[i - 1] : 0;
            int num = std::stoi(s.substr(i - 2, 2));
            if (s[i - 2] == '1' || (s[i - 2] == '2' && num <= 26)) dp[i] += dp[i - 2];
            else if (s[i - 2] == '*') dp[i] += (num <= 26 && num >= 10) ? 2 * dp[i - 2] : dp[i - 2];
        }
        dp[i] %= MOD;
    }
    return dp[n];
}
```
The algorithm uses dynamic programming to calculate the number of ways to decode the string. The idea is to iterate over the characters of the string and, for each character `'c'`, calculate how many ways to decode the string up to the position of `'c'`.

We will use an array `dp`, where `dp[i]` holds the number of ways to decode the string up to position `i`. The base cases are `dp[0] = 1` and `dp[1]` is assigned depending on whether the first character is a star or not.

In each step, we will consider pairs of characters: the current character `'c'` and the previous character `'prevC'`. If `'c'` is a star, it can be replaced with any digit from '1' to '9', so we need to calculate how many ways we can decode each possibility. Similarly, we need to handle the case when `'c'` is not a star but `'prevC'` is.

Finally, we update the number of ways to decode the string at each position, taking care of the modulo operation to avoid integer overflow issues.

The final answer will be the number of ways to decode the entire string, which is stored in `dp[n]`.

## A solution in Python

```python
def num_decodings(s: str) -> int:
    MOD = 10**9 + 7
    n = len(s)
    dp = [0] * (n + 1)
    dp[0] = 1
    dp[1] = 9 if s[0] == '*' else (0 if s[0] == '0' else 1)

    for i in range(2, n + 1):
        c, prev_c = s[i - 1], s[i - 2]

        if c == '*':
            dp[i] = 9 * dp[i - 1]
            if prev_c == '1': dp[i] += 9 * dp[i - 2]
            elif prev_c == '2': dp[i] += 6 * dp[i - 2]
            elif prev_c == '*': dp[i] += 15 * dp[i - 2]
        else:
            dp[i] = dp[i - 1] if c != '0' else 0
            num = int(s[i - 2 : i])
            if prev_c == '1' or (prev_c == '2' and num <= 26): dp[i] += dp[i - 2]
            elif prev_c == '*': dp[i] += 2 * dp[i - 2] if 10 <= num <= 26 else dp[i - 2]

        dp[i] %= MOD
    return dp[n]
```
The algorithm uses dynamic programming to calculate the number of ways to decode the string. The idea is to iterate over the characters of the string and, for each character `'c'`, calculate how many ways to decode the string up to the position of `'c'`.

We will use an array `dp`, where `dp[i]` holds the number of ways to decode the string up to position `i`. The base cases are `dp[0] = 1` and `dp[1]` is assigned depending on whether the first character is a star or not.

In each step, we will consider pairs of characters: the current character `'c'` and the previous character `'prevC'`. If `'c'` is a star, it can be replaced with any digit from '1' to '9', so we need to calculate how many ways we can decode each possibility. Similarly, we need to handle the case when `'c'` is not a star but `'prevC'` is.

Finally, we update the number of ways to decode the string at each position, taking care of the modulo operation to avoid integer overflow issues.

The final answer will be the number of ways to decode the entire string, which is stored in `dp[n]`.

## A solution in Javascript

```javascript
function numDecodings(s) {
    const MOD = 1_000_000_007;
    const n = s.length;
    const dp = new Array(n + 1).fill(0);
    dp[0] = 1;
    dp[1] = s[0] === '*' ? 9 : (s[0] === '0' ? 0 : 1);

    for (let i = 2; i <= n; ++i) {
        let c = s[i - 1];
        let prevC = s[i - 2];

        if (c === '*') {
            dp[i] = 9 * dp[i - 1];
            if (prevC === '1') dp[i] += 9 * dp[i - 2];
            else if (prevC === '2') dp[i] += 6 * dp[i - 2];
            else if (prevC === '*') dp[i] += 15 * dp[i - 2];
        } else {
            dp[i] = (c !== '0') ? dp[i - 1] : 0;
            let num = parseInt(s.slice(i - 2, i));
            if (prevC === '1' || (prevC === '2' && num <= 26)) dp[i] += dp[i - 2];
            else if (prevC === '*') dp[i] += (num <= 26 && num >= 10) ? 2 * dp[i - 2] : dp[i - 2];
        }
        dp[i] %= MOD;
    }
    return dp[n];
}
```
The algorithm uses dynamic programming to calculate the number of ways to decode the string. The idea is to iterate over the characters of the string and, for each character `'c'`, calculate how many ways to decode the string up to the position of `'c'`.

We will use an array `dp`, where `dp[i]` holds the number of ways to decode the string up to position `i`. The base cases are `dp[0] = 1` and `dp[1]` is assigned depending on whether the first character is a star or not.

In each step, we will consider pairs of characters: the current character `'c'` and the previous character `'prevC'`. If `'c'` is a star, it can be replaced with any digit from '1' to '9', so we need to calculate how many ways we can decode each possibility. Similarly, we need to handle the case when `'c'` is not a star but `'prevC'` is.

Finally, we update the number of ways to decode the string at each position, taking care of the modulo operation to avoid integer overflow issues.

The final answer will be the number of ways to decode the entire string, which is stored in `dp[n]`.


# Solve the Equation

- slug: solve-the-equation
- difficulty: Medium

Solve a given equation and return the value of `'x'` in the form of a string `"x=#value "`. The equation contains only `'+'`, `'-'` operation, the variable `'x'` and its coefficient. You should return `"No solution "` if there is no solution for the equation, or `"Infinite solutions "` if there are infinite solutions for the equation.

If there is exactly one solution for the equation, we ensure that the value of `'x'` is an integer.

**Example 1:**

**Input:** equation =  "x+5-3+x=6+x-2 "
**Output:**  "x=2 "

**Example 2:**

**Input:** equation =  "x=x "
**Output:**  "Infinite solutions "

**Example 3:**

**Input:** equation =  "2x=x "
**Output:**  "x=0 "

**Constraints:**

*   `3 <= equation.length <= 1000`
*   `equation` has exactly one `'='`.
*   `equation` consists of integers with an absolute value in the range `[0, 100]` without any leading zeros, and the variable `'x'`.

## A solution in Java

```java
public String solveEquation(String equation) {
    int coefficient = 0, value = 0, left = 1, operator = 1;
    String[] parts = (equation + "+").split("(?<=[+-])");
    for (String part : parts) {
        if (part.equals("=")) {
            left = -1;
            operator = 1;
        } else {
            String[] nums = part.split("x");
            int n = Integer.parseInt(nums[0]);
            (nums.length == 1 ? value : coefficient) += left * operator * n;
            operator = nums.length;
        }
    }

    if (coefficient == 0) {
        return value == 0 ? "Infinite solutions" : "No solution";
    }
    return "x=" + -value / coefficient;
}
```
The algorithm used to solve this problem is based on processing the given equation as a string and having separate variables to track the coefficients for both 'x' and the values separately.

1. Initialize variables to track coefficients (`coef`), values (`val`), position (`left`), and operation (`operate`).
2. Iterate through the equation, updating position and operation when encountering a `="+` or `"="`. Otherwise, separate the terms involving x and the constant values, updating their coefficients accordingly.
3. After processing the equation, check if the coefficient for x is 0.
   - If yes, return "Infinite solutions" if the value is also 0; otherwise, return "No solution".
   - If no, divide the value by the coefficient and return the result as "x=#value".

Note that the function for each language has some differences in parsing the input string and managing the internal data as needed but follows the same strategy throughout.

## A solution in C++

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

string solveEquation(string equation) {
    int coef = 0, val = 0, left = 1, operate = 1;
    istringstream in(equation + "+");
    char op;
    int n;
    string s;
    while (in >> op) {
        if (op == '=') {
            left = -1;
            operate = 1;
        } else {
            in >> n >> s;
            (s.size() == 0 ? val : coef) += (op == '+' ? 1 : -1) * left * operate * n;
            operate = s.size();
        }
    }

    if (coef == 0) {
        return val == 0 ? "Infinite solutions" : "No solution";
    } else {
        return "x=" + to_string(-val / coef);
    }
}
```
The algorithm used to solve this problem is based on processing the given equation as a string and having separate variables to track the coefficients for both 'x' and the values separately.

1. Initialize variables to track coefficients (`coef`), values (`val`), position (`left`), and operation (`operate`).
2. Iterate through the equation, updating position and operation when encountering a `="+` or `"="`. Otherwise, separate the terms involving x and the constant values, updating their coefficients accordingly.
3. After processing the equation, check if the coefficient for x is 0.
   - If yes, return "Infinite solutions" if the value is also 0; otherwise, return "No solution".
   - If no, divide the value by the coefficient and return the result as "x=#value".

Note that the function for each language has some differences in parsing the input string and managing the internal data as needed but follows the same strategy throughout.

## A solution in Python

```python
def solve_equation(equation: str) -> str:
    coef = val = left = operate = 0
    equation += '+'
    parts = [s.strip()+c for c in equation if c in '+-' for s in equation.split(c)]
    for part in parts:
        if part == '=':
            left = -1
            operate = 1
        else:
            n, x = part.split('x')
            value_to_change = 1 if n else int(n)
            if x:
                coef += (1 if part[0] == '+' else -1) * left * operate * value_to_change
            else:
                val += (1 if part[0] == '+' else -1) * left * operate * value_to_change
            operate = 1 - x.find('x')

    if coef == 0:
        return "Infinite solutions" if val == 0 else "No solution"
    return "x=" + str(-val // coef)
```
The algorithm used to solve this problem is based on processing the given equation as a string and having separate variables to track the coefficients for both 'x' and the values separately.

1. Initialize variables to track coefficients (`coef`), values (`val`), position (`left`), and operation (`operate`).
2. Iterate through the equation, updating position and operation when encountering a `="+` or `"="`. Otherwise, separate the terms involving x and the constant values, updating their coefficients accordingly.
3. After processing the equation, check if the coefficient for x is 0.
   - If yes, return "Infinite solutions" if the value is also 0; otherwise, return "No solution".
   - If no, divide the value by the coefficient and return the result as "x=#value".

Note that the function for each language has some differences in parsing the input string and managing the internal data as needed but follows the same strategy throughout.

## A solution in Javascript

```javascript
function solveEquation(equation) {
    let coef = 0, val = 0, left = 1, operate = 1;
    let parts = equation.replace(/([+-])/g, ' $1').split('=');
    let leftPart = parts[0].split(' ');
    let rightPart = parts[1].split(' ');

    for (let part of leftPart.concat(rightPart)) {
        if (part === '+') {
            operate = 1;
        } else if (part === '-') {
            operate = -1;
        } else if (part.includes('x')) {
            coef += parseInt(part.replace('x', '') || '1', 10) * operate * left;
        } else {
            val += parseInt(part, 10) * operate * left;
        }
    }

    if (coef === 0) {
        return val === 0 ? "Infinite solutions" : "No solution";
    } else {
        return "x=" + (-val / coef).toString();
    }
}
```
The algorithm used to solve this problem is based on processing the given equation as a string and having separate variables to track the coefficients for both 'x' and the values separately.

1. Initialize variables to track coefficients (`coef`), values (`val`), position (`left`), and operation (`operate`).
2. Iterate through the equation, updating position and operation when encountering a `="+` or `"="`. Otherwise, separate the terms involving x and the constant values, updating their coefficients accordingly.
3. After processing the equation, check if the coefficient for x is 0.
   - If yes, return "Infinite solutions" if the value is also 0; otherwise, return "No solution".
   - If no, divide the value by the coefficient and return the result as "x=#value".

Note that the function for each language has some differences in parsing the input string and managing the internal data as needed but follows the same strategy throughout.