# Guess Number Higher or Lower

- slug: guess-number-higher-or-lower
- difficulty: Easy

We are playing the Guess Game. The game is as follows:

I pick a number from `1` to `n`. You have to guess which number I picked.

Every time you guess wrong, I will tell you whether the number I picked is higher or lower than your guess.

You call a pre-defined API `int guess(int num)`, which returns three possible results:

*   `-1`: Your guess is higher than the number I picked (i.e. `num > pick`).
*   `1`: Your guess is lower than the number I picked (i.e. `num < pick`).
*   `0`: your guess is equal to the number I picked (i.e. `num == pick`).

Return _the number that I picked_.

**Example 1:**

**Input:** n = 10, pick = 6
**Output:** 6

**Example 2:**

**Input:** n = 1, pick = 1
**Output:** 1

**Example 3:**

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

**Constraints:**

*   `1 <= n <= 231 - 1`
*   `1 <= pick <= n`

## A solution in Java

```java
public int guessNumber(int n) {
    int low = 1, high = n;
    while (low <= high) {
        int mid = low + (high - low) / 2;
        int result = guess(mid);
        if (result == 0) {
            return mid;
        } else if (result < 0) {
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    return -1;
}
```
The algorithm uses binary search to find the correct number. The idea is to progressively eliminate half of the remaining options with each guess:

1. Initialize two pointers, `low` and `high`, to 1 and n.
2. While `low` is less than or equal to `high`:
   1. Calculate the middle value `mid` between `low` and `high`.
   2. Call the `guess` function with `mid` as the argument.
   3. If the `guess` function returns 0, the number has been found, so return `mid`.
   4. If the `guess` function returns a negative number, the target number is lower than `mid`, so update `high` to `mid - 1`.
   5. If the `guess` function returns a positive number, the target number is higher than `mid`, so update `low` to `mid + 1`.
3. If the search is unsuccessful, return -1.

The guess function is pre-defined and not shown in the code above.

## A solution in C++

```cpp
int guessNumber(int n) {
    int low = 1, high = n;
    while (low <= high) {
        int mid = low + (high - low) / 2;
        int result = guess(mid);
        if (result == 0) {
            return mid;
        } else if (result < 0) {
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    return -1;
}
```
The algorithm uses binary search to find the correct number. The idea is to progressively eliminate half of the remaining options with each guess:

1. Initialize two pointers, `low` and `high`, to 1 and n.
2. While `low` is less than or equal to `high`:
   1. Calculate the middle value `mid` between `low` and `high`.
   2. Call the `guess` function with `mid` as the argument.
   3. If the `guess` function returns 0, the number has been found, so return `mid`.
   4. If the `guess` function returns a negative number, the target number is lower than `mid`, so update `high` to `mid - 1`.
   5. If the `guess` function returns a positive number, the target number is higher than `mid`, so update `low` to `mid + 1`.
3. If the search is unsuccessful, return -1.

The guess function is pre-defined and not shown in the code above.

## A solution in Python

```python
def guessNumber(n):
    low, high = 1, n
    while low <= high:
        mid = low + (high - low) // 2
        result = guess(mid)
        if result == 0:
            return mid
        elif result < 0:
            high = mid - 1
        else:
            low = mid + 1
    return -1
```
The algorithm uses binary search to find the correct number. The idea is to progressively eliminate half of the remaining options with each guess:

1. Initialize two pointers, `low` and `high`, to 1 and n.
2. While `low` is less than or equal to `high`:
   1. Calculate the middle value `mid` between `low` and `high`.
   2. Call the `guess` function with `mid` as the argument.
   3. If the `guess` function returns 0, the number has been found, so return `mid`.
   4. If the `guess` function returns a negative number, the target number is lower than `mid`, so update `high` to `mid - 1`.
   5. If the `guess` function returns a positive number, the target number is higher than `mid`, so update `low` to `mid + 1`.
3. If the search is unsuccessful, return -1.

The guess function is pre-defined and not shown in the code above.

## A solution in Javascript

```javascript
function guessNumber(n) {
    let low = 1, high = n;
    while (low <= high) {
        let mid = Math.floor(low + (high - low) / 2);
        let result = guess(mid);
        if (result === 0) {
            return mid;
        } else if (result < 0) {
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    return -1;
}
```
The algorithm uses binary search to find the correct number. The idea is to progressively eliminate half of the remaining options with each guess:

1. Initialize two pointers, `low` and `high`, to 1 and n.
2. While `low` is less than or equal to `high`:
   1. Calculate the middle value `mid` between `low` and `high`.
   2. Call the `guess` function with `mid` as the argument.
   3. If the `guess` function returns 0, the number has been found, so return `mid`.
   4. If the `guess` function returns a negative number, the target number is lower than `mid`, so update `high` to `mid - 1`.
   5. If the `guess` function returns a positive number, the target number is higher than `mid`, so update `low` to `mid + 1`.
3. If the search is unsuccessful, return -1.

The guess function is pre-defined and not shown in the code above.


# Guess Number Higher or Lower II

- slug: guess-number-higher-or-lower-ii
- difficulty: Medium

We are playing the Guessing Game. The game will work as follows:

1.  I pick a number between `1` and `n`.
2.  You guess a number.
3.  If you guess the right number, **you win the game**.
4.  If you guess the wrong number, then I will tell you whether the number I picked is **higher or lower**, and you will continue guessing.
5.  Every time you guess a wrong number `x`, you will pay `x` dollars. If you run out of money, **you lose the game**.

Given a particular `n`, return _the minimum amount of money you need to **guarantee a win regardless of what number I pick**_.

**Example 1:**

**Input:** n = 10
**Output:** 16
**Explanation:** The winning strategy is as follows:
- The range is \[1,10\]. Guess 7.
    - If this is my number, your total is $0. Otherwise, you pay $7.
    - If my number is higher, the range is \[8,10\]. Guess 9.
        - If this is my number, your total is $7. Otherwise, you pay $9.
        - If my number is higher, it must be 10. Guess 10. Your total is $7 + $9 = $16.
        - If my number is lower, it must be 8. Guess 8. Your total is $7 + $9 = $16.
    - If my number is lower, the range is \[1,6\]. Guess 3.
        - If this is my number, your total is $7. Otherwise, you pay $3.
        - If my number is higher, the range is \[4,6\]. Guess 5.
            - If this is my number, your total is $7 + $3 = $10. Otherwise, you pay $5.
            - If my number is higher, it must be 6. Guess 6. Your total is $7 + $3 + $5 = $15.
            - If my number is lower, it must be 4. Guess 4. Your total is $7 + $3 + $5 = $15.
        - If my number is lower, the range is \[1,2\]. Guess 1.
            - If this is my number, your total is $7 + $3 = $10. Otherwise, you pay $1.
            - If my number is higher, it must be 2. Guess 2. Your total is $7 + $3 + $1 = $11.
The worst case in all these scenarios is that you pay $16. Hence, you only need $16 to guarantee a win.

**Example 2:**

**Input:** n = 1
**Output:** 0
**Explanation:** There is only one possible number, so you can guess 1 and not have to pay anything.

**Example 3:**

**Input:** n = 2
**Output:** 1
**Explanation:** There are two possible numbers, 1 and 2.
- Guess 1.
    - If this is my number, your total is $0. Otherwise, you pay $1.
    - If my number is higher, it must be 2. Guess 2. Your total is $1.
The worst case is that you pay $1.

**Constraints:**

*   `1 <= n <= 200`

## A solution in Java

```java
public int getMoneyAmount(int n) {
    int[][] dp = new int[n + 1][n + 1];
    for (int i = n - 1; i >= 1; i--) {
        for (int j = i + 1; j <= n; j++) {
            int min_cost = Integer.MAX_VALUE;
            for (int k = i; k < j; k++) {
                int cost = k + Math.max(dp[i][k - 1], dp[k + 1][j]);
                min_cost = Math.min(min_cost, cost);
            }
            dp[i][j] = min_cost;
        }
    }
    return dp[1][n];
}
```
The algorithm uses dynamic programming to find the minimum cost required to guarantee a win. We create a 2D array `dp` where `dp[i][j]` represents the minimum cost required to guess the correct number from numbers between i and j inclusive.

We fill in this array from the bottom right corner, and move towards the top left corner. For each value of `i` and `j`, we calculate the cost by guessing a number `k` between `i` and `j`. The cost is equal to `k + max(dp[i][k-1], dp[k+1][j])`, which means that we pay `k` and take the worst-case scenario, and we try to minimize this cost.

After filling the `dp` array, the minimum cost required to win the game when guessing numbers from 1 to `n` is stored in `dp[1][n]`.

## A solution in C++

```cpp
int getMoneyAmount(int n) {
    vector<vector<int>> dp(n + 1, vector<int>(n + 1, 0));
    for (int i = n - 1; i >= 1; i--) {
        for (int j = i + 1; j <= n; j++) {
            int min_cost = INT_MAX;
            for (int k = i; k < j; k++) {
                int cost = k + max(dp[i][k - 1], dp[k + 1][j]);
                min_cost = min(min_cost, cost);
            }
            dp[i][j] = min_cost;
        }
    }
    return dp[1][n];
}
```
The algorithm uses dynamic programming to find the minimum cost required to guarantee a win. We create a 2D array `dp` where `dp[i][j]` represents the minimum cost required to guess the correct number from numbers between i and j inclusive.

We fill in this array from the bottom right corner, and move towards the top left corner. For each value of `i` and `j`, we calculate the cost by guessing a number `k` between `i` and `j`. The cost is equal to `k + max(dp[i][k-1], dp[k+1][j])`, which means that we pay `k` and take the worst-case scenario, and we try to minimize this cost.

After filling the `dp` array, the minimum cost required to win the game when guessing numbers from 1 to `n` is stored in `dp[1][n]`.

## A solution in Python

```python
def getMoneyAmount(n: int) -> int:
    dp = [[0] * (n + 1) for _ in range(n + 1)]
    for i in range(n - 1, 0, -1):
        for j in range(i + 1, n + 1):
            min_cost = float("inf")
            for k in range(i, j):
                cost = k + max(dp[i][k - 1], dp[k + 1][j])
                min_cost = min(min_cost, cost)
            dp[i][j] = min_cost
    return dp[1][n]
```
The algorithm uses dynamic programming to find the minimum cost required to guarantee a win. We create a 2D array `dp` where `dp[i][j]` represents the minimum cost required to guess the correct number from numbers between i and j inclusive.

