# Find Pivot Index

- slug: find-pivot-index
- difficulty: Easy

Given an array of integers `nums`, calculate the **pivot index** of this array.

The **pivot index** is the index where the sum of all the numbers **strictly** to the left of the index is equal to the sum of all the numbers **strictly** to the index's right.

If the index is on the left edge of the array, then the left sum is `0` because there are no elements to the left. This also applies to the right edge of the array.

Return _the **leftmost pivot index**_. If no such index exists, return `-1`.

**Example 1:**

**Input:** nums = \[1,7,3,6,5,6\]
**Output:** 3
**Explanation:**
The pivot index is 3.
Left sum = nums\[0\] + nums\[1\] + nums\[2\] = 1 + 7 + 3 = 11
Right sum = nums\[4\] + nums\[5\] = 5 + 6 = 11

**Example 2:**

**Input:** nums = \[1,2,3\]
**Output:** -1
**Explanation:**
There is no index that satisfies the conditions in the problem statement.

**Example 3:**

**Input:** nums = \[2,1,-1\]
**Output:** 0
**Explanation:**
The pivot index is 0.
Left sum = 0 (no elements to the left of index 0)
Right sum = nums\[1\] + nums\[2\] = 1 + -1 = 0

**Constraints:**

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

**Note:** This question is the same as 1991: [https://leetcode.com/problems/find-the-middle-index-in-array/](https://leetcode.com/problems/find-the-middle-index-in-array/)

## A solution in Java

```java
public int pivotIndex(int[] nums) {
    int total_sum = 0, left_sum = 0;
    for (int num : nums)
        total_sum += num;
    for (int i = 0; i < nums.length; ++i) {
        if (left_sum == total_sum - left_sum - nums[i])
            return i;
        left_sum += nums[i];
    }
    return -1;
}
```
1. First, find the total sum of the array.
2. Iterate through the array, maintaining a running sum of the elements to the left of the current index.
3. For each index, check if the left sum is equal to the total sum minus the left sum and the value at the current index.
4. If such equality is found, return the index as the pivot index. If not found, return -1.

## A solution in C++

```cpp
int pivotIndex(vector<int>& nums) {
    int total_sum = 0, left_sum = 0;
    for (int num : nums)
        total_sum += num;
    for (int i = 0; i < nums.size(); ++i) {
        if (left_sum == total_sum - left_sum - nums[i])
            return i;
        left_sum += nums[i];
    }
    return -1;
}
```
1. First, find the total sum of the array.
2. Iterate through the array, maintaining a running sum of the elements to the left of the current index.
3. For each index, check if the left sum is equal to the total sum minus the left sum and the value at the current index.
4. If such equality is found, return the index as the pivot index. If not found, return -1.

## A solution in Python

```python
def pivotIndex(nums):
    total_sum = sum(nums)
    left_sum = 0
    for i, num in enumerate(nums):
        if left_sum == total_sum - left_sum - num:
            return i
        left_sum += num
    return -1
```
1. First, find the total sum of the array.
2. Iterate through the array, maintaining a running sum of the elements to the left of the current index.
3. For each index, check if the left sum is equal to the total sum minus the left sum and the value at the current index.
4. If such equality is found, return the index as the pivot index. If not found, return -1.

## A solution in Javascript

```javascript
function pivotIndex(nums) {
    const total_sum = nums.reduce((a, b) => a + b, 0);
    let left_sum = 0;
    for (let i = 0; i < nums.length; ++i) {
        if (left_sum === total_sum - left_sum - nums[i])
            return i;
        left_sum += nums[i];
    }
    return -1;
}
```
1. First, find the total sum of the array.
2. Iterate through the array, maintaining a running sum of the elements to the left of the current index.
3. For each index, check if the left sum is equal to the total sum minus the left sum and the value at the current index.
4. If such equality is found, return the index as the pivot index. If not found, return -1.


# Split Linked List in Parts

- slug: split-linked-list-in-parts
- difficulty: Medium

Given the `head` of a singly linked list and an integer `k`, split the linked list into `k` consecutive linked list parts.

The length of each part should be as equal as possible: no two parts should have a size differing by more than one. This may lead to some parts being null.

The parts should be in the order of occurrence in the input list, and parts occurring earlier should always have a size greater than or equal to parts occurring later.

Return _an array of the_ `k` _parts_.

**Example 1:**

**Input:** head = \[1,2,3\], k = 5
**Output:** \[\[1\],\[2\],\[3\],\[\],\[\]\]
**Explanation:**
The first element output\[0\] has output\[0\].val = 1, output\[0\].next = null.
The last element output\[4\] is null, but its string representation as a ListNode is \[\].

**Example 2:**

**Input:** head = \[1,2,3,4,5,6,7,8,9,10\], k = 3
**Output:** \[\[1,2,3,4\],\[5,6,7\],\[8,9,10\]\]
**Explanation:**
The input has been split into consecutive parts with size difference at most 1, and earlier parts are a larger size than the later parts.

**Constraints:**

*   The number of nodes in the list is in the range `[0, 1000]`.
*   `0 <= Node.val <= 1000`
*   `1 <= k <= 50`

## A solution in Java

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

public ListNode[] splitListToParts(ListNode root, int k) {
    ListNode[] result = new ListNode[k];
    int listSize = 0;
    ListNode currentNode = root;
    while (currentNode != null) {
        listSize++;
        currentNode = currentNode.next;
    }

    int baseSize = listSize / k;
    int extra = listSize % k;

    currentNode = root;
    for (int i = 0; i < k && currentNode != null; ++i) {
        result[i] = currentNode;
        int currentPartSize = baseSize + (i < extra ? 1 : 0);
        for (int j = 1; j < currentPartSize; ++j) {
            currentNode = currentNode.next;
        }
        ListNode nextNode = currentNode.next;
        currentNode.next = null;
        currentNode = nextNode;
    }

    return result;
}
```
1. First, we count the size of the input linked list.
2. Then, we calculate the base size of each part, which is the integer division of the list size by k, and the extra elements, which is the remainder of the integer division of the list size by k.
3. Next, we iterate through the linked list, placing each part in the result array. The size of each part is calculated by adding 1 to the base size if the current part's index is less than the extra, otherwise, it remains the same as the base size.
4. For each part, we move forward in the linked list by one element less than the part size to create the new head for the next part. After reaching the end of the current part, we save the next node, disconnect the current node from the next node, and set the current node to the next node for the next iteration.

## A solution in C++

```
class ListNode {
public:
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(NULL) {}
};

vector<ListNode*> splitListToParts(ListNode* root, int k) {
    vector<ListNode*> result(k, nullptr);
    int listSize = 0;
    ListNode* currentNode = root;
    while (currentNode) {
        listSize++;
        currentNode = currentNode->next;
    }

    int baseSize = listSize / k;
    int extra = listSize % k;

    currentNode = root;
    for (int i = 0; i < k && currentNode; ++i) {
        result[i] = currentNode;
        int currentPartSize = baseSize + (i < extra ? 1 : 0);
        for (int j = 1; j < currentPartSize; ++j) {
            currentNode = currentNode->next;
        }
        ListNode* nextNode = currentNode->next;
        currentNode->next = nullptr;
        currentNode = nextNode;
    }

    return result;
}
```
1. First, we count the size of the input linked list.
2. Then, we calculate the base size of each part, which is the integer division of the list size by k, and the extra elements, which is the remainder of the integer division of the list size by k.
3. Next, we iterate through the linked list, placing each part in the result array. The size of each part is calculated by adding 1 to the base size if the current part's index is less than the extra, otherwise, it remains the same as the base size.
4. For each part, we move forward in the linked list by one element less than the part size to create the new head for the next part. After reaching the end of the current part, we save the next node, disconnect the current node from the next node, and set the current node to the next node for the next iteration.

## A solution in Python

```python
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def splitListToParts(root, k):
    result = [None] * k
    list_size = 0
    current_node = root
    while current_node:
        list_size += 1
        current_node = current_node.next

    base_size = list_size // k
    extra = list_size % k

    current_node = root
    for i in range(k):
        if not current_node:
            break
        result[i] = current_node
        current_part_size = base_size + (1 if i < extra else 0)
        for _ in range(current_part_size - 1):
            current_node = current_node.next
        next_node = current_node.next
        current_node.next = None
        current_node = next_node

    return result
```
1. First, we count the size of the input linked list.
2. Then, we calculate the base size of each part, which is the integer division of the list size by k, and the extra elements, which is the remainder of the integer division of the list size by k.
3. Next, we iterate through the linked list, placing each part in the result array. The size of each part is calculated by adding 1 to the base size if the current part's index is less than the extra, otherwise, it remains the same as the base size.
4. For each part, we move forward in the linked list by one element less than the part size to create the new head for the next part. After reaching the end of the current part, we save the next node, disconnect the current node from the next node, and set the current node to the next node for the next iteration.

## A solution in Javascript

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

function splitListToParts(root, k) {
    let result = new Array(k).fill(null);
    let listSize = 0;
    let currentNode = root;
    while (currentNode) {
        listSize++;
        currentNode = currentNode.next;
    }

    let baseSize = Math.floor(listSize / k);
    let extra = listSize % k;

    currentNode = root;
    for (let i = 0; i < k && currentNode; ++i) {
        result[i] = currentNode;
        let currentPartSize = baseSize + (i < extra ? 1 : 0);
        for (let j = 1; j < currentPartSize; ++j) {
            currentNode = currentNode.next;
        }
        let nextNode = currentNode.next;
        currentNode.next = null;
        currentNode = nextNode;
    }

    return result;
}
```
1. First, we count the size of the input linked list.
2. Then, we calculate the base size of each part, which is the integer division of the list size by k, and the extra elements, which is the remainder of the integer division of the list size by k.
3. Next, we iterate through the linked list, placing each part in the result array. The size of each part is calculated by adding 1 to the base size if the current part's index is less than the extra, otherwise, it remains the same as the base size.
4. For each part, we move forward in the linked list by one element less than the part size to create the new head for the next part. After reaching the end of the current part, we save the next node, disconnect the current node from the next node, and set the current node to the next node for the next iteration.


# Number of Atoms

- slug: number-of-atoms
- difficulty: Hard

Given a string `formula` representing a chemical formula, return _the count of each atom_.

The atomic element always starts with an uppercase character, then zero or more lowercase letters, representing the name.

One or more digits representing that element's count may follow if the count is greater than `1`. If the count is `1`, no digits will follow.

*   For example, `"H2O "` and `"H2O2 "` are possible, but `"H1O2 "` is impossible.

Two formulas are concatenated together to produce another formula.

*   For example, `"H2O2He3Mg4 "` is also a formula.

A formula placed in parentheses, and a count (optionally added) is also a formula.

*   For example, `"(H2O2) "` and `"(H2O2)3 "` are formulas.

Return the count of all elements as a string in the following form: the first name (in sorted order), followed by its count (if that count is more than `1`), followed by the second name (in sorted order), followed by its count (if that count is more than `1`), and so on.

The test cases are generated so that all the values in the output fit in a **32-bit** integer.

**Example 1:**

**Input:** formula =  "H2O "
**Output:**  "H2O "
**Explanation:** The count of elements are {'H': 2, 'O': 1}.

**Example 2:**

**Input:** formula =  "Mg(OH)2 "
**Output:**  "H2MgO2 "
**Explanation:** The count of elements are {'H': 2, 'Mg': 1, 'O': 2}.

**Example 3:**

**Input:** formula =  "K4(ON(SO3)2)2 "
**Output:**  "K4N2O14S4 "
**Explanation:** The count of elements are {'K': 4, 'N': 2, 'O': 14, 'S': 4}.

**Constraints:**

*   `1 <= formula.length <= 1000`
*   `formula` consists of English letters, digits, `'('`, and `')'`.
*   `formula` is always valid.

## A solution in Java

```java
import java.util.Map;
import java.util.TreeMap;

public String countOfAtoms(String formula) {
    int[] i = {0};
    Map<String, Integer> counts = parse(formula, i);
    StringBuilder ans = new StringBuilder();
    for (Map.Entry<String, Integer> entry : counts.entrySet()) {
        ans.append(entry.getKey());
        if (entry.getValue() > 1) ans.append(entry.getValue());
    }
    return ans.toString();
}

private Map<String, Integer> parse(String formula, int[] i) {
    Map<String, Integer> counts = new TreeMap<>();
    while (i[0] < formula.length()) {
        if (formula.charAt(i[0]) == '(') {
            Map<String, Integer> temp = parse(formula, new int[]{++i[0]});
            int count = 0;
            while (i[0] < formula.length() && Character.isDigit(formula.charAt(i[0]))) {
                count = count * 10 + (formula.charAt(i[0]++) - '0');
            }
            if (count == 0) count = 1;
            for (Map.Entry<String, Integer> entry : temp.entrySet()) {
                counts.put(entry.getKey(), counts.getOrDefault(entry.getKey(), 0) + entry.getValue() * count);
            }
        } else if (formula.charAt(i[0]) == ')') {
            ++i[0];
            return counts;
        } else {
            StringBuilder name = new StringBuilder().append(formula.charAt(i[0]++));
            while (i[0] < formula.length() && Character.isLowerCase(formula.charAt(i[0]))) {
                name.append(formula.charAt(i[0]++));
            }
            int count = 0;
            while (i[0] < formula.length() && Character.isDigit(formula.charAt(i[0]))) {
                count = count * 10 + (formula.charAt(i[0]++) - '0');
            }
            if (count == 0) count = 1;
            counts.put(name.toString(), counts.getOrDefault(name.toString(), 0) + count);
        }
    }
    return counts;
}
```
The algorithm is based on a recursive descent parser. The idea is to parse the formula progressively, recognizing the atoms and the opening and closing parentheses. When an opening parenthesis is found, it calls itself to parse the inner formula, then when a closing parenthesis is found, it exits the function and accumulates the counts of the atoms, considering any eventual multiplier following the parentheses. If the formula contains no more parentheses, it will simply read the atoms and their counts.

The resulting atom counts are stored in a map or dictionary, depending on the language. In the end, the algorithm formats the output, concatenating the atom names and their counts (if greater than 1). The elements in the output are ordered based on the requirements (sorted), and no additional formatting is required.

## A solution in C++

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

map<string, int> parse(const string &formula, int &i) {
    map<string, int> counts;
    while (i < formula.size()) {
        if (formula[i] == '(') {
            map<string, int> temp = parse(formula, ++i);
            int count = 0;
            while (isdigit(formula[i])) {
                count = count * 10 + (formula[i++] - '0');
            }
            if (count == 0) count = 1;
            for (const auto &e : temp) {
                counts[e.first] += e.second * count;
            }
        } else if (formula[i] == ')') {
            ++i;
            return counts;
        } else {
            string name;
            name += formula[i++];
            while (islower(formula[i])) {
                name += formula[i++];
            }
            int count = 0;
            while (isdigit(formula[i])) {
                count = count * 10 + (formula[i++] - '0');
            }
            if (count == 0) count = 1;
            counts[name] += count;
        }
    }
    return counts;
}

string countOfAtoms(string formula) {
    int i = 0;
    map<string, int> counts = parse(formula, i);
    string ans;
    for (const auto &e : counts) {
        ans += e.first;
        if (e.second > 1) ans += to_string(e.second);
    }
    return ans;
}
```
The algorithm is based on a recursive descent parser. The idea is to parse the formula progressively, recognizing the atoms and the opening and closing parentheses. When an opening parenthesis is found, it calls itself to parse the inner formula, then when a closing parenthesis is found, it exits the function and accumulates the counts of the atoms, considering any eventual multiplier following the parentheses. If the formula contains no more parentheses, it will simply read the atoms and their counts.

The resulting atom counts are stored in a map or dictionary, depending on the language. In the end, the algorithm formats the output, concatenating the atom names and their counts (if greater than 1). The elements in the output are ordered based on the requirements (sorted), and no additional formatting is required.

## A solution in Python

```python
from collections import Counter

def parse(formula, i):
    counts = Counter()
    while i[0] < len(formula):
        if formula[i[0]] == '(':
            i[0] += 1
            temp = parse(formula, i)
            count = 0
            while i[0] < len(formula) and formula[i[0]].isdigit():
                count = count * 10 + int(formula[i[0]])
                i[0] += 1
            if count == 0: count = 1
            for name, c in temp.items():
                counts[name] += c * count
        elif formula[i[0]] == ')':
            i[0] += 1
            return counts
        else:
            name = formula[i[0]]
            i[0] += 1
            while i[0] < len(formula) and formula[i[0]].islower():
                name += formula[i[0]]
                i[0] += 1
            count = 0
            while i[0] < len(formula) and formula[i[0]].isdigit():
                count = count * 10 + int(formula[i[0]])
                i[0] += 1
            if count == 0: count = 1
            counts[name] += count
    return counts

def countOfAtoms(formula):
    i = [0]
    counts = parse(formula, i)
    ans = []
    for name, count in counts.items():
        ans.append(name)
        if count > 1: ans.append(str(count))
    return ''.join(ans)
```
The algorithm is based on a recursive descent parser. The idea is to parse the formula progressively, recognizing the atoms and the opening and closing parentheses. When an opening parenthesis is found, it calls itself to parse the inner formula, then when a closing parenthesis is found, it exits the function and accumulates the counts of the atoms, considering any eventual multiplier following the parentheses. If the formula contains no more parentheses, it will simply read the atoms and their counts.

The resulting atom counts are stored in a map or dictionary, depending on the language. In the end, the algorithm formats the output, concatenating the atom names and their counts (if greater than 1). The elements in the output are ordered based on the requirements (sorted), and no additional formatting is required.

## A solution in Javascript

```javascript
function parse(formula, i) {
    let counts = {};
    while (i[0] < formula.length) {
        if (formula[i[0]] == '(') {
            i[0] += 1;
            let temp = parse(formula, i);
            let count = 0;
            while (i[0] < formula.length && !isNaN(formula[i[0]])) {
                count = count * 10 + parseInt(formula[i[0]]);
                i[0] += 1;
            }
            if (count == 0) count = 1;
            for (let [name, c] of Object.entries(temp)) {
                counts[name] = (counts[name] || 0) + c * count;
            }
        } else if (formula[i[0]] == ')') {
            i[0] += 1;
            return counts;
        } else {
            let name = formula[i[0]];
            i[0] += 1;
            while (i[0] < formula.length && formula[i[0]] >= 'a' && formula[i[0]] <= 'z') {
                name += formula[i[0]];
                i[0] += 1;
            }
            let count = 0;
            while (i[0] < formula.length && !isNaN(formula[i[0]])) {
                count = count * 10 + parseInt(formula[i[0]]);
                i[0] += 1;
            }
            if (count == 0) count = 1;
            counts[name] = (counts[name] || 0) + count;
        }
    }
    return counts;
}

function countOfAtoms(formula) {
    let i = [0];
    let counts = parse(formula, i);
    let ans = [];
    for (let name of Object.keys(counts).sort()) {
        ans.push(name);
        if (counts[name] > 1) ans.push(counts[name]);
    }
    return ans.join('');
}
```
The algorithm is based on a recursive descent parser. The idea is to parse the formula progressively, recognizing the atoms and the opening and closing parentheses. When an opening parenthesis is found, it calls itself to parse the inner formula, then when a closing parenthesis is found, it exits the function and accumulates the counts of the atoms, considering any eventual multiplier following the parentheses. If the formula contains no more parentheses, it will simply read the atoms and their counts.

The resulting atom counts are stored in a map or dictionary, depending on the language. In the end, the algorithm formats the output, concatenating the atom names and their counts (if greater than 1). The elements in the output are ordered based on the requirements (sorted), and no additional formatting is required.


# Minimum Window Subsequence

- slug: minimum-window-subsequence
- difficulty: Hard

Given strings `s1` and `s2`, return _the minimum contiguous substring part of_ `s1`_, so that_ `s2` _is a subsequence of the part_.

If there is no such window in `s1` that covers all characters in `s2`, return the empty string `" "`. If there are multiple such minimum-length windows, return the one with the **left-most starting index**.

**Example 1:**

**Input:** s1 =  "abcdebdde ", s2 =  "bde "
**Output:**  "bcde "
**Explanation:**
 "bcde " is the answer because it occurs before  "bdde " which has the same length.
 "deb " is not a smaller window because the elements of s2 in the window must occur in order.

**Example 2:**

**Input:** s1 =  "jmeqksfrsdcmsiwvaovztaqenprpvnbstl ", s2 =  "u "
**Output:**  " "

**Constraints:**

*   `1 <= s1.length <= 2 * 104`
*   `1 <= s2.length <= 100`
*   `s1` and `s2` consist of lowercase English letters.

## A solution in Java

```java
public String minWindowSubSequence(String s1, String s2) {
    int m = s1.length(), n = s2.length();
    int[][] dp = new int[n + 1][m + 1];

    for (int j = 0; j <= m; ++j) {
        dp[0][j] = j;
    }

    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (s1.charAt(j - 1) == s2.charAt(i - 1)) {
                dp[i][j] = dp[i - 1][j - 1];
            } else {
                dp[i][j] = dp[i][j - 1];
            }
        }
    }

    int start = 0, length = m + 1;
    for (int j = 1; j <= m; ++j) {
        if (dp[n][j] != 0 && j - dp[n][j] < length) {
            start = dp[n][j];
            length = j - start;
        }
    }

    return length == m + 1 ? "" : s1.substring(start, start + length);
}
```
We will use Dynamic Programming to build a matrix `dp` where `dp[i][j]` represents the index in string `s1` where the length `i` of the subsequence `s2` has been reached up to index `j` in string `s1`. We fill the `dp` matrix by iterating through `s1` and `s2`, and if `s1[j-1] == s2[i-1]`, then we set `dp[i][j]` equal to the previous subsequence match index (which is `dp[i-1][j-1]`), otherwise, set `dp[i][j]` to the value in the left adjacent cell `dp[i][j-1]`.

Then, we iterate through the last row of the `dp` matrix to find the minimum contiguous substring part of `s1`, such that `s2` is a subsequence of the part. For each cell in the last row (i.e., `dp[n][j]`), we evaluate if there is a better minimum length, and if so, update the `start` and `length` accordingly.

Finally, we return the minimum contiguous substring part of `s1`, or an empty string if `length` is still equal to `m + 1`.

## A solution in C++

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

std::string min_window_sub_sequence(std::string s1, std::string s2) {
    int m = s1.length(), n = s2.length();
    std::vector<std::vector<int>> dp(n + 1, std::vector<int>(m + 1, -1));

    for (int j = 0; j <= m; ++j) {
        dp[0][j] = j;
    }

    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (s1[j - 1] == s2[i - 1]) {
                dp[i][j] = dp[i - 1][j - 1];
            } else {
                dp[i][j] = dp[i][j - 1];
            }
        }
    }

    int start = 0, length = m + 1;
    for (int j = 1; j <= m; ++j) {
        if (dp[n][j] != -1 && j - dp[n][j] < length) {
            start = dp[n][j];
            length = j - start;
        }
    }

    return length == m + 1 ? "" : s1.substr(start, length);
}
```
We will use Dynamic Programming to build a matrix `dp` where `dp[i][j]` represents the index in string `s1` where the length `i` of the subsequence `s2` has been reached up to index `j` in string `s1`. We fill the `dp` matrix by iterating through `s1` and `s2`, and if `s1[j-1] == s2[i-1]`, then we set `dp[i][j]` equal to the previous subsequence match index (which is `dp[i-1][j-1]`), otherwise, set `dp[i][j]` to the value in the left adjacent cell `dp[i][j-1]`.