We fill in this array from the bottom right corner, and move towards the top left corner. For each value of `i` and `j`, we calculate the cost by guessing a number `k` between `i` and `j`. The cost is equal to `k + max(dp[i][k-1], dp[k+1][j])`, which means that we pay `k` and take the worst-case scenario, and we try to minimize this cost.

After filling the `dp` array, the minimum cost required to win the game when guessing numbers from 1 to `n` is stored in `dp[1][n]`.

## A solution in Javascript

```javascript
function getMoneyAmount(n) {
    const dp = Array.from(Array(n + 1), () => Array(n + 1).fill(0));
    for (let i = n - 1; i >= 1; i--) {
        for (let j = i + 1; j <= n; j++) {
            let min_cost = Infinity;
            for (let k = i; k < j; k++) {
                const cost = k + Math.max(dp[i][k - 1], dp[k + 1][j]);
                min_cost = Math.min(min_cost, cost);
            }
            dp[i][j] = min_cost;
        }
    }
    return dp[1][n];
}
```
The algorithm uses dynamic programming to find the minimum cost required to guarantee a win. We create a 2D array `dp` where `dp[i][j]` represents the minimum cost required to guess the correct number from numbers between i and j inclusive.

We fill in this array from the bottom right corner, and move towards the top left corner. For each value of `i` and `j`, we calculate the cost by guessing a number `k` between `i` and `j`. The cost is equal to `k + max(dp[i][k-1], dp[k+1][j])`, which means that we pay `k` and take the worst-case scenario, and we try to minimize this cost.

After filling the `dp` array, the minimum cost required to win the game when guessing numbers from 1 to `n` is stored in `dp[1][n]`.


# Wiggle Subsequence

- slug: wiggle-subsequence
- difficulty: Medium

A **wiggle sequence** is a sequence where the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with one element and a sequence with two non-equal elements are trivially wiggle sequences.

*   For example, `[1, 7, 4, 9, 2, 5]` is a **wiggle sequence** because the differences `(6, -3, 5, -7, 3)` alternate between positive and negative.
*   In contrast, `[1, 4, 7, 2, 5]` and `[1, 7, 4, 5, 5]` are not wiggle sequences. The first is not because its first two differences are positive, and the second is not because its last difference is zero.

A **subsequence** is obtained by deleting some elements (possibly zero) from the original sequence, leaving the remaining elements in their original order.

Given an integer array `nums`, return _the length of the longest **wiggle subsequence** of_ `nums`.

**Example 1:**

**Input:** nums = \[1,7,4,9,2,5\]
**Output:** 6
**Explanation:** The entire sequence is a wiggle sequence with differences (6, -3, 5, -7, 3).

**Example 2:**

**Input:** nums = \[1,17,5,10,13,15,10,5,16,8\]
**Output:** 7
**Explanation:** There are several subsequences that achieve this length.
One is \[1, 17, 10, 13, 10, 16, 8\] with differences (16, -7, 3, -3, 6, -8).

**Example 3:**

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

**Constraints:**

*   `1 <= nums.length <= 1000`
*   `0 <= nums[i] <= 1000`

**Follow up:** Could you solve this in `O(n)` time?

## A solution in Java

```java
public int wiggleMaxLength(int[] nums) {
    int len = nums.length;
    if (len < 2) return len;

    int up = 1, down = 1;
    for (int i = 1; i < len; ++i) {
        if (nums[i] > nums[i - 1])
            up = down + 1;
        else if (nums[i] < nums[i - 1])
            down = up + 1;
    }
    return Math.max(up, down);
}
```
The algorithm uses dynamic programming to find the longest wiggle subsequence in a given array or list of integers. The dynamic programming consists of two parts: the longest increasing subsequence (up) and the longest decreasing subsequence (down).

Initialize up and down to 1. Loop through the input array starting from index 1. For each element, if the current element is greater than the previous element, update `up` to be `down + 1`. If the current element is less than the previous element, update `down` to be `up + 1`.

After iterating through the entire array, return the greater value between `up` and `down`, which represents the length of the longest wiggle sequence.

The algorithm's time complexity is O(n) since it iterates through the input array once, and its space complexity is O(1) as it only uses a constant amount of additional memory.

## A solution in C++

```cpp
int wiggleMaxLength(vector<int>& nums) {
    int len = nums.size();
    if (len < 2) return len;

    int up = 1, down = 1;
    for (int i = 1; i < len; ++i) {
        if (nums[i] > nums[i - 1])
            up = down + 1;
        else if (nums[i] < nums[i - 1])
            down = up + 1;
    }
    return max(up, down);
}
```
The algorithm uses dynamic programming to find the longest wiggle subsequence in a given array or list of integers. The dynamic programming consists of two parts: the longest increasing subsequence (up) and the longest decreasing subsequence (down).

Initialize up and down to 1. Loop through the input array starting from index 1. For each element, if the current element is greater than the previous element, update `up` to be `down + 1`. If the current element is less than the previous element, update `down` to be `up + 1`.

After iterating through the entire array, return the greater value between `up` and `down`, which represents the length of the longest wiggle sequence.

The algorithm's time complexity is O(n) since it iterates through the input array once, and its space complexity is O(1) as it only uses a constant amount of additional memory.

## A solution in Python

```python
def wiggleMaxLength(nums):
    if len(nums) < 2:
        return len(nums)

    up, down = 1, 1
    for i in range(1, len(nums)):
        if nums[i] > nums[i - 1]:
            up = down + 1
        elif nums[i] < nums[i - 1]:
            down = up + 1
    return max(up, down)
```
The algorithm uses dynamic programming to find the longest wiggle subsequence in a given array or list of integers. The dynamic programming consists of two parts: the longest increasing subsequence (up) and the longest decreasing subsequence (down).

Initialize up and down to 1. Loop through the input array starting from index 1. For each element, if the current element is greater than the previous element, update `up` to be `down + 1`. If the current element is less than the previous element, update `down` to be `up + 1`.

After iterating through the entire array, return the greater value between `up` and `down`, which represents the length of the longest wiggle sequence.

The algorithm's time complexity is O(n) since it iterates through the input array once, and its space complexity is O(1) as it only uses a constant amount of additional memory.

## A solution in Javascript

```javascript
function wiggleMaxLength(nums) {
    let len = nums.length;
    if (len < 2) return len;

    let up = 1, down = 1;
    for (let i = 1; i < len; ++i) {
        if (nums[i] > nums[i - 1])
            up = down + 1;
        else if (nums[i] < nums[i - 1])
            down = up + 1;
    }
    return Math.max(up, down);
}
```
The algorithm uses dynamic programming to find the longest wiggle subsequence in a given array or list of integers. The dynamic programming consists of two parts: the longest increasing subsequence (up) and the longest decreasing subsequence (down).

Initialize up and down to 1. Loop through the input array starting from index 1. For each element, if the current element is greater than the previous element, update `up` to be `down + 1`. If the current element is less than the previous element, update `down` to be `up + 1`.

After iterating through the entire array, return the greater value between `up` and `down`, which represents the length of the longest wiggle sequence.

The algorithm's time complexity is O(n) since it iterates through the input array once, and its space complexity is O(1) as it only uses a constant amount of additional memory.


# Combination Sum IV

- slug: combination-sum-iv
- difficulty: Medium

Given an array of **distinct** integers `nums` and a target integer `target`, return _the number of possible combinations that add up to_ `target`.

The test cases are generated so that the answer can fit in a **32-bit** integer.

**Example 1:**

**Input:** nums = \[1,2,3\], target = 4
**Output:** 7
**Explanation:**
The possible combination ways are:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
Note that different sequences are counted as different combinations.

**Example 2:**

**Input:** nums = \[9\], target = 3
**Output:** 0

**Constraints:**

*   `1 <= nums.length <= 200`
*   `1 <= nums[i] <= 1000`
*   All the elements of `nums` are **unique**.
*   `1 <= target <= 1000`

**Follow up:** What if negative numbers are allowed in the given array? How does it change the problem? What limitation we need to add to the question to allow negative numbers?

## A solution in Java

```java
public int combinationSum(int[] nums, int target) {
    int[] dp = new int[target + 1];
    dp[0] = 1;

    for(int num : nums) {
        for(int i = num; i <= target; i++) {
            dp[i] += dp[i - num];
        }
    }

    return dp[target];
}
```
The basic idea is to use dynamic programming to solve this question. We create an array called "dp" with a length of target + 1, initializing all values to 0 except for dp[0], which is set to 1. This is because there is always one way to make a sum of 0.

We then start iterating through the given `nums` array. For each number in the `nums` array, we iterate from the `num` itself to the `target`. At each step, we add the number of ways we can make the previous sub-target (i.e., `dp[i - num]`) and store this updated count in the `dp[i]`.

Finally, after iterating through all numbers and sub-targets, the value at `dp[target]` will give the number of possible combinations that add up to `target`.

## A solution in C++

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

int combinationSum(vector<int>& nums, int target) {
    vector<int> dp(target + 1, 0);
    dp[0] = 1;

    for(int num : nums) {
        for(int i = num; i <= target; i++) {
            dp[i] += dp[i - num];
        }
    }

    return dp[target];
}
```
The basic idea is to use dynamic programming to solve this question. We create an array called "dp" with a length of target + 1, initializing all values to 0 except for dp[0], which is set to 1. This is because there is always one way to make a sum of 0.

We then start iterating through the given `nums` array. For each number in the `nums` array, we iterate from the `num` itself to the `target`. At each step, we add the number of ways we can make the previous sub-target (i.e., `dp[i - num]`) and store this updated count in the `dp[i]`.

Finally, after iterating through all numbers and sub-targets, the value at `dp[target]` will give the number of possible combinations that add up to `target`.

## A solution in Python

```python
def combination_sum(nums, target):
    dp = [0] * (target + 1)
    dp[0] = 1

    for num in nums:
        for i in range(num, target + 1):
            dp[i] += dp[i - num]

    return dp[target]
```
The basic idea is to use dynamic programming to solve this question. We create an array called "dp" with a length of target + 1, initializing all values to 0 except for dp[0], which is set to 1. This is because there is always one way to make a sum of 0.

We then start iterating through the given `nums` array. For each number in the `nums` array, we iterate from the `num` itself to the `target`. At each step, we add the number of ways we can make the previous sub-target (i.e., `dp[i - num]`) and store this updated count in the `dp[i]`.

Finally, after iterating through all numbers and sub-targets, the value at `dp[target]` will give the number of possible combinations that add up to `target`.

## A solution in Javascript

```javascript
function combinationSum(nums, target) {
    let dp = new Array(target + 1).fill(0);
    dp[0] = 1;

    for(let num of nums) {
        for(let i = num; i <= target; i++) {
            dp[i] += dp[i - num];
        }
    }

    return dp[target];
}
```
The basic idea is to use dynamic programming to solve this question. We create an array called "dp" with a length of target + 1, initializing all values to 0 except for dp[0], which is set to 1. This is because there is always one way to make a sum of 0.

We then start iterating through the given `nums` array. For each number in the `nums` array, we iterate from the `num` itself to the `target`. At each step, we add the number of ways we can make the previous sub-target (i.e., `dp[i - num]`) and store this updated count in the `dp[i]`.

Finally, after iterating through all numbers and sub-targets, the value at `dp[target]` will give the number of possible combinations that add up to `target`.


# Kth Smallest Element in a Sorted Matrix

- slug: kth-smallest-element-in-a-sorted-matrix
- difficulty: Medium

Given an `n x n` `matrix` where each of the rows and columns is sorted in ascending order, return _the_ `kth` _smallest element in the matrix_.

Note that it is the `kth` smallest element **in the sorted order**, not the `kth` **distinct** element.

You must find a solution with a memory complexity better than `O(n2)`.

**Example 1:**

**Input:** matrix = \[\[1,5,9\],\[10,11,13\],\[12,13,15\]\], k = 8
**Output:** 13
**Explanation:** The elements in the matrix are \[1,5,9,10,11,12,13,**13**,15\], and the 8th smallest number is 13

**Example 2:**

**Input:** matrix = \[\[-5\]\], k = 1
**Output:** -5

**Constraints:**

*   `n == matrix.length == matrix[i].length`
*   `1 <= n <= 300`
*   `-109 <= matrix[i][j] <= 109`
*   All the rows and columns of `matrix` are **guaranteed** to be sorted in **non-decreasing order**.
*   `1 <= k <= n2`

**Follow up:**

*   Could you solve the problem with a constant memory (i.e., `O(1)` memory complexity)?
*   Could you solve the problem in `O(n)` time complexity? The solution may be too advanced for an interview but you may find reading [this paper](http://www.cse.yorku.ca/~andy/pubs/X+Y.pdf) fun.

## A solution in Java

```java
import java.util.PriorityQueue;

public int kthSmallest(int[][] matrix, int k) {
    int n = matrix.length;
    PriorityQueue<int[]> minHeap = new PriorityQueue<>((a, b) -> a[0] - b[0]);

    for (int i = 0; i < n; i++) {
        minHeap.offer(new int[]{matrix[i][0], i, 0});
    }

    while (--k > 0) {
        int[] element = minHeap.poll();
        int row = element[1];
        int col = element[2];

        if (col + 1 < n) {
            minHeap.offer(new int[]{matrix[row][col + 1], row, col + 1});
        }
    }

    return minHeap.peek()[0];
}
```
1. Initialize a min-heap and insert the first element of each row (sorted rows) into the heap along with row and column index.
2. Pop the minimum element from the heap `k-1` times.
3. Each time an element is popped, insert the next element from the same row (if there is any) into the heap.
4. The kth smallest element is the top of the heap after the previous steps.

The time complexity is O(k * log(n)) as we have at most `n` elements in the heap, and the memory complexity is O(n) for the heap.

## A solution in C++

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

int kthSmallest(std::vector<std::vector<int>>& matrix, int k) {
    int n = matrix.size();
    std::priority_queue<std::pair<int, std::pair<int, int>>, std::vector<std::pair<int, std::pair<int, int>>>, std::greater<>> min_heap;

    for (int i = 0; i < n; ++i) {
        min_heap.emplace(matrix[i][0], std::make_pair(i, 0));
    }

    while (--k) {
        auto [val, pos] = min_heap.top();
        min_heap.pop();

        if (++pos.second < n) {
            min_heap.emplace(matrix[pos.first][pos.second], pos);
        }
    }

    return min_heap.top().first;
}
```
1. Initialize a min-heap and insert the first element of each row (sorted rows) into the heap along with row and column index.
2. Pop the minimum element from the heap `k-1` times.
3. Each time an element is popped, insert the next element from the same row (if there is any) into the heap.
4. The kth smallest element is the top of the heap after the previous steps.

The time complexity is O(k * log(n)) as we have at most `n` elements in the heap, and the memory complexity is O(n) for the heap.

## A solution in Python

```python
import heapq

def kthSmallest(matrix, k):
    n = len(matrix)
    min_heap = []

    for i in range(n):
        heapq.heappush(min_heap, (matrix[i][0], i, 0))

    while k > 1:
        val, row, col = heapq.heappop(min_heap)

        if col + 1 < n:
            heapq.heappush(min_heap, (matrix[row][col + 1], row, col + 1))

        k -= 1

    return min_heap[0][0]
```
1. Initialize a min-heap and insert the first element of each row (sorted rows) into the heap along with row and column index.
2. Pop the minimum element from the heap `k-1` times.
3. Each time an element is popped, insert the next element from the same row (if there is any) into the heap.
4. The kth smallest element is the top of the heap after the previous steps.

The time complexity is O(k * log(n)) as we have at most `n` elements in the heap, and the memory complexity is O(n) for the heap.

## A solution in Javascript

```javascript
function kthSmallest(matrix, k) {
    const n = matrix.length;
    const minHeap = [];

    for (let i = 0; i < n; i++) {
        minHeap.push({ value: matrix[i][0], row: i, col: 0 });
    }

    minHeap.sort((a, b) => a.value - b.value);

    while (--k) {
        const { value, row, col } = minHeap.shift();

        if (col + 1 < n) {
            const newVal = { value: matrix[row][col + 1], row: row, col: col + 1 };
            insertSorted(minHeap, newVal, (a, b) => a.value - b.value);
        }
    }

    return minHeap[0].value;
}

function insertSorted(arr, item, comparator) {
    const insertIndex = arr.findIndex((el) => comparator(el, item) > 0);

    if (insertIndex === -1) {
        arr.push(item);
    } else {
        arr.splice(insertIndex, 0, item);
    }
}
```
1. Initialize a min-heap and insert the first element of each row (sorted rows) into the heap along with row and column index.
2. Pop the minimum element from the heap `k-1` times.
3. Each time an element is popped, insert the next element from the same row (if there is any) into the heap.
4. The kth smallest element is the top of the heap after the previous steps.

The time complexity is O(k * log(n)) as we have at most `n` elements in the heap, and the memory complexity is O(n) for the heap.


# Design Phone Directory

- slug: design-phone-directory
- difficulty: Medium

Design a phone directory that initially has `maxNumbers` empty slots that can store numbers. The directory should store numbers, check if a certain slot is empty or not, and empty a given slot.

Implement the `PhoneDirectory` class:

*   `PhoneDirectory(int maxNumbers)` Initializes the phone directory with the number of available slots `maxNumbers`.
*   `int get()` Provides a number that is not assigned to anyone. Returns `-1` if no number is available.
*   `bool check(int number)` Returns `true` if the slot `number` is available and `false` otherwise.
*   `void release(int number)` Recycles or releases the slot `number`.

**Example 1:**

**Input**
\[ "PhoneDirectory ",  "get ",  "get ",  "check ",  "get ",  "check ",  "release ",  "check "\]
\[\[3\], \[\], \[\], \[2\], \[\], \[2\], \[2\], \[2\]\]
**Output**
\[null, 0, 1, true, 2, false, null, true\]

**Explanation**
PhoneDirectory phoneDirectory = new PhoneDirectory(3);
phoneDirectory.get();      // It can return any available phone number. Here we assume it returns 0.
phoneDirectory.get();      // Assume it returns 1.
phoneDirectory.check(2);   // The number 2 is available, so return true.
phoneDirectory.get();      // It returns 2, the only number that is left.
phoneDirectory.check(2);   // The number 2 is no longer available, so return false.
phoneDirectory.release(2); // Release number 2 back to the pool.
phoneDirectory.check(2);   // Number 2 is available again, return true.

**Constraints:**

*   `1 <= maxNumbers <= 104`
*   `0 <= number < maxNumbers`
*   At most `2 * 104` calls will be made to `get`, `check`, and `release`.

## A solution in Java

```java
import java.util.*;

class PhoneDirectory {
    boolean[] available;
    Queue<Integer> released;

    public PhoneDirectory(int maxNumbers) {
        available = new boolean[maxNumbers];
        Arrays.fill(available, true);
        released = new LinkedList<>();
    }

    public int get() {
        if (!released.isEmpty()) {
            int number = released.poll();
            available[number] = false;
            return number;
        }
        for (int i = 0; i < available.length; i++) {
            if (available[i]) {
                available[i] = false;
                return i;
            }
        }
        return -1;
    }

    public boolean check(int number) {
        return available[number];
    }

    public void release(int number) {
        if (!available[number]) {
            available[number] = true;
            released.offer(number);
        }
    }
}
```
The algorithm uses an array of booleans called `available` with a size of `maxNumbers` to represent each slot's availability (true means available, and false means occupied). Additionally, it uses a queue called `released` to store numbers that have been released recently.

- When the phone directory is initialized, all `available` slots are set to `true`, and the `released` queue is empty.
- When `get()` is called, it returns the first available number. If there is a recently released number in the `released` queue, it assigns this number to the caller and removes it from the queue. If there are no recently released numbers, it simply finds the first available number in the `available` array, sets it to `false`, and returns it. If no number is available, it returns `-1`.
- When `check()` is called, it returns the value of `available[number]` (true or false).
- When `release()` is called, it sets the value of `available[number]` to `true` and enqueues this number to the `released` queue if the slot is not already available.

This solution ensures that each operation (get, check, and release) has an O(maxNumbers) complexity in the worst case, meeting the requirement given the constraints.

## A solution in C++

```cpp
class PhoneDirectory {
    vector<bool> available;
    queue<int> released;
public:
    PhoneDirectory(int maxNumbers): available(maxNumbers, true) {}

    int get() {
        if(!released.empty()) {
            int number = released.front();
            released.pop();
            available[number] = false;
            return number;
        }
        for(int i = 0; i < available.size(); i++) {
            if(available[i]) {
                available[i] = false;
                return i;
            }
        }
        return -1;
    }

    bool check(int number) {
        return available[number];
    }

    void release(int number) {
        if(!available[number]) {
            available[number] = true;
            released.push(number);
        }
    }
};
```
The algorithm uses an array of booleans called `available` with a size of `maxNumbers` to represent each slot's availability (true means available, and false means occupied). Additionally, it uses a queue called `released` to store numbers that have been released recently.