Then, we iterate through the last row of the `dp` matrix to find the minimum contiguous substring part of `s1`, such that `s2` is a subsequence of the part. For each cell in the last row (i.e., `dp[n][j]`), we evaluate if there is a better minimum length, and if so, update the `start` and `length` accordingly.

Finally, we return the minimum contiguous substring part of `s1`, or an empty string if `length` is still equal to `m + 1`.

## A solution in Python

```python
def min_window_sub_sequence(s1: str, s2: str) -> str:
    m, n = len(s1), len(s2)
    dp = [[0] * (m + 1) for _ in range(n + 1)]

    for j in range(0, m + 1):
        dp[0][j] = j

    for i in range(1, n + 1):
        for j in range(1, m + 1):
            if s1[j - 1] == s2[i - 1]:
                dp[i][j] = dp[i - 1][j - 1]
            else:
                dp[i][j] = dp[i][j - 1]

    start, length = 0, m + 1
    for j in range(1, m + 1):
        if dp[n][j] != 0 and j - dp[n][j] < length:
            start = dp[n][j]
            length = j - start

    return "" if length == m + 1 else s1[start:start + length]
```
We will use Dynamic Programming to build a matrix `dp` where `dp[i][j]` represents the index in string `s1` where the length `i` of the subsequence `s2` has been reached up to index `j` in string `s1`. We fill the `dp` matrix by iterating through `s1` and `s2`, and if `s1[j-1] == s2[i-1]`, then we set `dp[i][j]` equal to the previous subsequence match index (which is `dp[i-1][j-1]`), otherwise, set `dp[i][j]` to the value in the left adjacent cell `dp[i][j-1]`.

Then, we iterate through the last row of the `dp` matrix to find the minimum contiguous substring part of `s1`, such that `s2` is a subsequence of the part. For each cell in the last row (i.e., `dp[n][j]`), we evaluate if there is a better minimum length, and if so, update the `start` and `length` accordingly.

Finally, we return the minimum contiguous substring part of `s1`, or an empty string if `length` is still equal to `m + 1`.

## A solution in Javascript

```javascript
function minWindowSubSequence(s1, s2) {
    const m = s1.length, n = s2.length;
    const dp = Array.from({ length: n + 1 }, () => Array(m + 1).fill(0));

    for (let j = 0; j <= m; ++j) {
        dp[0][j] = j;
    }

    for (let i = 1; i <= n; ++i) {
        for (let j = 1; j <= m; ++j) {
            if (s1[j - 1] === s2[i - 1]) {
                dp[i][j] = dp[i - 1][j - 1];
            } else {
                dp[i][j] = dp[i][j - 1];
            }
        }
    }

    let start = 0, length = m + 1;
    for (let j = 1; j <= m; ++j) {
        if (dp[n][j] !== 0 && j - dp[n][j] < length) {
            start = dp[n][j];
            length = j - start;
        }
    }

    return length === m + 1 ? "" : s1.slice(start, start + length);
}
```
We will use Dynamic Programming to build a matrix `dp` where `dp[i][j]` represents the index in string `s1` where the length `i` of the subsequence `s2` has been reached up to index `j` in string `s1`. We fill the `dp` matrix by iterating through `s1` and `s2`, and if `s1[j-1] == s2[i-1]`, then we set `dp[i][j]` equal to the previous subsequence match index (which is `dp[i-1][j-1]`), otherwise, set `dp[i][j]` to the value in the left adjacent cell `dp[i][j-1]`.

Then, we iterate through the last row of the `dp` matrix to find the minimum contiguous substring part of `s1`, such that `s2` is a subsequence of the part. For each cell in the last row (i.e., `dp[n][j]`), we evaluate if there is a better minimum length, and if so, update the `start` and `length` accordingly.

Finally, we return the minimum contiguous substring part of `s1`, or an empty string if `length` is still equal to `m + 1`.


# Self Dividing Numbers

- slug: self-dividing-numbers
- difficulty: Easy

A **self-dividing number** is a number that is divisible by every digit it contains.

*   For example, `128` is **a self-dividing number** because `128 % 1 == 0`, `128 % 2 == 0`, and `128 % 8 == 0`.

A **self-dividing number** is not allowed to contain the digit zero.

Given two integers `left` and `right`, return _a list of all the **self-dividing numbers** in the range_ `[left, right]`.

**Example 1:**

**Input:** left = 1, right = 22
**Output:** \[1,2,3,4,5,6,7,8,9,11,12,15,22\]

**Example 2:**

**Input:** left = 47, right = 85
**Output:** \[48,55,66,77\]

**Constraints:**

*   `1 <= left <= right <= 104`