- When the phone directory is initialized, all `available` slots are set to `true`, and the `released` queue is empty.
- When `get()` is called, it returns the first available number. If there is a recently released number in the `released` queue, it assigns this number to the caller and removes it from the queue. If there are no recently released numbers, it simply finds the first available number in the `available` array, sets it to `false`, and returns it. If no number is available, it returns `-1`.
- When `check()` is called, it returns the value of `available[number]` (true or false).
- When `release()` is called, it sets the value of `available[number]` to `true` and enqueues this number to the `released` queue if the slot is not already available.

This solution ensures that each operation (get, check, and release) has an O(maxNumbers) complexity in the worst case, meeting the requirement given the constraints.

## A solution in Python

```python
from collections import deque

class PhoneDirectory:
    def __init__(self, maxNumbers: int):
        self.available = [True] * maxNumbers
        self.released = deque()

    def get(self) -> int:
        if self.released:
            number = self.released.popleft()
            self.available[number] = False
            return number
        for i in range(len(self.available)):
            if self.available[i]:
                self.available[i] = False
                return i
        return -1

    def check(self, number: int) -> bool:
        return self.available[number]

    def release(self, number: int) -> None:
        if not self.available[number]:
            self.available[number] = True
            self.released.append(number)
```
The algorithm uses an array of booleans called `available` with a size of `maxNumbers` to represent each slot's availability (true means available, and false means occupied). Additionally, it uses a queue called `released` to store numbers that have been released recently.

- When the phone directory is initialized, all `available` slots are set to `true`, and the `released` queue is empty.
- When `get()` is called, it returns the first available number. If there is a recently released number in the `released` queue, it assigns this number to the caller and removes it from the queue. If there are no recently released numbers, it simply finds the first available number in the `available` array, sets it to `false`, and returns it. If no number is available, it returns `-1`.
- When `check()` is called, it returns the value of `available[number]` (true or false).
- When `release()` is called, it sets the value of `available[number]` to `true` and enqueues this number to the `released` queue if the slot is not already available.

This solution ensures that each operation (get, check, and release) has an O(maxNumbers) complexity in the worst case, meeting the requirement given the constraints.

## A solution in Javascript

```javascript
class PhoneDirectory {
    constructor(maxNumbers) {
        this.available = new Array(maxNumbers).fill(true);
        this.released = [];
    }

    get() {
        if (this.released.length > 0) {
            let number = this.released.shift();
            this.available[number] = false;
            return number;
        }
        for (let i = 0; i < this.available.length; i++) {
            if (this.available[i]) {
                this.available[i] = false;
                return i;
            }
        }
        return -1;
    }

    check(number) {
        return this.available[number];
    }

    release(number) {
        if (!this.available[number]) {
            this.available[number] = true;
            this.released.push(number);
        }
    }
}
```
The algorithm uses an array of booleans called `available` with a size of `maxNumbers` to represent each slot's availability (true means available, and false means occupied). Additionally, it uses a queue called `released` to store numbers that have been released recently.

- When the phone directory is initialized, all `available` slots are set to `true`, and the `released` queue is empty.
- When `get()` is called, it returns the first available number. If there is a recently released number in the `released` queue, it assigns this number to the caller and removes it from the queue. If there are no recently released numbers, it simply finds the first available number in the `available` array, sets it to `false`, and returns it. If no number is available, it returns `-1`.
- When `check()` is called, it returns the value of `available[number]` (true or false).
- When `release()` is called, it sets the value of `available[number]` to `true` and enqueues this number to the `released` queue if the slot is not already available.

This solution ensures that each operation (get, check, and release) has an O(maxNumbers) complexity in the worst case, meeting the requirement given the constraints.


# Insert Delete GetRandom O(1)

- slug: insert-delete-getrandom-o1
- difficulty: Medium

Implement the `RandomizedSet` class:

*   `RandomizedSet()` Initializes the `RandomizedSet` object.
*   `bool insert(int val)` Inserts an item `val` into the set if not present. Returns `true` if the item was not present, `false` otherwise.
*   `bool remove(int val)` Removes an item `val` from the set if present. Returns `true` if the item was present, `false` otherwise.
*   `int getRandom()` Returns a random element from the current set of elements (it's guaranteed that at least one element exists when this method is called). Each element must have the **same probability** of being returned.

You must implement the functions of the class such that each function works in **average** `O(1)` time complexity.

**Example 1:**

**Input**
\[ "RandomizedSet ",  "insert ",  "remove ",  "insert ",  "getRandom ",  "remove ",  "insert ",  "getRandom "\]
\[\[\], \[1\], \[2\], \[2\], \[\], \[1\], \[2\], \[\]\]
**Output**
\[null, true, false, true, 2, true, false, 2\]

**Explanation**
RandomizedSet randomizedSet = new RandomizedSet();
randomizedSet.insert(1); // Inserts 1 to the set. Returns true as 1 was inserted successfully.
randomizedSet.remove(2); // Returns false as 2 does not exist in the set.
randomizedSet.insert(2); // Inserts 2 to the set, returns true. Set now contains \[1,2\].
randomizedSet.getRandom(); // getRandom() should return either 1 or 2 randomly.
randomizedSet.remove(1); // Removes 1 from the set, returns true. Set now contains \[2\].
randomizedSet.insert(2); // 2 was already in the set, so return false.
randomizedSet.getRandom(); // Since 2 is the only number in the set, getRandom() will always return 2.

**Constraints:**

*   `-231 <= val <= 231 - 1`
*   At most `2 *` `105` calls will be made to `insert`, `remove`, and `getRandom`.
*   There will be **at least one** element in the data structure when `getRandom` is called.

## A solution in Java

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

public class RandomizedSet {
    private Map<Integer, Integer> indexMap;
    private List<Integer> nums;
    private Random rand;

    public RandomizedSet() {
        indexMap = new HashMap<>();
        nums = new ArrayList<>();
        rand = new Random();
    }

    public boolean insert(int val) {
        if (indexMap.containsKey(val)) return false;

        indexMap.put(val, nums.size());
        nums.add(val);
        return true;
    }

    public boolean remove(int val) {
        if (!indexMap.containsKey(val)) return false;

        int last = nums.get(nums.size() - 1);
        indexMap.put(last, indexMap.get(val));
        nums.set(indexMap.get(val), last);

        nums.remove(nums.size() - 1);
        indexMap.remove(val);
        return true;
    }

    public int getRandom() {
        return nums.get(rand.nextInt(nums.size()));
    }
}
```
The algorithm uses a combination of both data structures, HashMap and ArrayList (or unordered_map and vector in C++). The HashMap is used to store the values and their corresponding indices in the ArrayList.

1. When inserting a value, we first check if the value is already present in the HashMap. If it's not present, we add the value to the HashMap with its index in the ArrayList, and also add the value to the ArrayList.

2. When removing a value, we check if the value is present in the HashMap. If it's present, we swap the value to be removed with the last value in the ArrayList, update the HashMap with the new index of the last value, and remove the last value from the ArrayList. After that, we remove the value from the HashMap.

3. To get a random value, we use the random function to generate a random index within the ArrayList's range and return the value at that index.

By using this combination of data structures, we are able to achieve average O(1) time complexity for each of the functions.

## A solution in C++

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

class RandomizedSet {
    std::unordered_map<int, int> index_map;
    std::vector<int> nums;
public:
    bool insert(int val) {
        if (index_map.count(val)) return false;

        index_map[val] = nums.size();
        nums.push_back(val);
        return true;
    }

    bool remove(int val) {
        if (!index_map.count(val)) return false;

        int last = nums.back();
        index_map[last] = index_map[val];
        nums[index_map[val]] = last;

        nums.pop_back();
        index_map.erase(val);
        return true;
    }

    int getRandom() {
        return nums[rand() % nums.size()];
    }
};
```
The algorithm uses a combination of both data structures, HashMap and ArrayList (or unordered_map and vector in C++). The HashMap is used to store the values and their corresponding indices in the ArrayList.

1. When inserting a value, we first check if the value is already present in the HashMap. If it's not present, we add the value to the HashMap with its index in the ArrayList, and also add the value to the ArrayList.

2. When removing a value, we check if the value is present in the HashMap. If it's present, we swap the value to be removed with the last value in the ArrayList, update the HashMap with the new index of the last value, and remove the last value from the ArrayList. After that, we remove the value from the HashMap.

3. To get a random value, we use the random function to generate a random index within the ArrayList's range and return the value at that index.

By using this combination of data structures, we are able to achieve average O(1) time complexity for each of the functions.

## A solution in Python

```python
import random

class RandomizedSet:
    def __init__(self):
        self.index_map = {}
        self.nums = []

    def insert(self, val: int) -> bool:
        if val in self.index_map:
            return False

        self.index_map[val] = len(self.nums)
        self.nums.append(val)
        return True

    def remove(self, val: int) -> bool:
        if val not in self.index_map:
            return False

        last = self.nums[-1]
        self.index_map[last] = self.index_map[val]
        self.nums[self.index_map[val]] = last

        self.nums.pop()
        del self.index_map[val]
        return True

    def getRandom(self) -> int:
        return self.nums[random.randint(0, len(self.nums) - 1)]
```
The algorithm uses a combination of both data structures, HashMap and ArrayList (or unordered_map and vector in C++). The HashMap is used to store the values and their corresponding indices in the ArrayList.

1. When inserting a value, we first check if the value is already present in the HashMap. If it's not present, we add the value to the HashMap with its index in the ArrayList, and also add the value to the ArrayList.

2. When removing a value, we check if the value is present in the HashMap. If it's present, we swap the value to be removed with the last value in the ArrayList, update the HashMap with the new index of the last value, and remove the last value from the ArrayList. After that, we remove the value from the HashMap.

3. To get a random value, we use the random function to generate a random index within the ArrayList's range and return the value at that index.

By using this combination of data structures, we are able to achieve average O(1) time complexity for each of the functions.

## A solution in Javascript

```javascript
class RandomizedSet {
    constructor() {
        this.indexMap = new Map();
        this.nums = [];
    }

    insert(val) {
        if (this.indexMap.has(val)) return false;

        this.indexMap.set(val, this.nums.length);
        this.nums.push(val);
        return true;
    }

    remove(val) {
        if (!this.indexMap.has(val)) return false;

        const last = this.nums[this.nums.length - 1];
        this.indexMap.set(last, this.indexMap.get(val));
        this.nums[this.indexMap.get(val)] = last;

        this.nums.pop();
        this.indexMap.delete(val);
        return true;
    }

    getRandom() {
        return this.nums[Math.floor(Math.random() * this.nums.length)];
    }
}
```
The algorithm uses a combination of both data structures, HashMap and ArrayList (or unordered_map and vector in C++). The HashMap is used to store the values and their corresponding indices in the ArrayList.

1. When inserting a value, we first check if the value is already present in the HashMap. If it's not present, we add the value to the HashMap with its index in the ArrayList, and also add the value to the ArrayList.

2. When removing a value, we check if the value is present in the HashMap. If it's present, we swap the value to be removed with the last value in the ArrayList, update the HashMap with the new index of the last value, and remove the last value from the ArrayList. After that, we remove the value from the HashMap.

3. To get a random value, we use the random function to generate a random index within the ArrayList's range and return the value at that index.

By using this combination of data structures, we are able to achieve average O(1) time complexity for each of the functions.


# Insert Delete GetRandom O(1) - Duplicates allowed

- slug: insert-delete-getrandom-o1-duplicates-allowed
- difficulty: Hard

`RandomizedCollection` is a data structure that contains a collection of numbers, possibly duplicates (i.e., a multiset). It should support inserting and removing specific elements and also reporting a random element.

Implement the `RandomizedCollection` class:

*   `RandomizedCollection()` Initializes the empty `RandomizedCollection` object.
*   `bool insert(int val)` Inserts an item `val` into the multiset, even if the item is already present. Returns `true` if the item is not present, `false` otherwise.
*   `bool remove(int val)` Removes an item `val` from the multiset if present. Returns `true` if the item is present, `false` otherwise. Note that if `val` has multiple occurrences in the multiset, we only remove one of them.
*   `int getRandom()` Returns a random element from the current multiset of elements. The probability of each element being returned is **linearly related** to the number of the same values the multiset contains.

You must implement the functions of the class such that each function works on **average** `O(1)` time complexity.

**Note:** The test cases are generated such that `getRandom` will only be called if there is **at least one** item in the `RandomizedCollection`.

**Example 1:**

**Input**
\[ "RandomizedCollection ",  "insert ",  "insert ",  "insert ",  "getRandom ",  "remove ",  "getRandom "\]
\[\[\], \[1\], \[1\], \[2\], \[\], \[1\], \[\]\]
**Output**
\[null, true, false, true, 2, true, 1\]

**Explanation**
RandomizedCollection randomizedCollection = new RandomizedCollection();
randomizedCollection.insert(1);   // return true since the collection does not contain 1.
                                  // Inserts 1 into the collection.
randomizedCollection.insert(1);   // return false since the collection contains 1.
                                  // Inserts another 1 into the collection. Collection now contains \[1,1\].
randomizedCollection.insert(2);   // return true since the collection does not contain 2.
                                  // Inserts 2 into the collection. Collection now contains \[1,1,2\].
randomizedCollection.getRandom(); // getRandom should:
                                  // - return 1 with probability 2/3, or
                                  // - return 2 with probability 1/3.
randomizedCollection.remove(1);   // return true since the collection contains 1.
                                  // Removes 1 from the collection. Collection now contains \[1,2\].
randomizedCollection.getRandom(); // getRandom should return 1 or 2, both equally likely.

**Constraints:**

*   `-231 <= val <= 231 - 1`
*   At most `2 * 105` calls **in total** will be made to `insert`, `remove`, and `getRandom`.
*   There will be **at least one** element in the data structure when `getRandom` is called.

## A solution in Java

```java
import java.util.*;

class RandomizedCollection {
    Map<Integer, Set<Integer>> indices;
    List<Integer> nums;

    public RandomizedCollection() {
        indices = new HashMap<>();
        nums = new ArrayList<>();
    }

    public boolean insert(int val) {
        nums.add(val);
        indices.putIfAbsent(val, new HashSet<>());
        indices.get(val).add(nums.size() - 1);
        return indices.get(val).size() == 1;
    }

    public boolean remove(int val) {
        if (!indices.containsKey(val) || indices.get(val).isEmpty()) return false;
        int idx = indices.get(val).iterator().next();
        indices.get(val).remove(idx);

        if (idx < nums.size() - 1) {
            int last = nums.get(nums.size() - 1);
            nums.set(idx, last);
            indices.get(last).remove(nums.size() - 1);
            indices.get(last).add(idx);
        }
        nums.remove(nums.size() - 1);
        return true;
    }

    public int getRandom() {
        int index = (int) (Math.random() * nums.size());
        return nums.get(index);
    }
}
```
The data structure uses a HashMap (or an unordered_map in C++, or a Map in JavaScript) called 'indices' to store the indices of each number in the collection. It also uses a List (or a vector in C++, or an Array in JavaScript) called 'nums' to store the numbers in the order they are inserted.

The 'insert' function adds the element to the nums list and updates the indices in the HashMap. If the size of the index set is equal to 1, then the value is new. The 'remove' function removes an element from the nums list and updates the indices in the HashMap accordingly. To keep the time complexity O(1), we swap the element to remove with the last element in the list, and then remove the last element from the list.

Finally, the 'getRandom' function generates a random index in the range of the size of the nums list and returns the element at that index. Since each function takes constant time on average, the overall time complexity is O(1).

## A solution in C++

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

class RandomizedCollection {
public:
    unordered_map<int, unordered_set<int>> indices;
    vector<int> nums;

    bool insert(int val) {
        nums.push_back(val);
        indices[val].insert(nums.size() - 1);
        return indices[val].size() == 1;
    }

    bool remove(int val) {
        if (!indices[val].size()) return false;
        int idx = *indices[val].begin();
        indices[val].erase(idx);
        if (idx < nums.size() - 1) {
            int last = nums.back();
            nums[idx] = last;
            indices[last].erase(nums.size() - 1);
            indices[last].insert(idx);
        }
        nums.pop_back();
        return true;
    }

    int getRandom() {
        return nums[rand() % nums.size()];
    }
};
```
The data structure uses a HashMap (or an unordered_map in C++, or a Map in JavaScript) called 'indices' to store the indices of each number in the collection. It also uses a List (or a vector in C++, or an Array in JavaScript) called 'nums' to store the numbers in the order they are inserted.

The 'insert' function adds the element to the nums list and updates the indices in the HashMap. If the size of the index set is equal to 1, then the value is new. The 'remove' function removes an element from the nums list and updates the indices in the HashMap accordingly. To keep the time complexity O(1), we swap the element to remove with the last element in the list, and then remove the last element from the list.

Finally, the 'getRandom' function generates a random index in the range of the size of the nums list and returns the element at that index. Since each function takes constant time on average, the overall time complexity is O(1).

## A solution in Python

```python
import random
from collections import defaultdict

class RandomizedCollection:
    def __init__(self):
        self.indices = defaultdict(set)
        self.nums = []

    def insert(self, val):
        self.nums.append(val)
        self.indices[val].add(len(self.nums) - 1)
        return len(self.indices[val]) == 1

    def remove(self, val):
        if not self.indices[val]:
            return False

        idx = self.indices[val].pop()
        if idx < len(self.nums) - 1:
            last = self.nums[-1]
            self.nums[idx] = last
            self.indices[last].remove(len(self.nums) - 1)
            self.indices[last].add(idx)
        self.nums.pop()
        return True

    def getRandom(self):
        return self.nums[random.randint(0, len(self.nums) - 1)]
```
The data structure uses a HashMap (or an unordered_map in C++, or a Map in JavaScript) called 'indices' to store the indices of each number in the collection. It also uses a List (or a vector in C++, or an Array in JavaScript) called 'nums' to store the numbers in the order they are inserted.

The 'insert' function adds the element to the nums list and updates the indices in the HashMap. If the size of the index set is equal to 1, then the value is new. The 'remove' function removes an element from the nums list and updates the indices in the HashMap accordingly. To keep the time complexity O(1), we swap the element to remove with the last element in the list, and then remove the last element from the list.

Finally, the 'getRandom' function generates a random index in the range of the size of the nums list and returns the element at that index. Since each function takes constant time on average, the overall time complexity is O(1).

## A solution in Javascript

```javascript
class RandomizedCollection {
    constructor() {
        this.indices = new Map();
        this.nums = [];
    }

    insert(val) {
        this.nums.push(val);
        if (!this.indices.has(val)) this.indices.set(val, new Set());
        this.indices.get(val).add(this.nums.length - 1);
        return this.indices.get(val).size === 1;
    }

    remove(val) {
        if (!this.indices.has(val) || this.indices.get(val).size === 0) return false;
        const idx = this.indices.get(val).values().next().value;
        this.indices.get(val).delete(idx);

        if (idx < this.nums.length - 1) {
            const last = this.nums[this.nums.length - 1];
            this.nums[idx] = last;
            this.indices.get(last).delete(this.nums.length - 1);
            this.indices.get(last).add(idx);
        }
        this.nums.pop();
        return true;
    }

    getRandom() {
        const index = Math.floor(Math.random() * this.nums.length);
        return this.nums[index];
    }
}
```
The data structure uses a HashMap (or an unordered_map in C++, or a Map in JavaScript) called 'indices' to store the indices of each number in the collection. It also uses a List (or a vector in C++, or an Array in JavaScript) called 'nums' to store the numbers in the order they are inserted.

The 'insert' function adds the element to the nums list and updates the indices in the HashMap. If the size of the index set is equal to 1, then the value is new. The 'remove' function removes an element from the nums list and updates the indices in the HashMap accordingly. To keep the time complexity O(1), we swap the element to remove with the last element in the list, and then remove the last element from the list.

Finally, the 'getRandom' function generates a random index in the range of the size of the nums list and returns the element at that index. Since each function takes constant time on average, the overall time complexity is O(1).


# Linked List Random Node

- slug: linked-list-random-node
- difficulty: Medium

Given a singly linked list, return a random node's value from the linked list. Each node must have the **same probability** of being chosen.

Implement the `Solution` class:

*   `Solution(ListNode head)` Initializes the object with the head of the singly-linked list `head`.
*   `int getRandom()` Chooses a node randomly from the list and returns its value. All the nodes of the list should be equally likely to be chosen.

**Example 1:**

**Input**
\[ "Solution ",  "getRandom ",  "getRandom ",  "getRandom ",  "getRandom ",  "getRandom "\]
\[\[\[1, 2, 3\]\], \[\], \[\], \[\], \[\], \[\]\]
**Output**
\[null, 1, 3, 2, 2, 3\]

**Explanation**
Solution solution = new Solution(\[1, 2, 3\]);
solution.getRandom(); // return 1
solution.getRandom(); // return 3
solution.getRandom(); // return 2
solution.getRandom(); // return 2
solution.getRandom(); // return 3
// getRandom() should return either 1, 2, or 3 randomly. Each element should have equal probability of returning.

**Constraints:**

*   The number of nodes in the linked list will be in the range `[1, 104]`.
*   `-104 <= Node.val <= 104`
*   At most `104` calls will be made to `getRandom`.

**Follow up:**

*   What if the linked list is extremely large and its length is unknown to you?
*   Could you solve this efficiently without using extra space?

## A solution in Java

```java
import java.util.Random;

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}