## A solution in Java

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

public class Solution {
    public static boolean isSelfDividing(int num) {
        int n = num;
        while (n != 0) {
            int digit = n % 10;
            if (digit == 0 || num % digit != 0)
                return false;
            n /= 10;
        }
        return true;
    }

    public static List<Integer> selfDividingNumbers(int left, int right) {
        List<Integer> result = new ArrayList<>();
        for (int i = left; i <= right; ++i) {
            if (isSelfDividing(i))
                result.add(i);
        }
        return result;
    }
}
```
The algorithm consists of two functions: `isSelfDividing` and `selfDividingNumbers`. The first function, `isSelfDividing`, takes an integer as input and returns true if it is a self-dividing number and false otherwise. It does this by checking each digit of the number and verifying that they're nonzero and that the number is divisible by that digit. The checking is done by repeatedly dividing the number by 10 and finding the remainder.

The second function, `selfDividingNumbers`, takes `left` and `right` as input, and returns a list of self-dividing numbers in the given range. It iterates through all the numbers between `left` and `right` (inclusive) and checks if the number is a self-dividing number using the `isSelfDividing` function. If it is, the number is added to the result list. Finally, the result list is returned.

## A solution in C++

```cpp
#include <vector>

bool isSelfDividing(int num) {
    int n = num;
    while (n) {
        int digit = n % 10;
        if (digit == 0 || num % digit != 0)
            return false;
        n /= 10;
    }
    return true;
}

std::vector<int> selfDividingNumbers(int left, int right) {
    std::vector<int> result;
    for (int i = left; i <= right; ++i) {
        if (isSelfDividing(i))
            result.push_back(i);
    }
    return result;
}
```
The algorithm consists of two functions: `isSelfDividing` and `selfDividingNumbers`. The first function, `isSelfDividing`, takes an integer as input and returns true if it is a self-dividing number and false otherwise. It does this by checking each digit of the number and verifying that they're nonzero and that the number is divisible by that digit. The checking is done by repeatedly dividing the number by 10 and finding the remainder.

The second function, `selfDividingNumbers`, takes `left` and `right` as input, and returns a list of self-dividing numbers in the given range. It iterates through all the numbers between `left` and `right` (inclusive) and checks if the number is a self-dividing number using the `isSelfDividing` function. If it is, the number is added to the result list. Finally, the result list is returned.

## A solution in Python

```python
def is_self_dividing(num):
    n = num
    while n:
        digit = n % 10
        if digit == 0 or num % digit != 0:
            return False
        n //= 10
    return True

def self_dividing_numbers(left, right):
    return [i for i in range(left, right+1) if is_self_dividing(i)]
```
The algorithm consists of two functions: `isSelfDividing` and `selfDividingNumbers`. The first function, `isSelfDividing`, takes an integer as input and returns true if it is a self-dividing number and false otherwise. It does this by checking each digit of the number and verifying that they're nonzero and that the number is divisible by that digit. The checking is done by repeatedly dividing the number by 10 and finding the remainder.

The second function, `selfDividingNumbers`, takes `left` and `right` as input, and returns a list of self-dividing numbers in the given range. It iterates through all the numbers between `left` and `right` (inclusive) and checks if the number is a self-dividing number using the `isSelfDividing` function. If it is, the number is added to the result list. Finally, the result list is returned.

## A solution in Javascript

```javascript
function isSelfDividing(num) {
    let n = num;
    while (n) {
        const digit = n % 10;
        if (digit === 0 || num % digit !== 0)
            return false;
        n = Math.floor(n / 10);
    }
    return true;
}

function selfDividingNumbers(left, right) {
    const result = [];
    for (let i = left; i <= right; ++i) {
        if (isSelfDividing(i))
            result.push(i);
    }
    return result;
}
```
The algorithm consists of two functions: `isSelfDividing` and `selfDividingNumbers`. The first function, `isSelfDividing`, takes an integer as input and returns true if it is a self-dividing number and false otherwise. It does this by checking each digit of the number and verifying that they're nonzero and that the number is divisible by that digit. The checking is done by repeatedly dividing the number by 10 and finding the remainder.

The second function, `selfDividingNumbers`, takes `left` and `right` as input, and returns a list of self-dividing numbers in the given range. It iterates through all the numbers between `left` and `right` (inclusive) and checks if the number is a self-dividing number using the `isSelfDividing` function. If it is, the number is added to the result list. Finally, the result list is returned.


# My Calendar I

- slug: my-calendar-i
- difficulty: Medium

You are implementing a program to use as your calendar. We can add a new event if adding the event will not cause a **double booking**.

A **double booking** happens when two events have some non-empty intersection (i.e., some moment is common to both events.).

The event can be represented as a pair of integers `start` and `end` that represents a booking on the half-open interval `[start, end)`, the range of real numbers `x` such that `start <= x < end`.

Implement the `MyCalendar` class:

*   `MyCalendar()` Initializes the calendar object.
*   `boolean book(int start, int end)` Returns `true` if the event can be added to the calendar successfully without causing a **double booking**. Otherwise, return `false` and do not add the event to the calendar.

**Example 1:**

**Input**
\[ "MyCalendar ",  "book ",  "book ",  "book "\]
\[\[\], \[10, 20\], \[15, 25\], \[20, 30\]\]
**Output**
\[null, true, false, true\]

**Explanation**
MyCalendar myCalendar = new MyCalendar();
myCalendar.book(10, 20); // return True
myCalendar.book(15, 25); // return False, It can not be booked because time 15 is already booked by another event.
myCalendar.book(20, 30); // return True, The event can be booked, as the first event takes every time less than 20, but not including 20.

**Constraints:**

*   `0 <= start < end <= 109`
*   At most `1000` calls will be made to `book`.

## A solution in Java

```java
import java.util.TreeMap;

class MyCalendar {
    private TreeMap<Integer, Integer> calendar;

    public MyCalendar() {
        calendar = new TreeMap<>();
    }

    public boolean book(int start, int end) {
        Integer prevStart = calendar.floorKey(start);
        Integer nextStart = calendar.ceilingKey(start);

        if ((prevStart == null || calendar.get(prevStart) <= start) &&
            (nextStart == null || end <= nextStart)) {
            calendar.put(start, end);
            return true;
        }
        return false;
    }
}
```
This algorithm uses a data structure (map in C++, TreeMap in Java, List in Python, and Map in JavaScript) to store the events in the calendar. The `book()` function takes in the start and end times of the event.

1. In C++, the function finds the iterator pointing to the position just greater than or equal to the start time. If there is an event before this iterator and its end time is greater than the start time of the new event, we return false as double booking occurs.
2. In Java, we use the floorKey and ceilingKey functions to find the events closest to the start time of the new event. We check if there is any overlap with these events, and if there is none, we insert the event into the calendar.
3. In Python, we use a bisect_left function to find the index at which the new event can be inserted. We then check if there is any overlap with the previous event or the next event in the list, and if not, we insert the start and end times of the new event in the calendar.
4. In JavaScript, the function iterates through the calendar's events and checks if there are any overlaps using the maximum of start times and the minimum of end times. If there are no overlaps, the new event is inserted into the calendar.

If there are no overlaps with other events (i.e., no double booking), the function returns true; otherwise, it returns false.

## A solution in C++

```cpp
#include <map>

class MyCalendar {
public:
    std::map<int, int> calendar;

    bool book(int start, int end) {
        auto it = calendar.lower_bound(start);
        if (it != calendar.begin() && (--it)->second > start) return false;
        if (it != calendar.end() && end > it->first) return false;
        calendar[start] = end;
        return true;
    }
};
```
This algorithm uses a data structure (map in C++, TreeMap in Java, List in Python, and Map in JavaScript) to store the events in the calendar. The `book()` function takes in the start and end times of the event.

1. In C++, the function finds the iterator pointing to the position just greater than or equal to the start time. If there is an event before this iterator and its end time is greater than the start time of the new event, we return false as double booking occurs.
2. In Java, we use the floorKey and ceilingKey functions to find the events closest to the start time of the new event. We check if there is any overlap with these events, and if there is none, we insert the event into the calendar.
3. In Python, we use a bisect_left function to find the index at which the new event can be inserted. We then check if there is any overlap with the previous event or the next event in the list, and if not, we insert the start and end times of the new event in the calendar.
4. In JavaScript, the function iterates through the calendar's events and checks if there are any overlaps using the maximum of start times and the minimum of end times. If there are no overlaps, the new event is inserted into the calendar.

If there are no overlaps with other events (i.e., no double booking), the function returns true; otherwise, it returns false.

## A solution in Python

```python
from bisect import bisect_left, insort

class MyCalendar:

    def __init__(self):
        self.calendar = []

    def book(self, start, end):
        i = bisect_left(self.calendar, [start, end])
        if i % 2 == 1:
            return False
        if i > 0 and self.calendar[i-1] > start:
            return False
        if i < len(self.calendar) and end > self.calendar[i]:
            return False
        insort(self.calendar, start)
        insort(self.calendar, end)
        return True
```
This algorithm uses a data structure (map in C++, TreeMap in Java, List in Python, and Map in JavaScript) to store the events in the calendar. The `book()` function takes in the start and end times of the event.

1. In C++, the function finds the iterator pointing to the position just greater than or equal to the start time. If there is an event before this iterator and its end time is greater than the start time of the new event, we return false as double booking occurs.
2. In Java, we use the floorKey and ceilingKey functions to find the events closest to the start time of the new event. We check if there is any overlap with these events, and if there is none, we insert the event into the calendar.
3. In Python, we use a bisect_left function to find the index at which the new event can be inserted. We then check if there is any overlap with the previous event or the next event in the list, and if not, we insert the start and end times of the new event in the calendar.
4. In JavaScript, the function iterates through the calendar's events and checks if there are any overlaps using the maximum of start times and the minimum of end times. If there are no overlaps, the new event is inserted into the calendar.

If there are no overlaps with other events (i.e., no double booking), the function returns true; otherwise, it returns false.

## A solution in Javascript

```javascript
class MyCalendar {
    constructor() {
        this.calendar = new Map();
    }

    book(start, end) {
        if (this.calendar.size === 0) {
            this.calendar.set(start, end);
            return true;
        }

        let booked = false;
        for (let [s, e] of this.calendar) {
            if (Math.max(s, start) < Math.min(e, end)) {
                booked = true;
                break;
            }
        }

        if (!booked) {
            this.calendar.set(start, end);
            return true;
        }

        return false;
    }
}
```
This algorithm uses a data structure (map in C++, TreeMap in Java, List in Python, and Map in JavaScript) to store the events in the calendar. The `book()` function takes in the start and end times of the event.

1. In C++, the function finds the iterator pointing to the position just greater than or equal to the start time. If there is an event before this iterator and its end time is greater than the start time of the new event, we return false as double booking occurs.
2. In Java, we use the floorKey and ceilingKey functions to find the events closest to the start time of the new event. We check if there is any overlap with these events, and if there is none, we insert the event into the calendar.
3. In Python, we use a bisect_left function to find the index at which the new event can be inserted. We then check if there is any overlap with the previous event or the next event in the list, and if not, we insert the start and end times of the new event in the calendar.
4. In JavaScript, the function iterates through the calendar's events and checks if there are any overlaps using the maximum of start times and the minimum of end times. If there are no overlaps, the new event is inserted into the calendar.

If there are no overlaps with other events (i.e., no double booking), the function returns true; otherwise, it returns false.


# Count Different Palindromic Subsequences

- slug: count-different-palindromic-subsequences
- difficulty: Hard

Given a string s, return _the number of different non-empty palindromic subsequences in_ `s`. Since the answer may be very large, return it **modulo** `109 + 7`.

A subsequence of a string is obtained by deleting zero or more characters from the string.

A sequence is palindromic if it is equal to the sequence reversed.

Two sequences `a1, a2, ...` and `b1, b2, ...` are different if there is some `i` for which `ai != bi`.

**Example 1:**

**Input:** s =  "bccb "
**Output:** 6
**Explanation:** The 6 different non-empty palindromic subsequences are 'b', 'c', 'bb', 'cc', 'bcb', 'bccb'.
Note that 'bcb' is counted only once, even though it occurs twice.

**Example 2:**

**Input:** s =  "abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba "
**Output:** 104860361
**Explanation:** There are 3104860382 different non-empty palindromic subsequences, which is 104860361 modulo 109 + 7.

**Constraints:**

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

## A solution in Java

```java
public int countPalindromicSubsequences(String S) {
    int n = S.length();
    int mod = 1000000007;
    int[][] dp = new int[4][n + 1];

    for (int i = n - 1; i >= 0; i--) {
        for (int j = i + 1; j <= n; j++) {
            int c = S.charAt(i) - 'a';
            dp[c][j] = dp[0][j - 1] + dp[1][j - 1] + dp[2][j - 1] + dp[3][j - 1] - dp[c][i] + 2;
            if (dp[c][j] < 0) dp[c][j] += mod;
        }
    }

    return (dp[0][n] + dp[1][n] + dp[2][n] + dp[3][n]) % mod;
}
```
The algorithm uses dynamic programming. The state of `dp[i][j]` stores the number of different non-empty palindromic subsequences of `s` with characters from index `i` to `j - 1`, and only considering the character `s[i]`. Iterating over the string from the back, the algorithm checks the current character into its corresponding bucket, and updates the current bucket's values based on the previous state.

This algorithm has a time complexity of O(N^2), where N is the length of the string. The space complexity is O(N), as the algorithm only stores palindromic subsequences for each character from 'a' to 'd'.

## A solution in C++

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

int countPalindromicSubsequences(string s) {
    int n = s.length();
    int MOD = 1000000007;
    vector<vector<int>> dp(4, vector<int>(n + 1, 0));

    for (int i = n - 1; i >= 0; i--) {
        for (int j = i + 1; j <= n; j++) {
            int c = s[i] - 'a';
            dp[c][j] = dp[0][j - 1] + dp[1][j - 1] + dp[2][j - 1] + dp[3][j - 1] - dp[c][i] + 2;
            dp[c][j] = (dp[c][j] + MOD) % MOD;
        }
    }

    return (dp[0][n] + dp[1][n] + dp[2][n] + dp[3][n]) % MOD;
}
```
The algorithm uses dynamic programming. The state of `dp[i][j]` stores the number of different non-empty palindromic subsequences of `s` with characters from index `i` to `j - 1`, and only considering the character `s[i]`. Iterating over the string from the back, the algorithm checks the current character into its corresponding bucket, and updates the current bucket's values based on the previous state.

This algorithm has a time complexity of O(N^2), where N is the length of the string. The space complexity is O(N), as the algorithm only stores palindromic subsequences for each character from 'a' to 'd'.

## A solution in Python

```python
def countPalindromicSubsequences(s: str) -> int:
    n = len(s)
    MOD = 1000000007
    dp = [[0] * (n + 1) for _ in range(4)]

    for i in range(n - 1, -1, -1):
        for j in range(i + 1, n + 1):
            c = ord(s[i]) - ord('a')
            dp[c][j] = sum(dp[k][j - 1] for k in range(4)) - dp[c][i] + 2
            dp[c][j] = (dp[c][j] + MOD) % MOD

    return sum(dp[c][n] for c in range(4)) % MOD
```
The algorithm uses dynamic programming. The state of `dp[i][j]` stores the number of different non-empty palindromic subsequences of `s` with characters from index `i` to `j - 1`, and only considering the character `s[i]`. Iterating over the string from the back, the algorithm checks the current character into its corresponding bucket, and updates the current bucket's values based on the previous state.

This algorithm has a time complexity of O(N^2), where N is the length of the string. The space complexity is O(N), as the algorithm only stores palindromic subsequences for each character from 'a' to 'd'.

## A solution in Javascript

```javascript
function countPalindromicSubsequences(s) {
    const n = s.length;
    const MOD = 1000000007;
    const dp = Array.from({ length: 4 }, () => Array(n + 1).fill(0));

    for (let i = n - 1; i >= 0; i--) {
        for (let j = i + 1; j <= n; j++) {
            const c = s.charCodeAt(i) - 97;
            dp[c][j] = dp[0][j - 1] + dp[1][j - 1] + dp[2][j - 1] + dp[3][j - 1] - dp[c][i] + 2;
            dp[c][j] = (dp[c][j] + MOD) % MOD;
        }
    }

    return (dp[0][n] + dp[1][n] + dp[2][n] + dp[3][n]) % MOD;
}
```
The algorithm uses dynamic programming. The state of `dp[i][j]` stores the number of different non-empty palindromic subsequences of `s` with characters from index `i` to `j - 1`, and only considering the character `s[i]`. Iterating over the string from the back, the algorithm checks the current character into its corresponding bucket, and updates the current bucket's values based on the previous state.

This algorithm has a time complexity of O(N^2), where N is the length of the string. The space complexity is O(N), as the algorithm only stores palindromic subsequences for each character from 'a' to 'd'.


# My Calendar II

- slug: my-calendar-ii
- difficulty: Medium

You are implementing a program to use as your calendar. We can add a new event if adding the event will not cause a **triple booking**.

A **triple booking** happens when three events have some non-empty intersection (i.e., some moment is common to all the three events.).

The event can be represented as a pair of integers `start` and `end` that represents a booking on the half-open interval `[start, end)`, the range of real numbers `x` such that `start <= x < end`.

Implement the `MyCalendarTwo` class:

*   `MyCalendarTwo()` Initializes the calendar object.
*   `boolean book(int start, int end)` Returns `true` if the event can be added to the calendar successfully without causing a **triple booking**. Otherwise, return `false` and do not add the event to the calendar.

**Example 1:**

**Input**
\[ "MyCalendarTwo ",  "book ",  "book ",  "book ",  "book ",  "book ",  "book "\]
\[\[\], \[10, 20\], \[50, 60\], \[10, 40\], \[5, 15\], \[5, 10\], \[25, 55\]\]
**Output**
\[null, true, true, true, false, true, true\]

**Explanation**
MyCalendarTwo myCalendarTwo = new MyCalendarTwo();
myCalendarTwo.book(10, 20); // return True, The event can be booked.
myCalendarTwo.book(50, 60); // return True, The event can be booked.
myCalendarTwo.book(10, 40); // return True, The event can be double booked.
myCalendarTwo.book(5, 15);  // return False, The event cannot be booked, because it would result in a triple booking.
myCalendarTwo.book(5, 10); // return True, The event can be booked, as it does not use time 10 which is already double booked.
myCalendarTwo.book(25, 55); // return True, The event can be booked, as the time in \[25, 40) will be double booked with the third event, the time \[40, 50) will be single booked, and the time \[50, 55) will be double booked with the second event.

**Constraints:**

*   `0 <= start < end <= 109`
*   At most `1000` calls will be made to `book`.

## A solution in Java

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