public class Solution {
    ListNode head;
    Random random;

    public Solution(ListNode head) {
        this.head = head;
        random = new Random();
    }

    public int getRandom() {
        ListNode current = head;
        int result = current.val, i;
        for (i = 1; current != null; i++) {
            if (random.nextInt(i) == 0) {
                result = current.val;
            }
            current = current.next;
        }
        return result;
    }
}
```
The function initializes the head of the linked list and a random number generator (in the case of Java). The `getRandom()` function iterates through the list, starting with the head node. It uses the reservoir sampling algorithm of size 1 for obtaining a random value at each step. This ensures each node has an equal probability of being chosen. In this algorithm, a random integer `i` is generated, and if `i` is 0, the current node's value is selected as the result.

## A solution in C++

```cpp
#include <cstdlib>
#include <ctime>

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
    ListNode* head;

    Solution(ListNode* _head) {
        head = _head;
        srand(time(0));
    }

    int getRandom() {
        int result;
        ListNode* current = head;
        for (int i = 1; current; ++i) {
            if (rand() % i == 0) {
                result = current->val;
            }
            current = current->next;
        }
        return result;
    }
};
```
The function initializes the head of the linked list and a random number generator (in the case of Java). The `getRandom()` function iterates through the list, starting with the head node. It uses the reservoir sampling algorithm of size 1 for obtaining a random value at each step. This ensures each node has an equal probability of being chosen. In this algorithm, a random integer `i` is generated, and if `i` is 0, the current node's value is selected as the result.

## A solution in Python

```python
import random

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def __init__(self, head: ListNode):
        self.head = head

    def getRandom(self) -> int:
        current, result = self.head, 0
        for i, node in enumerate(self.iterate_nodes(current)):
            if random.randint(0, i) == 0:
                result = node.val
        return result

    def iterate_nodes(self, current):
        while current:
            yield current
            current = current.next
```
The function initializes the head of the linked list and a random number generator (in the case of Java). The `getRandom()` function iterates through the list, starting with the head node. It uses the reservoir sampling algorithm of size 1 for obtaining a random value at each step. This ensures each node has an equal probability of being chosen. In this algorithm, a random integer `i` is generated, and if `i` is 0, the current node's value is selected as the result.

## A solution in Javascript

```javascript
class ListNode {
    constructor(val, next = null) {
        this.val = val;
        this.next = next;
    }
}

class Solution {
    constructor(head) {
        this.head = head;
    }

    getRandom() {
        let current = this.head;
        let result = current.val;
        for (let i = 1; current !== null; i++) {
            if (Math.floor(Math.random() * i) === 0) {
                result = current.val;
            }
            current = current.next;
        }
        return result;
    }
}
```
The function initializes the head of the linked list and a random number generator (in the case of Java). The `getRandom()` function iterates through the list, starting with the head node. It uses the reservoir sampling algorithm of size 1 for obtaining a random value at each step. This ensures each node has an equal probability of being chosen. In this algorithm, a random integer `i` is generated, and if `i` is 0, the current node's value is selected as the result.


# Ransom Note

- slug: ransom-note
- difficulty: Easy

Given two strings `ransomNote` and `magazine`, return `true` _if_ `ransomNote` _can be constructed by using the letters from_ `magazine` _and_ `false` _otherwise_.

Each letter in `magazine` can only be used once in `ransomNote`.

**Example 1:**

**Input:** ransomNote = "a", magazine = "b"
**Output:** false

**Example 2:**

**Input:** ransomNote = "aa", magazine = "ab"
**Output:** false

**Example 3:**

**Input:** ransomNote = "aa", magazine = "aab"
**Output:** true

**Constraints:**

*   `1 <= ransomNote.length, magazine.length <= 105`
*   `ransomNote` and `magazine` consist of lowercase English letters.

## A solution in Java

```java
import java.util.HashMap;

public boolean canConstruct(String ransomNote, String magazine) {
    HashMap<Character, Integer> letterCount = new HashMap<>();

    for (char c : magazine.toCharArray()) {
        letterCount.put(c, letterCount.getOrDefault(c, 0) + 1);
    }

    for (char c : ransomNote.toCharArray()) {
        if (!letterCount.containsKey(c) || letterCount.get(c) == 0) {
            return false;
        }
        letterCount.put(c, letterCount.get(c) - 1);
    }

    return true;
}
```
The algorithm works as follows:
1. Create a hash map called `letterCount`, which holds the count of each character in the `magazine` string.
2. Iterate over the characters in `ransomNote`. For each character:
   a. If the character is not in `letterCount` or its count is 0, return `false`, as the required letter is not available in `magazine`.
   b. Decrease the count of the character in `letterCount` by 1.
3. Once the iteration is done, if the entire `ransomNote` string is processed without any issue, return `true`.

This algorithm checks if the `ransomNote` can be made from the available characters in the `magazine` by using a single pass through each string and maintaining the count of characters in a hash map.

## A solution in C++

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

bool canConstruct(std::string ransomNote, std::string magazine) {
    std::unordered_map<char, int> letterCount;
    for (char c : magazine) {
        letterCount[c]++;
    }

    for (char c : ransomNote) {
        if (letterCount[c] == 0) {
            return false;
        }
        letterCount[c]--;
    }

    return true;
}
```
The algorithm works as follows:
1. Create a hash map called `letterCount`, which holds the count of each character in the `magazine` string.
2. Iterate over the characters in `ransomNote`. For each character:
   a. If the character is not in `letterCount` or its count is 0, return `false`, as the required letter is not available in `magazine`.
   b. Decrease the count of the character in `letterCount` by 1.
3. Once the iteration is done, if the entire `ransomNote` string is processed without any issue, return `true`.

This algorithm checks if the `ransomNote` can be made from the available characters in the `magazine` by using a single pass through each string and maintaining the count of characters in a hash map.

## A solution in Python

```python
def can_construct(ransom_note, magazine):
    letter_count = {}

    for c in magazine:
        letter_count[c] = letter_count.get(c, 0) + 1

    for c in ransom_note:
        if c not in letter_count or letter_count[c] == 0:
            return False
        letter_count[c] -= 1

    return True
```
The algorithm works as follows:
1. Create a hash map called `letterCount`, which holds the count of each character in the `magazine` string.
2. Iterate over the characters in `ransomNote`. For each character:
   a. If the character is not in `letterCount` or its count is 0, return `false`, as the required letter is not available in `magazine`.
   b. Decrease the count of the character in `letterCount` by 1.
3. Once the iteration is done, if the entire `ransomNote` string is processed without any issue, return `true`.

This algorithm checks if the `ransomNote` can be made from the available characters in the `magazine` by using a single pass through each string and maintaining the count of characters in a hash map.

## A solution in Javascript

```javascript
function canConstruct(ransomNote, magazine) {
    let letterCount = new Map();

    for (const c of magazine) {
        letterCount.set(c, (letterCount.get(c) || 0) + 1);
    }

    for (const c of ransomNote) {
        if (!letterCount.has(c) || letterCount.get(c) === 0) {
            return false;
        }
        letterCount.set(c, letterCount.get(c) - 1);
    }

    return true;
}
```
The algorithm works as follows:
1. Create a hash map called `letterCount`, which holds the count of each character in the `magazine` string.
2. Iterate over the characters in `ransomNote`. For each character:
   a. If the character is not in `letterCount` or its count is 0, return `false`, as the required letter is not available in `magazine`.
   b. Decrease the count of the character in `letterCount` by 1.
3. Once the iteration is done, if the entire `ransomNote` string is processed without any issue, return `true`.

This algorithm checks if the `ransomNote` can be made from the available characters in the `magazine` by using a single pass through each string and maintaining the count of characters in a hash map.


# Shuffle an Array

- slug: shuffle-an-array
- difficulty: Medium

Given an integer array `nums`, design an algorithm to randomly shuffle the array. All permutations of the array should be **equally likely** as a result of the shuffling.

Implement the `Solution` class:

*   `Solution(int[] nums)` Initializes the object with the integer array `nums`.
*   `int[] reset()` Resets the array to its original configuration and returns it.
*   `int[] shuffle()` Returns a random shuffling of the array.

**Example 1:**

**Input**
\[ "Solution ",  "shuffle ",  "reset ",  "shuffle "\]
\[\[\[1, 2, 3\]\], \[\], \[\], \[\]\]
**Output**
\[null, \[3, 1, 2\], \[1, 2, 3\], \[1, 3, 2\]\]

**Explanation**
Solution solution = new Solution(\[1, 2, 3\]);
solution.shuffle();    // Shuffle the array \[1,2,3\] and return its result.
                       // Any permutation of \[1,2,3\] must be equally likely to be returned.
                       // Example: return \[3, 1, 2\]
solution.reset();      // Resets the array back to its original configuration \[1,2,3\]. Return \[1, 2, 3\]
solution.shuffle();    // Returns the random shuffling of array \[1,2,3\]. Example: return \[1, 3, 2\]

**Constraints:**

*   `1 <= nums.length <= 50`
*   `-106 <= nums[i] <= 106`
*   All the elements of `nums` are **unique**.
*   At most `104` calls **in total** will be made to `reset` and `shuffle`.

## A solution in Java

```java
import java.util.Random;
import java.util.Arrays;

class Solution {
    private int[] original;
    private Random rand;

    public Solution(int[] nums) {
        original = nums;
        rand = new Random();
    }

    public int[] reset() {
        return original;
    }

    public int[] shuffle() {
        int[] shuffled = Arrays.copyOf(original, original.length);
        for (int i = shuffled.length - 1; i > 0; i--) {
            int j = rand.nextInt(i + 1);
            int temp = shuffled[i];
            shuffled[i] = shuffled[j];
            shuffled[j] = temp;
        }
        return shuffled;
    }
}
```
The algorithm uses the Fisher-Yates shuffle algorithm (also known as the Knuth shuffle) to achieve a uniformly random shuffle of the input array. It starts from the last element of the array and iterates to the first element. For each element, it chooses a random index (j) from 0 to i (inclusive), and then swaps the element at index i with the element at index j. This ensures that all elements will be shuffled uniformly.

This solution makes use of classes and methods in each language. The constructor initializes the original array which holds the input array. The reset() method simply returns the original array. The shuffle() method performs the Fisher-Yates shuffle and returns the shuffled array. Note that in each shuffle() method, we create a copy of the original array and operate on that copy to avoid modifying the original array.

## A solution in C++

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

class Solution {
public:
    Solution(std::vector<int>& nums) {
        original = nums;
        srand(time(0));
    }

    std::vector<int> reset() {
        return original;
    }

    std::vector<int> shuffle() {
        std::vector<int> shuffled = original;
        for (int i = shuffled.size() - 1; i > 0; i--) {
            int j = rand() % (i + 1);
            std::swap(shuffled[i], shuffled[j]);
        }
        return shuffled;
    }
private:
    std::vector<int> original;
};
```
The algorithm uses the Fisher-Yates shuffle algorithm (also known as the Knuth shuffle) to achieve a uniformly random shuffle of the input array. It starts from the last element of the array and iterates to the first element. For each element, it chooses a random index (j) from 0 to i (inclusive), and then swaps the element at index i with the element at index j. This ensures that all elements will be shuffled uniformly.

This solution makes use of classes and methods in each language. The constructor initializes the original array which holds the input array. The reset() method simply returns the original array. The shuffle() method performs the Fisher-Yates shuffle and returns the shuffled array. Note that in each shuffle() method, we create a copy of the original array and operate on that copy to avoid modifying the original array.

## A solution in Python

```python
import random

class Solution:
    def __init__(self, nums):
        self.original = nums

    def reset(self):
        return self.original

    def shuffle(self):
        shuffled = self.original[:]
        for i in range(len(shuffled) - 1, 0, -1):
            j = random.randint(0, i)
            shuffled[i], shuffled[j] = shuffled[j], shuffled[i]
        return shuffled
```
The algorithm uses the Fisher-Yates shuffle algorithm (also known as the Knuth shuffle) to achieve a uniformly random shuffle of the input array. It starts from the last element of the array and iterates to the first element. For each element, it chooses a random index (j) from 0 to i (inclusive), and then swaps the element at index i with the element at index j. This ensures that all elements will be shuffled uniformly.

This solution makes use of classes and methods in each language. The constructor initializes the original array which holds the input array. The reset() method simply returns the original array. The shuffle() method performs the Fisher-Yates shuffle and returns the shuffled array. Note that in each shuffle() method, we create a copy of the original array and operate on that copy to avoid modifying the original array.

## A solution in Javascript

```javascript
class Solution {
    constructor(nums) {
        this.original = nums;
    }

    reset() {
        return this.original;
    }

    shuffle() {
        let shuffled = [...this.original];
        for (let i = shuffled.length - 1; i > 0; i--) {
            let j = Math.floor(Math.random() * (i + 1));
            [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
        }
        return shuffled;
    }
}
```
The algorithm uses the Fisher-Yates shuffle algorithm (also known as the Knuth shuffle) to achieve a uniformly random shuffle of the input array. It starts from the last element of the array and iterates to the first element. For each element, it chooses a random index (j) from 0 to i (inclusive), and then swaps the element at index i with the element at index j. This ensures that all elements will be shuffled uniformly.

This solution makes use of classes and methods in each language. The constructor initializes the original array which holds the input array. The reset() method simply returns the original array. The shuffle() method performs the Fisher-Yates shuffle and returns the shuffled array. Note that in each shuffle() method, we create a copy of the original array and operate on that copy to avoid modifying the original array.


# Mini Parser

- slug: mini-parser
- difficulty: Medium

Given a string s represents the serialization of a nested list, implement a parser to deserialize it and return _the deserialized_ `NestedInteger`.

Each element is either an integer or a list whose elements may also be integers or other lists.

**Example 1:**

**Input:** s =  "324 "
**Output:** 324
**Explanation:** You should return a NestedInteger object which contains a single integer 324.

**Example 2:**

**Input:** s =  "\[123,\[456,\[789\]\]\] "
**Output:** \[123,\[456,\[789\]\]\]
**Explanation:** Return a NestedInteger object containing a nested list with 2 elements:
1. An integer containing value 123.
2. A nested list containing two elements:
    i.  An integer containing value 456.
    ii. A nested list with one element:
         a. An integer containing value 789

**Constraints:**

*   `1 <= s.length <= 5 * 104`
*   `s` consists of digits, square brackets `"[] "`, negative sign `'-'`, and commas `','`.
*   `s` is the serialization of valid `NestedInteger`.
*   All the values in the input are in the range `[-106, 106]`.

## A solution in Java

```java
import java.util.*;

class NestedInteger {
    NestedInteger() {}
    NestedInteger(int value) {}
    void add(NestedInteger ni) {}
}

public class Solution {
    public NestedInteger deserialize(String s) {
        if (s.charAt(0) != '[') {
            return new NestedInteger(Integer.parseInt(s));
        }

        Stack<NestedInteger> stack = new Stack<>();
        NestedInteger curr = null;
        int start = 0;

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == '[') {
                if (curr != null) {
                    stack.push(curr);
                }
                curr = new NestedInteger();
                start = i + 1;
            } else if (c == ',' || c == ']') {
                if (i > start) {
                    curr.add(new NestedInteger(Integer.parseInt(s.substring(start, i))));
                }
                start = i + 1;

                if (c == ']' && !stack.isEmpty()) {
                    NestedInteger pop = stack.pop();
                    pop.add(curr);
                    curr = pop;
                }
            }
        }
        return curr;
    }
}
```
The algorithm is based on using a stack to maintain the hierarchy of the NestedInteger objects:

1. If the input string does not start with '[', it means the NestedInteger is an integer. Parse it directly and return the NestedInteger object.
2. If the input string starts with '[', it means the NestedInteger is a list. Initialize the stack, curr, and start variables.
3. Iterate through the string, one character at a time.
    a. If the current character is '[', push the current NestedInteger object onto the stack (if it exists), and create a new NestedInteger object.
    b. If the current character is ',' or ']', add the NestedInteger object formed by the sub-string between the start and the current index (if the sub-string is not empty) to the curr NestedInteger object. Update the start index to the next character.
    c. If the current character is ']' and the stack is not empty, pop the topmost NestedInteger from the stack, add the curr NestedInteger to it, and update the curr NestedInteger to the popped NestedInteger.
4. Once the iteration is complete, the curr NestedInteger contains the deserialized NestedInteger. Return it.

This algorithm works for all languages by converting the string into language-specific data structures (e.g., stringstream in C++ and istringstream in Python). The rest of the implementation remains the same across all languages.

## A solution in C++

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

class NestedInteger {
public:
    NestedInteger() {}
    NestedInteger(int value) {}
    void add(const NestedInteger& ni) {}
};

NestedInteger deserialize(string s);

NestedInteger deserializeHelper(istringstream& ss) {
    int num;
    if (ss >> num)
        return NestedInteger(num);

    ss.clear();
    ss.get();
    NestedInteger list;
    while (ss.peek() != ']') {
        list.add(deserializeHelper(ss));
        if (ss.peek() == ',')
            ss.get();
    }
    ss.get();
    return list;
}

NestedInteger deserialize(string s) {
    istringstream ss(s);
    return deserializeHelper(ss);
}
```
The algorithm is based on using a stack to maintain the hierarchy of the NestedInteger objects:

1. If the input string does not start with '[', it means the NestedInteger is an integer. Parse it directly and return the NestedInteger object.
2. If the input string starts with '[', it means the NestedInteger is a list. Initialize the stack, curr, and start variables.
3. Iterate through the string, one character at a time.
    a. If the current character is '[', push the current NestedInteger object onto the stack (if it exists), and create a new NestedInteger object.
    b. If the current character is ',' or ']', add the NestedInteger object formed by the sub-string between the start and the current index (if the sub-string is not empty) to the curr NestedInteger object. Update the start index to the next character.
    c. If the current character is ']' and the stack is not empty, pop the topmost NestedInteger from the stack, add the curr NestedInteger to it, and update the curr NestedInteger to the popped NestedInteger.
4. Once the iteration is complete, the curr NestedInteger contains the deserialized NestedInteger. Return it.

This algorithm works for all languages by converting the string into language-specific data structures (e.g., stringstream in C++ and istringstream in Python). The rest of the implementation remains the same across all languages.

## A solution in Python

```python
class NestedInteger:
    def __init__(self, value=None):
        pass

    def add(self, ni):
        pass

def deserialize(s: str) -> NestedInteger:
    if s[0] != '[':
        return NestedInteger(int(s))

    stack = []
    curr, start = None, 0

    for i, c in enumerate(s):
        if c == '[':
            if curr:
                stack.append(curr)
            curr = NestedInteger()
            start = i + 1
        elif c == ',' or c == ']':
            if i > start:
                curr.add(NestedInteger(int(s[start:i])))
            start = i + 1

            if c == ']' and stack:
                popped = stack.pop()
                popped.add(curr)
                curr = popped

    return curr
```
The algorithm is based on using a stack to maintain the hierarchy of the NestedInteger objects:

1. If the input string does not start with '[', it means the NestedInteger is an integer. Parse it directly and return the NestedInteger object.
2. If the input string starts with '[', it means the NestedInteger is a list. Initialize the stack, curr, and start variables.
3. Iterate through the string, one character at a time.
    a. If the current character is '[', push the current NestedInteger object onto the stack (if it exists), and create a new NestedInteger object.
    b. If the current character is ',' or ']', add the NestedInteger object formed by the sub-string between the start and the current index (if the sub-string is not empty) to the curr NestedInteger object. Update the start index to the next character.
    c. If the current character is ']' and the stack is not empty, pop the topmost NestedInteger from the stack, add the curr NestedInteger to it, and update the curr NestedInteger to the popped NestedInteger.
4. Once the iteration is complete, the curr NestedInteger contains the deserialized NestedInteger. Return it.

This algorithm works for all languages by converting the string into language-specific data structures (e.g., stringstream in C++ and istringstream in Python). The rest of the implementation remains the same across all languages.

## A solution in Javascript