class MyCalendarTwo {
    List<int[]> singles, doubles;

    public MyCalendarTwo() {
        singles = new ArrayList<>();
        doubles = new ArrayList<>();
    }

    public boolean book(int start, int end) {
        for (int[] d : doubles) {
            if (start < d[1] && end > d[0]) return false;
        }
        for (int[] s : singles) {
            if (start < s[1] && end > s[0]) {
                doubles.add(new int[]{Math.max(start, s[0]), Math.min(end, s[1])});
            }
        }
        singles.add(new int[]{start, end});
        return true;
    }
}
```
The algorithm maintains two lists, one for single bookings and one for double bookings. When a new event is added, it first checks if the new event overlaps with any of the double events; if so, it returns false since it would cause a triple booking. Then, it checks if the new event overlaps with any single events, and if so, calculates the overlap and adds it to the list of double events. Finally, adds the new event to the list of single events and returns true. This way, we have an efficient way of avoiding triple bookings using simple iterations and checking.

## A solution in C++

```cpp
#include <vector>

class MyCalendarTwo {
    std::vector<std::pair<int, int>> singles, doubles;
public:
    bool book(int start, int end) {
        for (auto d : doubles) {
            if (start < d.second && end > d.first) return false;
        }
        for (auto s : singles) {
            if (start < s.second && end > s.first) {
                doubles.emplace_back(std::max(start, s.first), std::min(end, s.second));
            }
        }
        singles.emplace_back(start, end);
        return true;
    }
};
```
The algorithm maintains two lists, one for single bookings and one for double bookings. When a new event is added, it first checks if the new event overlaps with any of the double events; if so, it returns false since it would cause a triple booking. Then, it checks if the new event overlaps with any single events, and if so, calculates the overlap and adds it to the list of double events. Finally, adds the new event to the list of single events and returns true. This way, we have an efficient way of avoiding triple bookings using simple iterations and checking.

## A solution in Python

```python
class MyCalendarTwo:
    def __init__(self):
        self.singles = []
        self.doubles = []

    def book(self, start: int, end: int) -> bool:
        for d_start, d_end in self.doubles:
            if start < d_end and end > d_start:
                return False
        for s_start, s_end in self.singles:
            if start < s_end and end > s_start:
                self.doubles.append((max(start, s_start), min(end, s_end)))
        self.singles.append((start, end))
        return True
```
The algorithm maintains two lists, one for single bookings and one for double bookings. When a new event is added, it first checks if the new event overlaps with any of the double events; if so, it returns false since it would cause a triple booking. Then, it checks if the new event overlaps with any single events, and if so, calculates the overlap and adds it to the list of double events. Finally, adds the new event to the list of single events and returns true. This way, we have an efficient way of avoiding triple bookings using simple iterations and checking.

## A solution in Javascript

```javascript
class MyCalendarTwo {
    constructor() {
        this.singles = [];
        this.doubles = [];
    }

    book(start, end) {
        for (const [dStart, dEnd] of this.doubles) {
            if (start < dEnd && end > dStart) return false;
        }
        for (const [sStart, sEnd] of this.singles) {
            if (start < sEnd && end > sStart) {
                this.doubles.push([Math.max(start, sStart), Math.min(end, sEnd)]);
            }
        }
        this.singles.push([start, end]);
        return true;
    }
}
```
The algorithm maintains two lists, one for single bookings and one for double bookings. When a new event is added, it first checks if the new event overlaps with any of the double events; if so, it returns false since it would cause a triple booking. Then, it checks if the new event overlaps with any single events, and if so, calculates the overlap and adds it to the list of double events. Finally, adds the new event to the list of single events and returns true. This way, we have an efficient way of avoiding triple bookings using simple iterations and checking.


# My Calendar III

- slug: my-calendar-iii
- difficulty: Hard

A `k`\-booking happens when `k` events have some non-empty intersection (i.e., there is some time that is common to all `k` events.)

You are given some events `[startTime, endTime)`, after each given event, return an integer `k` representing the maximum `k`\-booking between all the previous events.

Implement the `MyCalendarThree` class:

*   `MyCalendarThree()` Initializes the object.
*   `int book(int startTime, int endTime)` Returns an integer `k` representing the largest integer such that there exists a `k`\-booking in the calendar.

**Example 1:**

**Input**
\[ "MyCalendarThree ",  "book ",  "book ",  "book ",  "book ",  "book ",  "book "\]
\[\[\], \[10, 20\], \[50, 60\], \[10, 40\], \[5, 15\], \[5, 10\], \[25, 55\]\]
**Output**
\[null, 1, 1, 2, 3, 3, 3\]

**Explanation**
MyCalendarThree myCalendarThree = new MyCalendarThree();
myCalendarThree.book(10, 20); // return 1
myCalendarThree.book(50, 60); // return 1
myCalendarThree.book(10, 40); // return 2
myCalendarThree.book(5, 15); // return 3
myCalendarThree.book(5, 10); // return 3
myCalendarThree.book(25, 55); // return 3

**Constraints:**

*   `0 <= startTime < endTime <= 109`
*   At most `400` calls will be made to `book`.

## A solution in Java

```java
import java.util.TreeMap;

class MyCalendarThree {
    private TreeMap<Integer, Integer> timeline = new TreeMap<>();

    public int book(int start, int end) {
        timeline.put(start, timeline.getOrDefault(start, 0) + 1);
        timeline.put(end, timeline.getOrDefault(end, 0) - 1);
        int ongoing = 0, k = 0;
        for (int value : timeline.values()) {
            k = Math.max(k, ongoing += value);
        }
        return k;
    }
}
```
The algorithm maintains a timeline, which is a data structure that stores events with their start and end times. For each booking, we increase the value at the start time by 1 and decrease the value at the end time by 1 in the timeline.

After updating the timeline, we iterate over its values and keep track of the ongoing events count. By getting the maximum value of the ongoing events count, we can determine the maximum k-booking.

In C++, we use a `std::map<int, int>` to store the timeline events, while in Java, we use `TreeMap<Integer, Integer>`. In Python, we use a `collections.defaultdict(int)` to store the timeline events, and in JavaScript, we use a `Map()`.

The time complexity of the algorithm is O(N * log N) due to sorting for time (start and end) in the timeline data structure. The space complexity is O(N) to store the timeline events where N is the number of events.

## A solution in C++

```cpp
#include <map>

class MyCalendarThree {
public:
    std::map<int, int> timeline;

    int book(int start, int end) {
        timeline[start]++;
        timeline[end]--;
        int ongoing = 0, k = 0;
        for (auto& t : timeline) {
            k = std::max(k, ongoing += t.second);
        }
        return k;
    }
};
```
The algorithm maintains a timeline, which is a data structure that stores events with their start and end times. For each booking, we increase the value at the start time by 1 and decrease the value at the end time by 1 in the timeline.

After updating the timeline, we iterate over its values and keep track of the ongoing events count. By getting the maximum value of the ongoing events count, we can determine the maximum k-booking.

In C++, we use a `std::map<int, int>` to store the timeline events, while in Java, we use `TreeMap<Integer, Integer>`. In Python, we use a `collections.defaultdict(int)` to store the timeline events, and in JavaScript, we use a `Map()`.

The time complexity of the algorithm is O(N * log N) due to sorting for time (start and end) in the timeline data structure. The space complexity is O(N) to store the timeline events where N is the number of events.

## A solution in Python

```python
from collections import defaultdict
import heapq

class MyCalendarThree:

    def __init__(self):
        self.timeline = defaultdict(int)

    def book(self, start: int, end: int) -> int:
        self.timeline[start] += 1
        self.timeline[end] -= 1
        ongoing, k = 0, 0
        for value in self.timeline.values():
            k = max(k, ongoing + value)
            ongoing += value
        return k
```
The algorithm maintains a timeline, which is a data structure that stores events with their start and end times. For each booking, we increase the value at the start time by 1 and decrease the value at the end time by 1 in the timeline.

After updating the timeline, we iterate over its values and keep track of the ongoing events count. By getting the maximum value of the ongoing events count, we can determine the maximum k-booking.

In C++, we use a `std::map<int, int>` to store the timeline events, while in Java, we use `TreeMap<Integer, Integer>`. In Python, we use a `collections.defaultdict(int)` to store the timeline events, and in JavaScript, we use a `Map()`.

The time complexity of the algorithm is O(N * log N) due to sorting for time (start and end) in the timeline data structure. The space complexity is O(N) to store the timeline events where N is the number of events.

## A solution in Javascript

```javascript
class MyCalendarThree {
    constructor() {
        this.timeline = new Map();
    }

    book(start, end) {
        this.timeline.set(start, (this.timeline.get(start) || 0) + 1);
        this.timeline.set(end, (this.timeline.get(end) || 0) - 1);
        let ongoing = 0, k = 0;
        for (const value of this.timeline.values()) {
            k = Math.max(k, ongoing += value);
        }
        return k;
    }
}
```
The algorithm maintains a timeline, which is a data structure that stores events with their start and end times. For each booking, we increase the value at the start time by 1 and decrease the value at the end time by 1 in the timeline.

After updating the timeline, we iterate over its values and keep track of the ongoing events count. By getting the maximum value of the ongoing events count, we can determine the maximum k-booking.

In C++, we use a `std::map<int, int>` to store the timeline events, while in Java, we use `TreeMap<Integer, Integer>`. In Python, we use a `collections.defaultdict(int)` to store the timeline events, and in JavaScript, we use a `Map()`.

The time complexity of the algorithm is O(N * log N) due to sorting for time (start and end) in the timeline data structure. The space complexity is O(N) to store the timeline events where N is the number of events.


# Flood Fill

- slug: flood-fill
- difficulty: Easy

An image is represented by an `m x n` integer grid `image` where `image[i][j]` represents the pixel value of the image.

You are also given three integers `sr`, `sc`, and `color`. You should perform a **flood fill** on the image starting from the pixel `image[sr][sc]`.

To perform a **flood fill**, consider the starting pixel, plus any pixels connected **4-directionally** to the starting pixel of the same color as the starting pixel, plus any pixels connected **4-directionally** to those pixels (also with the same color), and so on. Replace the color of all of the aforementioned pixels with `color`.

Return _the modified image after performing the flood fill_.

**Example 1:**

**Input:** image = \[\[1,1,1\],\[1,1,0\],\[1,0,1\]\], sr = 1, sc = 1, color = 2
**Output:** \[\[2,2,2\],\[2,2,0\],\[2,0,1\]\]
**Explanation:** From the center of the image with position (sr, sc) = (1, 1) (i.e., the red pixel), all pixels connected by a path of the same color as the starting pixel (i.e., the blue pixels) are colored with the new color.
Note the bottom corner is not colored 2, because it is not 4-directionally connected to the starting pixel.

**Example 2:**

**Input:** image = \[\[0,0,0\],\[0,0,0\]\], sr = 0, sc = 0, color = 0
**Output:** \[\[0,0,0\],\[0,0,0\]\]
**Explanation:** The starting pixel is already colored 0, so no changes are made to the image.

**Constraints:**

*   `m == image.length`
*   `n == image[i].length`
*   `1 <= m, n <= 50`
*   `0 <= image[i][j], color < 216`
*   `0 <= sr < m`
*   `0 <= sc < n`

## A solution in Java

```java
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
    int startColor = image[sr][sc];
    fill(image, sr, sc, newColor, startColor);
    return image;
}

private void fill(int[][] image, int sr, int sc, int newColor, int startColor) {
    if (sr < 0 || sc < 0 || sr >= image.length || sc >= image[0].length || image[sr][sc] != startColor || image[sr][sc] == newColor) return;
    image[sr][sc] = newColor;
    fill(image, sr - 1, sc, newColor, startColor);
    fill(image, sr + 1, sc, newColor, startColor);
    fill(image, sr, sc - 1, newColor, startColor);
    fill(image, sr, sc + 1, newColor, startColor);
}
```
To implement the flood-fill algorithm, we create a `fill` function that receives the image, the target position, the new color, and the starting color. It is not necessary to pass the image every time, because it's mutable, but we require the other parameters each time. We then check if the current position is out of bounds or if the current pixel color at the position is not the same as the starting color or if the current pixel color is equal to the new color. If any of these conditions are met, we return without modifying the image. Otherwise, we set the color of the current pixel to the new color and call `fill` function recursively for each adjacent 4-directionally connected pixel. The main function first sets the `startColor` as the color of the pixel image[sr][sc] and then executes the `fill` function with `sr`, `sc`, `newColor`, and `startColor`. Finally, the modified image is returned.

## A solution in C++

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

void fill(vector<vector<int>>& image, int sr, int sc, int newColor, int startColor) {
    if (sr < 0 || sc < 0 || sr >= image.size() || sc >= image[0].size() || image[sr][sc] != startColor || image[sr][sc] == newColor) return;
    image[sr][sc] = newColor;
    fill(image, sr - 1, sc, newColor, startColor);
    fill(image, sr + 1, sc, newColor, startColor);
    fill(image, sr, sc - 1, newColor, startColor);
    fill(image, sr, sc + 1, newColor, startColor);
}

vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
    int startColor = image[sr][sc];
    fill(image, sr, sc, newColor, startColor);
    return image;
}
```
To implement the flood-fill algorithm, we create a `fill` function that receives the image, the target position, the new color, and the starting color. It is not necessary to pass the image every time, because it's mutable, but we require the other parameters each time. We then check if the current position is out of bounds or if the current pixel color at the position is not the same as the starting color or if the current pixel color is equal to the new color. If any of these conditions are met, we return without modifying the image. Otherwise, we set the color of the current pixel to the new color and call `fill` function recursively for each adjacent 4-directionally connected pixel. The main function first sets the `startColor` as the color of the pixel image[sr][sc] and then executes the `fill` function with `sr`, `sc`, `newColor`, and `startColor`. Finally, the modified image is returned.

## A solution in Python

```python
def floodFill(image, sr, sc, newColor):
    startColor = image[sr][sc]
    def fill(sr, sc):
        if not (0 <= sr < len(image)) or not (0 <= sc < len(image[0])) or image[sr][sc] != startColor or image[sr][sc] == newColor:
            return
        image[sr][sc] = newColor
        fill(sr - 1, sc)
        fill(sr + 1, sc)
        fill(sr, sc - 1)
        fill(sr, sc + 1)

    fill(sr, sc)
    return image
```
To implement the flood-fill algorithm, we create a `fill` function that receives the image, the target position, the new color, and the starting color. It is not necessary to pass the image every time, because it's mutable, but we require the other parameters each time. We then check if the current position is out of bounds or if the current pixel color at the position is not the same as the starting color or if the current pixel color is equal to the new color. If any of these conditions are met, we return without modifying the image. Otherwise, we set the color of the current pixel to the new color and call `fill` function recursively for each adjacent 4-directionally connected pixel. The main function first sets the `startColor` as the color of the pixel image[sr][sc] and then executes the `fill` function with `sr`, `sc`, `newColor`, and `startColor`. Finally, the modified image is returned.

## A solution in Javascript

```javascript
function floodFill(image, sr, sc, newColor) {
    let startColor = image[sr][sc];
    function fill(sr, sc) {
        if (sr < 0 || sc < 0 || sr >= image.length || sc >= image[0].length || image[sr][sc] !== startColor || image[sr][sc] === newColor) return;
        image[sr][sc] = newColor;
        fill(sr - 1, sc);
        fill(sr + 1, sc);
        fill(sr, sc - 1);
        fill(sr, sc + 1);
    }
    fill(sr, sc);
    return image;
}
```
To implement the flood-fill algorithm, we create a `fill` function that receives the image, the target position, the new color, and the starting color. It is not necessary to pass the image every time, because it's mutable, but we require the other parameters each time. We then check if the current position is out of bounds or if the current pixel color at the position is not the same as the starting color or if the current pixel color is equal to the new color. If any of these conditions are met, we return without modifying the image. Otherwise, we set the color of the current pixel to the new color and call `fill` function recursively for each adjacent 4-directionally connected pixel. The main function first sets the `startColor` as the color of the pixel image[sr][sc] and then executes the `fill` function with `sr`, `sc`, `newColor`, and `startColor`. Finally, the modified image is returned.


# Sentence Similarity

- slug: sentence-similarity
- difficulty: Easy

We can represent a sentence as an array of words, for example, the sentence `"I am happy with leetcode "` can be represented as `arr = [ "I ", "am ",happy ", "with ", "leetcode "]`.

Given two sentences `sentence1` and `sentence2` each represented as a string array and given an array of string pairs `similarPairs` where `similarPairs[i] = [xi, yi]` indicates that the two words `xi` and `yi` are similar.

Return _`true` if `sentence1` and `sentence2` are similar, or `false` if they are not similar_.

Two sentences are similar if:

*   They have **the same length** (i.e., the same number of words)
*   `sentence1[i]` and `sentence2[i]` are similar.

Notice that a word is always similar to itself, also notice that the similarity relation is not transitive. For example, if the words `a` and `b` are similar, and the words `b` and `c` are similar, `a` and `c` are **not necessarily similar**.

**Example 1:**

**Input:** sentence1 = \[ "great ", "acting ", "skills "\], sentence2 = \[ "fine ", "drama ", "talent "\], similarPairs = \[\[ "great ", "fine "\],\[ "drama ", "acting "\],\[ "skills ", "talent "\]\]
**Output:** true
**Explanation:** The two sentences have the same length and each word i of sentence1 is also similar to the corresponding word in sentence2.

**Example 2:**

**Input:** sentence1 = \[ "great "\], sentence2 = \[ "great "\], similarPairs = \[\]
**Output:** true
**Explanation:** A word is similar to itself.

**Example 3:**

**Input:** sentence1 = \[ "great "\], sentence2 = \[ "doubleplus ", "good "\], similarPairs = \[\[ "great ", "doubleplus "\]\]
**Output:** false
**Explanation:** As they don't have the same length, we return false.

**Constraints:**

*   `1 <= sentence1.length, sentence2.length <= 1000`
*   `1 <= sentence1[i].length, sentence2[i].length <= 20`
*   `sentence1[i]` and `sentence2[i]` consist of English letters.
*   `0 <= similarPairs.length <= 1000`
*   `similarPairs[i].length == 2`
*   `1 <= xi.length, yi.length <= 20`
*   `xi` and `yi` consist of lower-case and upper-case English letters.
*   All the pairs `(xi, yi)` are **distinct**.

## A solution in Java