```javascript
class NestedInteger {
    constructor(value) {
        this.value = value;
        this.list = [];
    }

    add(ni) {
        this.list.push(ni);
    }
}

function deserialize(s) {
    if (s[0] !== '[') {
        return new NestedInteger(parseInt(s));
    }

    let stack = [];
    let curr = null;
    let start = 0;

    for (let i = 0; i < s.length; i++) {
        let c = s[i];
        if (c === '[') {
            if (curr !== null) {
                stack.push(curr);
            }
            curr = new NestedInteger();
            start = i + 1;
        } else if (c === ',' || c === ']') {
            if (i > start) {
                curr.add(new NestedInteger(parseInt(s.substring(start, i))));
            }
            start = i + 1;

            if (c === ']' && stack.length > 0) {
                let popped = stack.pop();
                popped.add(curr);
                curr = popped;
            }
        }
    }
    return curr;
}
```
The algorithm is based on using a stack to maintain the hierarchy of the NestedInteger objects:

1. If the input string does not start with '[', it means the NestedInteger is an integer. Parse it directly and return the NestedInteger object.
2. If the input string starts with '[', it means the NestedInteger is a list. Initialize the stack, curr, and start variables.
3. Iterate through the string, one character at a time.
    a. If the current character is '[', push the current NestedInteger object onto the stack (if it exists), and create a new NestedInteger object.
    b. If the current character is ',' or ']', add the NestedInteger object formed by the sub-string between the start and the current index (if the sub-string is not empty) to the curr NestedInteger object. Update the start index to the next character.
    c. If the current character is ']' and the stack is not empty, pop the topmost NestedInteger from the stack, add the curr NestedInteger to it, and update the curr NestedInteger to the popped NestedInteger.
4. Once the iteration is complete, the curr NestedInteger contains the deserialized NestedInteger. Return it.

This algorithm works for all languages by converting the string into language-specific data structures (e.g., stringstream in C++ and istringstream in Python). The rest of the implementation remains the same across all languages.


# Lexicographical Numbers

- slug: lexicographical-numbers
- difficulty: Medium

Given an integer `n`, return all the numbers in the range `[1, n]` sorted in lexicographical order.

You must write an algorithm that runs in `O(n)` time and uses `O(1)` extra space.

**Example 1:**

**Input:** n = 13
**Output:** \[1,10,11,12,13,2,3,4,5,6,7,8,9\]

**Example 2:**

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

**Constraints:**

*   `1 <= n <= 5 * 104`

## A solution in Java

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

public static void lexicographicalOrderHelper(int current, int n, List<Integer> result) {
    if (current > n) return;

    result.add(current);
    for (int i = 0; i <= 9; ++i) {
        lexicographicalOrderHelper(current * 10 + i, n, result);
    }
}

public static List<Integer> lexicalOrder(int n) {
    List<Integer> result = new ArrayList<>();
    for (int i = 1; i <= 9; ++i) {
        lexicographicalOrderHelper(i, n, result);
    }
    return result;
}
```
The algorithm relies on a helper function (`lexicographicalOrderHelper`) that takes the current number, n, and the result array as input. This helper function uses recursion to traverse the range of numbers from 1 to n in lexicographical order.

First, the function checks if the current number is greater than n. If so, it returns. Otherwise, it adds the current number to the result array. Then, it loops through the digits 0 to 9, appending each digit to the current number and then recursively calling the function again with the updated value.

The main function (`lexicalOrder`) initializes the result array and iterates through the starting digits (1 to 9), calling the helper function for each starting digit.

The algorithm has a time complexity of O(n), as it goes through each number in the range once. Moreover, the function has an extra space complexity of O(1) because all input parameters are scalars (except for the result array, which is created only once and returned, and recursive calls only manipulate references or scalars).

## A solution in C++

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

void lexicographicalOrderHelper(int current, int n, std::vector<int>& result) {
    if (current > n) return;

    result.push_back(current);
    for (int i = 0; i <= 9; ++i) {
        lexicographicalOrderHelper(current * 10 + i, n, result);
    }
}

std::vector<int> lexicalOrder(int n) {
    std::vector<int> result;
    for (int i = 1; i <= 9; ++i) {
        lexicographicalOrderHelper(i, n, result);
    }
    return result;
}
```
The algorithm relies on a helper function (`lexicographicalOrderHelper`) that takes the current number, n, and the result array as input. This helper function uses recursion to traverse the range of numbers from 1 to n in lexicographical order.

First, the function checks if the current number is greater than n. If so, it returns. Otherwise, it adds the current number to the result array. Then, it loops through the digits 0 to 9, appending each digit to the current number and then recursively calling the function again with the updated value.

The main function (`lexicalOrder`) initializes the result array and iterates through the starting digits (1 to 9), calling the helper function for each starting digit.

The algorithm has a time complexity of O(n), as it goes through each number in the range once. Moreover, the function has an extra space complexity of O(1) because all input parameters are scalars (except for the result array, which is created only once and returned, and recursive calls only manipulate references or scalars).

## A solution in Python

```python
def lexicographical_order_helper(current, n, result):
    if current > n:
        return

    result.append(current)
    for i in range(10):
        lexicographical_order_helper(current * 10 + i, n, result)

def lexical_order(n):
    result = []
    for i in range(1, 10):
        lexicographical_order_helper(i, n, result)
    return result
```
The algorithm relies on a helper function (`lexicographicalOrderHelper`) that takes the current number, n, and the result array as input. This helper function uses recursion to traverse the range of numbers from 1 to n in lexicographical order.

First, the function checks if the current number is greater than n. If so, it returns. Otherwise, it adds the current number to the result array. Then, it loops through the digits 0 to 9, appending each digit to the current number and then recursively calling the function again with the updated value.

The main function (`lexicalOrder`) initializes the result array and iterates through the starting digits (1 to 9), calling the helper function for each starting digit.

The algorithm has a time complexity of O(n), as it goes through each number in the range once. Moreover, the function has an extra space complexity of O(1) because all input parameters are scalars (except for the result array, which is created only once and returned, and recursive calls only manipulate references or scalars).

## A solution in Javascript

```javascript
function lexicographicalOrderHelper(current, n, result) {
    if (current > n) return;

    result.push(current);
    for (let i = 0; i <= 9; ++i) {
        lexicographicalOrderHelper(current * 10 + i, n, result);
    }
}

function lexicalOrder(n) {
    let result = [];
    for (let i = 1; i <= 9; ++i) {
        lexicographicalOrderHelper(i, n, result);
    }
    return result;
}
```
The algorithm relies on a helper function (`lexicographicalOrderHelper`) that takes the current number, n, and the result array as input. This helper function uses recursion to traverse the range of numbers from 1 to n in lexicographical order.

First, the function checks if the current number is greater than n. If so, it returns. Otherwise, it adds the current number to the result array. Then, it loops through the digits 0 to 9, appending each digit to the current number and then recursively calling the function again with the updated value.

The main function (`lexicalOrder`) initializes the result array and iterates through the starting digits (1 to 9), calling the helper function for each starting digit.

The algorithm has a time complexity of O(n), as it goes through each number in the range once. Moreover, the function has an extra space complexity of O(1) because all input parameters are scalars (except for the result array, which is created only once and returned, and recursive calls only manipulate references or scalars).


# First Unique Character in a String

- slug: first-unique-character-in-a-string
- difficulty: Easy

Given a string `s`, _find the first non-repeating character in it and return its index_. If it does not exist, return `-1`.

**Example 1:**

**Input:** s = "leetcode"
**Output:** 0

**Example 2:**

**Input:** s = "loveleetcode"
**Output:** 2

**Example 3:**

**Input:** s = "aabb"
**Output:** -1

**Constraints:**

*   `1 <= s.length <= 105`
*   `s` consists of only lowercase English letters.

## A solution in Java

```java
public int firstUniqChar(String s) {
    HashMap<Character, Integer> charCount = new HashMap<>();
    for (char c : s.toCharArray())
        charCount.put(c, charCount.getOrDefault(c, 0) + 1);
    for (int i = 0; i < s.length(); i++)
        if (charCount.get(s.charAt(i)) == 1)
            return i;
    return -1;
}
```
The algorithm first creates a dictionary to store the count of each character in the input string 's'. Then, it iterates through the string, counting the occurrences of each character and updating the dictionary accordingly.

After that, the algorithm iterates through the input string 's' again, and it checks if the count of the current character in the dictionary is 1. If it is, the algorithm returns the index of the current character as the answer. If no such character is found, the algorithm returns -1 as the answer.

The time complexity of this algorithm is O(n), where n is the length of the input string 's'.

## A solution in C++

```cpp
int firstUniqChar(std::string s) {
    std::unordered_map<char, int> charCount;
    for (char c : s)
        charCount[c]++;
    for (int i = 0; i < s.length(); i++)
        if (charCount[s[i]] == 1)
            return i;
    return -1;
}
```
The algorithm first creates a dictionary to store the count of each character in the input string 's'. Then, it iterates through the string, counting the occurrences of each character and updating the dictionary accordingly.

After that, the algorithm iterates through the input string 's' again, and it checks if the count of the current character in the dictionary is 1. If it is, the algorithm returns the index of the current character as the answer. If no such character is found, the algorithm returns -1 as the answer.

The time complexity of this algorithm is O(n), where n is the length of the input string 's'.

## A solution in Python

```python
def firstUniqChar(s):
    char_count = {}
    for c in s:
        char_count[c] = char_count.get(c, 0) + 1
    for i in range(len(s)):
        if char_count[s[i]] == 1:
            return i
    return -1
```
The algorithm first creates a dictionary to store the count of each character in the input string 's'. Then, it iterates through the string, counting the occurrences of each character and updating the dictionary accordingly.

After that, the algorithm iterates through the input string 's' again, and it checks if the count of the current character in the dictionary is 1. If it is, the algorithm returns the index of the current character as the answer. If no such character is found, the algorithm returns -1 as the answer.

The time complexity of this algorithm is O(n), where n is the length of the input string 's'.

## A solution in Javascript

```javascript
function firstUniqChar(s) {
    let charCount = {};
    for (let c of s)
        charCount[c] = (charCount[c] || 0) + 1;
    for (let i = 0; i < s.length; i++)
        if (charCount[s[i]] === 1)
            return i;
    return -1;
}
```
The algorithm first creates a dictionary to store the count of each character in the input string 's'. Then, it iterates through the string, counting the occurrences of each character and updating the dictionary accordingly.

After that, the algorithm iterates through the input string 's' again, and it checks if the count of the current character in the dictionary is 1. If it is, the algorithm returns the index of the current character as the answer. If no such character is found, the algorithm returns -1 as the answer.

The time complexity of this algorithm is O(n), where n is the length of the input string 's'.