```java
import java.util.*;

public boolean areSentencesSimilar(String[] sentence1, String[] sentence2, List<List<String>> similarPairs) {
    if (sentence1.length != sentence2.length) return false;
    Map<String, Set<String>> similarityMap = new HashMap<>();
    for (List<String> pair : similarPairs) {
        similarityMap.putIfAbsent(pair.get(0), new HashSet<>());
        similarityMap.putIfAbsent(pair.get(1), new HashSet<>());
        similarityMap.get(pair.get(0)).add(pair.get(1));
        similarityMap.get(pair.get(1)).add(pair.get(0));
    }
    for (int i = 0; i < sentence1.length; ++i) {
        if (!sentence1[i].equals(sentence2[i]) && !similarityMap.getOrDefault(sentence1[i], Collections.emptySet()).contains(sentence2[i]))
            return false;
    }
    return true;
}
```
1. If the lengths of the given sentences are unequal, the sentences cannot be similar, hence return false.
2. Create a mapping from each word in similarPairs to its set of similar words.
3. Iterate over each word in both sentences and check whether they are similar. If not, return false.
4. If all words in sentence1 are similar to words at same indices in sentence2, return true.

## A solution in C++

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

bool areSentencesSimilar(vector<string>& sentence1, vector<string>& sentence2, vector<vector<string>>& similarPairs) {
    if (sentence1.size() != sentence2.size()) return false;
    unordered_map<string, unordered_set<string>> similarityMap;
    for (const auto& pair : similarPairs) {
        similarityMap[pair[0]].insert(pair[1]);
        similarityMap[pair[1]].insert(pair[0]);
    }
    for (int i = 0; i < sentence1.size(); ++i) {
        if (sentence1[i] != sentence2[i] && !similarityMap[sentence1[i]].count(sentence2[i]))
            return false;
    }
    return true;
}
```
1. If the lengths of the given sentences are unequal, the sentences cannot be similar, hence return false.
2. Create a mapping from each word in similarPairs to its set of similar words.
3. Iterate over each word in both sentences and check whether they are similar. If not, return false.
4. If all words in sentence1 are similar to words at same indices in sentence2, return true.

## A solution in Python

```python
from collections import defaultdict

def areSentencesSimilar(sentence1, sentence2, similarPairs):
    if len(sentence1) != len(sentence2): return False
    similarityMap = defaultdict(set)
    for pair in similarPairs:
        similarityMap[pair[0]].add(pair[1])
        similarityMap[pair[1]].add(pair[0])
    for i in range(len(sentence1)):
        if sentence1[i] != sentence2[i] and sentence2[i] not in similarityMap[sentence1[i]]:
            return False
    return True
```
1. If the lengths of the given sentences are unequal, the sentences cannot be similar, hence return false.
2. Create a mapping from each word in similarPairs to its set of similar words.
3. Iterate over each word in both sentences and check whether they are similar. If not, return false.
4. If all words in sentence1 are similar to words at same indices in sentence2, return true.

## A solution in Javascript

```javascript
function areSentencesSimilar(sentence1, sentence2, similarPairs) {
    if (sentence1.length !== sentence2.length) return false;
    const similarityMap = new Map();
    for (const pair of similarPairs) {
        if (!similarityMap.has(pair[0])) similarityMap.set(pair[0], new Set());
        if (!similarityMap.has(pair[1])) similarityMap.set(pair[1], new Set());
        similarityMap.get(pair[0]).add(pair[1]);
        similarityMap.get(pair[1]).add(pair[0]);
    }
    for (let i = 0; i < sentence1.length; ++i) {
        if (sentence1[i] !== sentence2[i] && !similarityMap.get(sentence1[i])?.has(sentence2[i]))
            return false;
    }
    return true;
}
```
1. If the lengths of the given sentences are unequal, the sentences cannot be similar, hence return false.
2. Create a mapping from each word in similarPairs to its set of similar words.
3. Iterate over each word in both sentences and check whether they are similar. If not, return false.
4. If all words in sentence1 are similar to words at same indices in sentence2, return true.


# Asteroid Collision

- slug: asteroid-collision
- difficulty: Medium

We are given an array `asteroids` of integers representing asteroids in a row.

For each asteroid, the absolute value represents its size, and the sign represents its direction (positive meaning right, negative meaning left). Each asteroid moves at the same speed.

Find out the state of the asteroids after all collisions. If two asteroids meet, the smaller one will explode. If both are the same size, both will explode. Two asteroids moving in the same direction will never meet.

**Example 1:**

**Input:** asteroids = \[5,10,-5\]
**Output:** \[5,10\]
**Explanation:** The 10 and -5 collide resulting in 10. The 5 and 10 never collide.

**Example 2:**

**Input:** asteroids = \[8,-8\]
**Output:** \[\]
**Explanation:** The 8 and -8 collide exploding each other.

**Example 3:**

**Input:** asteroids = \[10,2,-5\]
**Output:** \[10\]
**Explanation:** The 2 and -5 collide resulting in -5. The 10 and -5 collide resulting in 10.

**Constraints:**

*   `2 <= asteroids.length <= 104`
*   `-1000 <= asteroids[i] <= 1000`
*   `asteroids[i] != 0`

## A solution in Java

```java
import java.util.*;
class Solution {
    public int[] asteroidCollision(int[] asteroids) {
        Stack<Integer> s = new Stack<>();
        for (int i = 0; i < asteroids.length; i++) {
            if (asteroids[i] > 0 || s.isEmpty() || s.peek() < 0) {
                s.push(asteroids[i]);
            } else if (s.peek() <= -asteroids[i]) {
                if (s.peek() < -asteroids[i]) i--;
                s.pop();
            }
        }
        int[] ans = new int[s.size()];
        for (int i = ans.length - 1; i >= 0; i--) {
            ans[i] = s.pop();
        }
        return ans;
    }
}
```
The algorithm uses a stack data structure to track the asteroids. For each asteroid, if it is moving to the right, or if the stack is empty, or if the top of the stack has an asteroid with a negative value (moving left), then we can simply push the current asteroid onto the stack.

If the top of the stack has an asteroid with a positive value and the current asteroid has a negative value (meaning they will collide), compare their absolute values. If the top of the stack has a smaller value, decrement the iterator and pop the stack, so that the current asteroid will be considered again. If both have the same value, simply pop the stack without decrementing the iterator. Otherwise, if the top of the stack has a larger value, ignore the current asteroid, and proceed to the next asteroid.

The final stack will have the remaining asteroids after all the collisions. In the case of Java, the stack is converted to an array before returning the result.

## A solution in C++

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

vector<int> asteroidCollision(vector<int>& asteroids) {
    vector<int> s;
    for (int i = 0; i < asteroids.size(); i++) {
        if (asteroids[i] > 0 || s.empty() || s.back() < 0) {
            s.push_back(asteroids[i]);
        } else if (s.back() <= -asteroids[i]) {
            if (s.back() < -asteroids[i]) i--;
            s.pop_back();
        }
    }
    return s;
}
```
The algorithm uses a stack data structure to track the asteroids. For each asteroid, if it is moving to the right, or if the stack is empty, or if the top of the stack has an asteroid with a negative value (moving left), then we can simply push the current asteroid onto the stack.

If the top of the stack has an asteroid with a positive value and the current asteroid has a negative value (meaning they will collide), compare their absolute values. If the top of the stack has a smaller value, decrement the iterator and pop the stack, so that the current asteroid will be considered again. If both have the same value, simply pop the stack without decrementing the iterator. Otherwise, if the top of the stack has a larger value, ignore the current asteroid, and proceed to the next asteroid.

The final stack will have the remaining asteroids after all the collisions. In the case of Java, the stack is converted to an array before returning the result.

## A solution in Python

```python
def asteroidCollision(asteroids):
    s = []
    for num in asteroids:
        if num > 0 or not s or s[-1] < 0:
            s.append(num)
        elif s[-1] <= -num:
            if s[-1] < -num:
                s.pop()
                s.append(num)
            else:
                s.pop()
    return s
```
The algorithm uses a stack data structure to track the asteroids. For each asteroid, if it is moving to the right, or if the stack is empty, or if the top of the stack has an asteroid with a negative value (moving left), then we can simply push the current asteroid onto the stack.

If the top of the stack has an asteroid with a positive value and the current asteroid has a negative value (meaning they will collide), compare their absolute values. If the top of the stack has a smaller value, decrement the iterator and pop the stack, so that the current asteroid will be considered again. If both have the same value, simply pop the stack without decrementing the iterator. Otherwise, if the top of the stack has a larger value, ignore the current asteroid, and proceed to the next asteroid.

The final stack will have the remaining asteroids after all the collisions. In the case of Java, the stack is converted to an array before returning the result.

## A solution in Javascript

```javascript
function asteroidCollision(asteroids) {
    const s = [];
    for (let i = 0; i < asteroids.length; i++) {
        if (asteroids[i] > 0 || !s.length || s[s.length - 1] < 0) {
            s.push(asteroids[i]);
        } else if (s[s.length - 1] <= -asteroids[i]) {
            if (s[s.length - 1] < -asteroids[i]) i--;
            s.pop();
        }
    }
    return s;
}
```
The algorithm uses a stack data structure to track the asteroids. For each asteroid, if it is moving to the right, or if the stack is empty, or if the top of the stack has an asteroid with a negative value (moving left), then we can simply push the current asteroid onto the stack.

If the top of the stack has an asteroid with a positive value and the current asteroid has a negative value (meaning they will collide), compare their absolute values. If the top of the stack has a smaller value, decrement the iterator and pop the stack, so that the current asteroid will be considered again. If both have the same value, simply pop the stack without decrementing the iterator. Otherwise, if the top of the stack has a larger value, ignore the current asteroid, and proceed to the next asteroid.

The final stack will have the remaining asteroids after all the collisions. In the case of Java, the stack is converted to an array before returning the result.