# Amount of Time for Binary Tree to Be Infected

- slug: amount-of-time-for-binary-tree-to-be-infected
- difficulty: Medium

You are given the `root` of a binary tree with **unique** values, and an integer `start`. At minute `0`, an **infection** starts from the node with value `start`.

Each minute, a node becomes infected if:

*   The node is currently uninfected.
*   The node is adjacent to an infected node.

Return _the number of minutes needed for the entire tree to be infected._

**Example 1:**

**Input:** root = \[1,5,3,null,4,10,6,9,2\], start = 3
**Output:** 4
**Explanation:** The following nodes are infected during:
- Minute 0: Node 3
- Minute 1: Nodes 1, 10 and 6
- Minute 2: Node 5
- Minute 3: Node 4
- Minute 4: Nodes 9 and 2
It takes 4 minutes for the whole tree to be infected so we return 4.

**Example 2:**

**Input:** root = \[1\], start = 1
**Output:** 0
**Explanation:** At minute 0, the only node in the tree is infected so we return 0.

**Constraints:**

*   The number of nodes in the tree is in the range `[1, 105]`.
*   `1 <= Node.val <= 105`
*   Each node has a **unique** value.
*   A node with a value of `start` exists in the tree.

## A solution in Java

```java
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode() {}
    TreeNode(int val) { this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

int timeToInfect(TreeNode node, int start, int minutes) {
    if (node == null) return 0;
    if (node.val == start) return minutes;
    return Math.max(timeToInfect(node.left, start, minutes+1),
                    timeToInfect(node.right, start, minutes+1));
}

int totalInfectionTime(TreeNode root, int total_minutes) {
    if (root == null) return total_minutes;
    int time_needed = Math.max(Math.max(total_minutes,
                                  timeToInfect(root, root.val, 0)),
               Math.max(totalInfectionTime(root.left, total_minutes + 1),
                        totalInfectionTime(root.right, total_minutes + 1)));
    return time_needed;
}
```
The function has a two part process. First, we have the function `timeToInfect` which gets the time needed to infect a given node. The function traverses the tree recursively trying to find the infected node in either its left or right child. If the node is found, its minutes value would be returned; if not found, it'd return 0.

The second part of the process is the `totalInfectionTime` function which calculates the required time to infect the entire tree. Similar to `timeToInfect`, it traverses the tree recursively, but for each node, it computes the maximum time required to infect that node. This ensures that the function returns the exact time required to infect the entire tree.

It starts with the root node and checks if the tree is empty or not. If it's empty, it returns 0 directly. Otherwise, it computes the maximum of four values: the current value of `total_minutes`, the time needed to infect the root, the time needed to infect the left subtree, and the time needed to infect the right subtree.

This algorithm would repeat the process for each node in the tree and return the maximum time required to infect the entire tree.

## A solution in C++

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

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

int timeToInfect(TreeNode* node, int start, int minutes) {
    if (!node) return 0;
    if (node->val == start) return minutes;
    return max(timeToInfect(node->left, start, minutes+1),
               timeToInfect(node->right, start, minutes+1));
}

int totalInfectionTime(TreeNode* root, int total_minutes = 0) {
    if (!root) return total_minutes;
    int time_needed = max({total_minutes,
                           timeToInfect(root, root->val, 0),
                           totalInfectionTime(root->left, total_minutes + 1),
                           totalInfectionTime(root->right, total_minutes + 1)});
    return time_needed;
}
```
The function has a two part process. First, we have the function `timeToInfect` which gets the time needed to infect a given node. The function traverses the tree recursively trying to find the infected node in either its left or right child. If the node is found, its minutes value would be returned; if not found, it'd return 0.

The second part of the process is the `totalInfectionTime` function which calculates the required time to infect the entire tree. Similar to `timeToInfect`, it traverses the tree recursively, but for each node, it computes the maximum time required to infect that node. This ensures that the function returns the exact time required to infect the entire tree.

It starts with the root node and checks if the tree is empty or not. If it's empty, it returns 0 directly. Otherwise, it computes the maximum of four values: the current value of `total_minutes`, the time needed to infect the root, the time needed to infect the left subtree, and the time needed to infect the right subtree.

This algorithm would repeat the process for each node in the tree and return the maximum time required to infect the entire tree.

## A solution in Python

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

def time_to_infect(node, start, minutes):
    if not node:
        return 0
    if node.val == start:
        return minutes
    return max(time_to_infect(node.left, start, minutes+1),
               time_to_infect(node.right, start, minutes+1))

def total_infection_time(root, total_minutes=0):
    if not root:
        return total_minutes
    time_needed = max(total_minutes,
                      time_to_infect(root, root.val, 0),
                      total_infection_time(root.left, total_minutes + 1),
                      total_infection_time(root.right, total_minutes + 1))
    return time_needed
```
The function has a two part process. First, we have the function `timeToInfect` which gets the time needed to infect a given node. The function traverses the tree recursively trying to find the infected node in either its left or right child. If the node is found, its minutes value would be returned; if not found, it'd return 0.

The second part of the process is the `totalInfectionTime` function which calculates the required time to infect the entire tree. Similar to `timeToInfect`, it traverses the tree recursively, but for each node, it computes the maximum time required to infect that node. This ensures that the function returns the exact time required to infect the entire tree.

It starts with the root node and checks if the tree is empty or not. If it's empty, it returns 0 directly. Otherwise, it computes the maximum of four values: the current value of `total_minutes`, the time needed to infect the root, the time needed to infect the left subtree, and the time needed to infect the right subtree.

This algorithm would repeat the process for each node in the tree and return the maximum time required to infect the entire tree.

## A solution in Javascript

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

function timeToInfect(node, start, minutes) {
    if (node === null) return 0;
    if (node.val === start) return minutes;
    return Math.max(timeToInfect(node.left, start, minutes+1),
                    timeToInfect(node.right, start, minutes+1));
}

function totalInfectionTime(root, total_minutes=0) {
    if (root === null) return total_minutes;
    let time_needed = Math.max(total_minutes,
                              timeToInfect(root, root.val, 0),
                              totalInfectionTime(root.left, total_minutes + 1),
                              totalInfectionTime(root.right, total_minutes + 1));
    return time_needed;
}
```
The function has a two part process. First, we have the function `timeToInfect` which gets the time needed to infect a given node. The function traverses the tree recursively trying to find the infected node in either its left or right child. If the node is found, its minutes value would be returned; if not found, it'd return 0.

The second part of the process is the `totalInfectionTime` function which calculates the required time to infect the entire tree. Similar to `timeToInfect`, it traverses the tree recursively, but for each node, it computes the maximum time required to infect that node. This ensures that the function returns the exact time required to infect the entire tree.

It starts with the root node and checks if the tree is empty or not. If it's empty, it returns 0 directly. Otherwise, it computes the maximum of four values: the current value of `total_minutes`, the time needed to infect the root, the time needed to infect the left subtree, and the time needed to infect the right subtree.

This algorithm would repeat the process for each node in the tree and return the maximum time required to infect the entire tree.


# Find the K-Sum of an Array

- slug: find-the-k-sum-of-an-array
- difficulty: Hard

You are given an integer array `nums` and a **positive** integer `k`. You can choose any **subsequence** of the array and sum all of its elements together.

We define the **K-Sum** of the array as the `kth` **largest** subsequence sum that can be obtained (**not** necessarily distinct).

Return _the K-Sum of the array_.

A **subsequence** is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.

**Note** that the empty subsequence is considered to have a sum of `0`.

**Example 1:**

**Input:** nums = \[2,4,-2\], k = 5
**Output:** 2
**Explanation:** All the possible subsequence sums that we can obtain are the following sorted in decreasing order:
- 6, 4, 4, 2, 2, 0, 0, -2.
The 5-Sum of the array is 2.

**Example 2:**

**Input:** nums = \[1,-2,3,4,-10,12\], k = 16
**Output:** 10
**Explanation:** The 16-Sum of the array is 10.

**Constraints:**

*   `n == nums.length`
*   `1 <= n <= 105`
*   `-109 <= nums[i] <= 109`
*   `1 <= k <= min(2000, 2n)`

## A solution in Java

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

public class Solution {
    public int kSum(int[] nums, int k) {
        ArrayList<Integer> sums = new ArrayList<>();
        sums.add(0);
        for (int num : nums) {
            if (num > 0) {
                for (int i = sums.size() - 1; i >= 0; i--) {
                    sums.add(sums.get(i) + num);
                }
                sums.sort(Collections.reverseOrder());
            } else {
                sums.add(num);
            }
        }

        return sums.get(k - 1);
    }
}
```
To calculate the K-Sum, we need a list of all the sums of max subsequences that can be obtained. The code creates a list `sums` initialized with only one element (0). We iterate over the input `nums`. For each positive number `num`, we add another sum by summing up `num` with every sum that's already in the list `sums`. If the input number is non-positive, we simply append it to the list `sums`. After each iteartion, the list `sums` is sorted in decreasing order to keep track of the largest sum(s) possible. After the process is done, the result is the `k-th` element in the list of `sums` (1-indexed).

## A solution in C++

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

using namespace std;

int kSum(vector<int>& nums, int k) {
    vector<int> sums{0};
    for (int num : nums) {
        if (num > 0) {
            for (int i = sums.size() - 1; i >= 0; --i) {
                sums.push_back(sums[i] + num);
            }
            sort(sums.rbegin(), sums.rend());
        } else {
            sums.push_back(num);
        }
    }

    return sums[k - 1];
}
```
To calculate the K-Sum, we need a list of all the sums of max subsequences that can be obtained. The code creates a list `sums` initialized with only one element (0). We iterate over the input `nums`. For each positive number `num`, we add another sum by summing up `num` with every sum that's already in the list `sums`. If the input number is non-positive, we simply append it to the list `sums`. After each iteartion, the list `sums` is sorted in decreasing order to keep track of the largest sum(s) possible. After the process is done, the result is the `k-th` element in the list of `sums` (1-indexed).

## A solution in Python

```python
def kSum(nums, k):
    sums = [0]
    for num in nums:
        if num > 0:
            sums.extend([s + num for s in sums])
            sums.sort(reverse=True)
        else:
            sums.append(num)

    return sums[k - 1]
```
To calculate the K-Sum, we need a list of all the sums of max subsequences that can be obtained. The code creates a list `sums` initialized with only one element (0). We iterate over the input `nums`. For each positive number `num`, we add another sum by summing up `num` with every sum that's already in the list `sums`. If the input number is non-positive, we simply append it to the list `sums`. After each iteartion, the list `sums` is sorted in decreasing order to keep track of the largest sum(s) possible. After the process is done, the result is the `k-th` element in the list of `sums` (1-indexed).

## A solution in Javascript

```javascript
function kSum(nums, k) {
    const sums = [0];
    for (const num of nums) {
        if (num > 0) {
            for (let i = sums.length - 1; i >= 0; i--) {
                sums.push(sums[i] + num);
            }
            sums.sort((a, b) => b - a);
        } else {
            sums.push(num);
        }
    }

    return sums[k - 1];
}
```
To calculate the K-Sum, we need a list of all the sums of max subsequences that can be obtained. The code creates a list `sums` initialized with only one element (0). We iterate over the input `nums`. For each positive number `num`, we add another sum by summing up `num` with every sum that's already in the list `sums`. If the input number is non-positive, we simply append it to the list `sums`. After each iteartion, the list `sums` is sorted in decreasing order to keep track of the largest sum(s) possible. After the process is done, the result is the `k-th` element in the list of `sums` (1-indexed).


# Median of a Row Wise Sorted Matrix

- slug: median-of-a-row-wise-sorted-matrix
- difficulty: Medium

Given an `m x n` matrix `grid` containing an **odd** number of integers where each row is sorted in **non-decreasing** order, return _the **median** of the matrix_.

You must solve the problem in less than `O(m * n)` time complexity.

**Example 1:**

**Input:** grid = \[\[1,1,2\],\[2,3,3\],\[1,3,4\]\]
**Output:** 2
**Explanation:** The elements of the matrix in sorted order are 1,1,1,2,2,3,3,3,4. The median is 2.

**Example 2:**

**Input:** grid = \[\[1,1,3,3,4\]\]
**Output:** 3
**Explanation:** The elements of the matrix in sorted order are 1,1,3,3,4. The median is 3.

**Constraints:**

*   `m == grid.length`
*   `n == grid[i].length`
*   `1 <= m, n <= 500`
*   `m` and `n` are both odd.
*   `1 <= grid[i][j] <= 106`
*   `grid[i]` is sorted in non-decreasing order.

## A solution in Java

```java
public int findMedian(int[][] grid) {
    int m = grid.length, n = grid[0].length;
    int low = 1, high = 1000000;

    while (low < high) {
        int mid = low + (high - low) / 2;
        int count = 0;
        for (int i = 0; i < m; ++i) {
            count += countElements(grid[i], mid);
        }

        if (count < (m * n) / 2 + 1) {
            low = mid + 1;
        } else {
            high = mid;
        }
    }

    return low;
}

private int countElements(int[] row, int value) {
    int left = 0, right = row.length;

    while (left < right) {
        int mid = left + (right - left) / 2;

        if (row[mid] <= value) {
            left = mid + 1;
        } else {
            right = mid;
        }
    }

    return left;
}
```
The algorithm uses binary search to find the median in less than O(m * n) time complexity. We start by defining the search bounds with `low` and `high`. Then, we perform a binary search by selecting a `mid` value between `low` and `high`. For each `mid`, we count the elements that are less than or equal to `mid` using the `upper_bound` or `countElements` functions depending on the language.

We then compare the count with the target count - which is `(m * n) / 2 + 1`, as the matrix is guaranteed to have an odd number of elements. If the count is less than the target count, it means that our current `mid` value is too small, so we update `low` to `mid + 1`. Otherwise, our `mid` value is a candidate for the median, so we update `high` to `mid`.

We continue the iteration until the `low` pointer is equal to the `high` pointer, at which point we have found the median of the matrix, and we return the `low` pointer value.

## A solution in C++

```cpp
int findMedian(vector<vector<int>>& grid) {
    int m = grid.size(), n = grid[0].size();
    int low = 1, high = 1e6;

    while (low < high) {
        int mid = low + (high - low) / 2;
        int count = 0;
        for (int i = 0; i < m; ++i) {
            count += upper_bound(grid[i].begin(), grid[i].end(), mid) - grid[i].begin();
        }

        if (count < (m * n) / 2 + 1) {
            low = mid + 1;
        } else {
            high = mid;
        }
    }

    return low;
}
```
The algorithm uses binary search to find the median in less than O(m * n) time complexity. We start by defining the search bounds with `low` and `high`. Then, we perform a binary search by selecting a `mid` value between `low` and `high`. For each `mid`, we count the elements that are less than or equal to `mid` using the `upper_bound` or `countElements` functions depending on the language.

We then compare the count with the target count - which is `(m * n) / 2 + 1`, as the matrix is guaranteed to have an odd number of elements. If the count is less than the target count, it means that our current `mid` value is too small, so we update `low` to `mid + 1`. Otherwise, our `mid` value is a candidate for the median, so we update `high` to `mid`.

We continue the iteration until the `low` pointer is equal to the `high` pointer, at which point we have found the median of the matrix, and we return the `low` pointer value.

## A solution in Python

```python
def findMedian(grid: List[List[int]]) -> int:
    m, n = len(grid), len(grid[0])
    low, high = 1, 1_000_000

    while low < high:
        mid = low + (high - low) // 2
        count = sum(bisect_right(row, mid) for row in grid)

        if count < (m * n) // 2 + 1:
            low = mid + 1
        else:
            high = mid

    return low
```
The algorithm uses binary search to find the median in less than O(m * n) time complexity. We start by defining the search bounds with `low` and `high`. Then, we perform a binary search by selecting a `mid` value between `low` and `high`. For each `mid`, we count the elements that are less than or equal to `mid` using the `upper_bound` or `countElements` functions depending on the language.

We then compare the count with the target count - which is `(m * n) / 2 + 1`, as the matrix is guaranteed to have an odd number of elements. If the count is less than the target count, it means that our current `mid` value is too small, so we update `low` to `mid + 1`. Otherwise, our `mid` value is a candidate for the median, so we update `high` to `mid`.

We continue the iteration until the `low` pointer is equal to the `high` pointer, at which point we have found the median of the matrix, and we return the `low` pointer value.

## A solution in Javascript

```javascript
function findMedian(grid) {
    const m = grid.length, n = grid[0].length;
    let low = 1, high = 1e6;

    while (low < high) {
        const mid = low + ((high - low) >> 1);
        let count = 0;
        for (let i = 0; i < m; ++i) {
            count += countElements(grid[i], mid);
        }

        if (count < ((m * n) >> 1) + 1) {
            low = mid + 1;
        } else {
            high = mid;
        }
    }

    return low;
}

function countElements(row, value) {
    let left = 0, right = row.length;

    while (left < right) {
        const mid = left + ((right - left) >> 1);

        if (row[mid] <= value) {
            left = mid + 1;
        } else {
            right = mid;
        }
    }

    return left;
}
```
The algorithm uses binary search to find the median in less than O(m * n) time complexity. We start by defining the search bounds with `low` and `high`. Then, we perform a binary search by selecting a `mid` value between `low` and `high`. For each `mid`, we count the elements that are less than or equal to `mid` using the `upper_bound` or `countElements` functions depending on the language.

We then compare the count with the target count - which is `(m * n) / 2 + 1`, as the matrix is guaranteed to have an odd number of elements. If the count is less than the target count, it means that our current `mid` value is too small, so we update `low` to `mid + 1`. Otherwise, our `mid` value is a candidate for the median, so we update `high` to `mid`.

We continue the iteration until the `low` pointer is equal to the `high` pointer, at which point we have found the median of the matrix, and we return the `low` pointer value.


# Longest Subsequence With Limited Sum

- slug: longest-subsequence-with-limited-sum
- difficulty: Easy

You are given an integer array `nums` of length `n`, and an integer array `queries` of length `m`.

Return _an array_ `answer` _of length_ `m` _where_ `answer[i]` _is the **maximum** size of a **subsequence** that you can take from_ `nums` _such that the **sum** of its elements is less than or equal to_ `queries[i]`.

A **subsequence** is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.

**Example 1:**

**Input:** nums = \[4,5,2,1\], queries = \[3,10,21\]
**Output:** \[2,3,4\]
**Explanation:** We answer the queries as follows:
- The subsequence \[2,1\] has a sum less than or equal to 3. It can be proven that 2 is the maximum size of such a subsequence, so answer\[0\] = 2.
- The subsequence \[4,5,1\] has a sum less than or equal to 10. It can be proven that 3 is the maximum size of such a subsequence, so answer\[1\] = 3.
- The subsequence \[4,5,2,1\] has a sum less than or equal to 21. It can be proven that 4 is the maximum size of such a subsequence, so answer\[2\] = 4.

**Example 2:**

**Input:** nums = \[2,3,4,5\], queries = \[1\]
**Output:** \[0\]
**Explanation:** The empty subsequence is the only subsequence that has a sum less than or equal to 1, so answer\[0\] = 0.

**Constraints:**

*   `n == nums.length`
*   `m == queries.length`
*   `1 <= n, m <= 1000`
*   `1 <= nums[i], queries[i] <= 106`

## A solution in Java

```java
import java.util.Arrays;

public int[] maxSizeSubsequenceSumQueries(int[] nums, int[] queries) {
    Arrays.sort(nums);
    int[] prefixSums = new int[nums.length + 1];
    for (int i = 0; i < nums.length; ++i) {
        prefixSums[i + 1] = prefixSums[i] + nums[i];
    }

    int[] answer = new int[queries.length];
    for (int i = 0; i < queries.length; ++i) {
        int idx = Arrays.binarySearch(prefixSums, queries[i]);
        if (idx < 0) {
            idx = -idx - 1;
        }
        answer[i] = idx - 1;
    }

    return answer;
}
```
The algorithm sorts the `nums` array in ascending order, then calculates the prefix sums for easy sum checks. For each query, it finds the position for the query in the prefix sums array using binary search, and the index of that position minus one represents the maximum size of a subsequence whose sum is less than or equal to the query. It adds that value to the answer array.

## A solution in C++

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

std::vector<int> maxSizeSubsequenceSumQueries(std::vector<int>& nums, std::vector<int>& queries) {
    std::sort(nums.begin(), nums.end());
    std::vector<int> prefixSums(nums.size() + 1);
    std::partial_sum(nums.begin(), nums.end(), prefixSums.begin() + 1);

    std::vector<int> answer(queries.size());
    for (int i = 0; i < queries.size(); ++i) {
        answer[i] = std::upper_bound(prefixSums.begin(), prefixSums.end(), queries[i]) - prefixSums.begin() - 1;
    }

    return answer;
}
```
The algorithm sorts the `nums` array in ascending order, then calculates the prefix sums for easy sum checks. For each query, it finds the position for the query in the prefix sums array using binary search, and the index of that position minus one represents the maximum size of a subsequence whose sum is less than or equal to the query. It adds that value to the answer array.

## A solution in Python

```python
from bisect import bisect

def maxSizeSubsequenceSumQueries(nums, queries):
    nums.sort()
    prefixSums = [0] * (len(nums) + 1)
    for i, x in enumerate(nums):
        prefixSums[i + 1] = prefixSums[i] + x

    answer = []
    for q in queries:
        idx = bisect(prefixSums, q)
        answer.append(idx - 1)

    return answer
```
The algorithm sorts the `nums` array in ascending order, then calculates the prefix sums for easy sum checks. For each query, it finds the position for the query in the prefix sums array using binary search, and the index of that position minus one represents the maximum size of a subsequence whose sum is less than or equal to the query. It adds that value to the answer array.

## A solution in Javascript

```javascript
function maxSizeSubsequenceSumQueries(nums, queries) {
    nums.sort((a, b) => a - b);
    const prefixSums = Array(nums.length + 1).fill(0);
    for (let i = 0; i < nums.length; ++i) {
        prefixSums[i + 1] = prefixSums[i] + nums[i];
    }

    const answer = [];
    for (const query of queries) {
        const idx = prefixSums.upperBound(query);
        answer.push(idx - 1);
    }

    if (!Array.prototype.upperBound) {
        Array.prototype.upperBound = function(val) {
            let left = 0;
            let right = this.length;
            while (left < right) {
                const mid = (left + right) >>> 1;
                if (this[mid] <= val) {
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }
            return left;
        };
    }

    return answer;
}
```
The algorithm sorts the `nums` array in ascending order, then calculates the prefix sums for easy sum checks. For each query, it finds the position for the query in the prefix sums array using binary search, and the index of that position minus one represents the maximum size of a subsequence whose sum is less than or equal to the query. It adds that value to the answer array.


# Removing Stars From a String

- slug: removing-stars-from-a-string
- difficulty: Medium

You are given a string `s`, which contains stars `*`.

In one operation, you can:

*   Choose a star in `s`.
*   Remove the closest **non-star** character to its **left**, as well as remove the star itself.

Return _the string after **all** stars have been removed_.

**Note:**

*   The input will be generated such that the operation is always possible.
*   It can be shown that the resulting string will always be unique.

**Example 1:**

**Input:** s =  "leet\*\*cod\*e "
**Output:**  "lecoe "
**Explanation:** Performing the removals from left to right:
- The closest character to the 1st star is 't' in  "lee**t**\*\*cod\*e ". s becomes  "lee\*cod\*e ".
- The closest character to the 2nd star is 'e' in  "le**e**\*cod\*e ". s becomes  "lecod\*e ".
- The closest character to the 3rd star is 'd' in  "leco**d**\*e ". s becomes  "lecoe ".
There are no more stars, so we return  "lecoe ".

**Example 2:**

**Input:** s =  "erase\*\*\*\*\* "
**Output:**  " "
**Explanation:** The entire string is removed, so we return an empty string.

**Constraints:**

*   `1 <= s.length <= 105`
*   `s` consists of lowercase English letters and stars `*`.
*   The operation above can be performed on `s`.

## A solution in Java

```java
public String removeStars(String s) {
    StringBuilder result = new StringBuilder();
    for (char c : s.toCharArray()) {
        if (c == '*') {
            if (result.length() > 0) {
                result.deleteCharAt(result.length() - 1);
            }
        } else {
            result.append(c);
        }
    }
    return result.toString();
}
```
For each character in the given string `s`, we iterate through the characters. If the character is a star, we remove the last character of the `result` only if `result` is not empty. Otherwise, we append the character to the `result`. Finally, we return the `result` as a string. This algorithm simulates the removal operation described in the question. Since we always remove characters that are closest to the stars, the order of operations does not matter, and the algorithm produces the unique possible output.

## A solution in C++

```cpp
std::string removeStars(std::string s) {
    std::string result;
    int stars = 0;
    for (char c : s) {
        if (c == '*') {
            if (!result.empty()) {
                result.pop_back();
            }
        } else {
            result.push_back(c);
        }
    }
    return result;
}
```
For each character in the given string `s`, we iterate through the characters. If the character is a star, we remove the last character of the `result` only if `result` is not empty. Otherwise, we append the character to the `result`. Finally, we return the `result` as a string. This algorithm simulates the removal operation described in the question. Since we always remove characters that are closest to the stars, the order of operations does not matter, and the algorithm produces the unique possible output.

## A solution in Python

```python
def remove_stars(s: str) -> str:
    result = []
    for c in s:
        if c == '*':
            if result:
                result.pop()
        else:
            result.append(c)
    return ''.join(result)
```
For each character in the given string `s`, we iterate through the characters. If the character is a star, we remove the last character of the `result` only if `result` is not empty. Otherwise, we append the character to the `result`. Finally, we return the `result` as a string. This algorithm simulates the removal operation described in the question. Since we always remove characters that are closest to the stars, the order of operations does not matter, and the algorithm produces the unique possible output.

## A solution in Javascript

```javascript
function removeStars(s) {
    let result = [];
    for (let c of s) {
        if (c === '*') {
            if (result.length > 0) {
                result.pop();
            }
        } else {
            result.push(c);
        }
    }
    return result.join('');
}
```
For each character in the given string `s`, we iterate through the characters. If the character is a star, we remove the last character of the `result` only if `result` is not empty. Otherwise, we append the character to the `result`. Finally, we return the `result` as a string. This algorithm simulates the removal operation described in the question. Since we always remove characters that are closest to the stars, the order of operations does not matter, and the algorithm produces the unique possible output.


# Minimum Amount of Time to Collect Garbage

- slug: minimum-amount-of-time-to-collect-garbage
- difficulty: Medium

You are given a **0-indexed** array of strings `garbage` where `garbage[i]` represents the assortment of garbage at the `ith` house. `garbage[i]` consists only of the characters `'M'`, `'P'` and `'G'` representing one unit of metal, paper and glass garbage respectively. Picking up **one** unit of any type of garbage takes `1` minute.

You are also given a **0-indexed** integer array `travel` where `travel[i]` is the number of minutes needed to go from house `i` to house `i + 1`.

There are three garbage trucks in the city, each responsible for picking up one type of garbage. Each garbage truck starts at house `0` and must visit each house **in order**; however, they do **not** need to visit every house.

Only **one** garbage truck may be used at any given moment. While one truck is driving or picking up garbage, the other two trucks **cannot** do anything.

Return _the **minimum** number of minutes needed to pick up all the garbage._

**Example 1:**

**Input:** garbage = \[ "G ", "P ", "GP ", "GG "\], travel = \[2,4,3\]
**Output:** 21
**Explanation:**
The paper garbage truck:
1. Travels from house 0 to house 1
2. Collects the paper garbage at house 1
3. Travels from house 1 to house 2
4. Collects the paper garbage at house 2
Altogether, it takes 8 minutes to pick up all the paper garbage.
The glass garbage truck:
1. Collects the glass garbage at house 0
2. Travels from house 0 to house 1
3. Travels from house 1 to house 2
4. Collects the glass garbage at house 2
5. Travels from house 2 to house 3
6. Collects the glass garbage at house 3
Altogether, it takes 13 minutes to pick up all the glass garbage.
Since there is no metal garbage, we do not need to consider the metal garbage truck.
Therefore, it takes a total of 8 + 13 = 21 minutes to collect all the garbage.

**Example 2:**

**Input:** garbage = \[ "MMM ", "PGM ", "GP "\], travel = \[3,10\]
**Output:** 37
**Explanation:**
The metal garbage truck takes 7 minutes to pick up all the metal garbage.
The paper garbage truck takes 15 minutes to pick up all the paper garbage.
The glass garbage truck takes 15 minutes to pick up all the glass garbage.
It takes a total of 7 + 15 + 15 = 37 minutes to collect all the garbage.

**Constraints:**

*   `2 <= garbage.length <= 105`
*   `garbage[i]` consists of only the letters `'M'`, `'P'`, and `'G'`.
*   `1 <= garbage[i].length <= 10`
*   `travel.length == garbage.length - 1`
*   `1 <= travel[i] <= 100`

## A solution in Java

```java
public int min_minutes(String[] garbage, int[] travel) {
    int[] time_garbage = new int[3];
    int[] time_travel = new int[3];

    for (int i = 0; i < garbage.length; i++) {
        int m = 0, p = 0, g = 0;
        for (char c : garbage[i].toCharArray()) {
            if (c == 'M') m++;
            else if (c == 'P') p++;
            else g++;
        }
        time_garbage[0] += m;
        time_garbage[1] += p;
        time_garbage[2] += g;
        if (i < garbage.length - 1) {
            time_travel[0] += travel[i];
            time_travel[1] += travel[i];
            time_travel[2] += travel[i];
        }
    }
    return time_garbage[0] + time_travel[0] + time_garbage[1] + time_travel[1] + time_garbage[2] + time_travel[2];
}
```
This algorithm iterates through the garbage and travel arrays simultaneously. It keeps track of two sets of time counters: one for the time spent on picking up each type of garbage and one for the time spent on traveling between houses. In each iteration, it counts the number of 'M', 'P', and 'G' in a house's garbage string and adds it to the respective time_garbage counters. It also adds the travel[i] value to the respective time_travel counters for all three types of garbage. Finally, it returns the total time spent on picking up garbage and traveling for all three types.

## A solution in C++

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

int min_minutes(const vector<string>& garbage, const vector<int>& travel) {
    vector<int> time_garbage(3, 0);
    vector<int> time_travel(3, 0);

    for (int i = 0; i < garbage.size(); i++) {
        int m = 0, p = 0, g = 0;
        for (char c : garbage[i]) {
            if (c == 'M') m++;
            else if (c == 'P') p++;
            else g++;
        }
        time_garbage[0] += m;
        time_garbage[1] += p;
        time_garbage[2] += g;
        if (i < garbage.size() - 1) {
            time_travel[0] += travel[i];
            time_travel[1] += travel[i];
            time_travel[2] += travel[i];
        }
    }
    return time_garbage[0] + time_travel[0] + time_garbage[1] + time_travel[1] + time_garbage[2] + time_travel[2];
}
```
This algorithm iterates through the garbage and travel arrays simultaneously. It keeps track of two sets of time counters: one for the time spent on picking up each type of garbage and one for the time spent on traveling between houses. In each iteration, it counts the number of 'M', 'P', and 'G' in a house's garbage string and adds it to the respective time_garbage counters. It also adds the travel[i] value to the respective time_travel counters for all three types of garbage. Finally, it returns the total time spent on picking up garbage and traveling for all three types.

## A solution in Python

```python
def min_minutes(garbage: list[str], travel: list[int]) -> int:
    time_garbage = [0, 0, 0]
    time_travel = [0, 0, 0]

    for i, g in enumerate(garbage):
        m, p, g = g.count('M'), g.count('P'), g.count('G')
        time_garbage[0] += m
        time_garbage[1] += p
        time_garbage[2] += g
        if i < len(garbage) - 1:
            time_travel[0] += travel[i]
            time_travel[1] += travel[i]
            time_travel[2] += travel[i]

    return sum(time_garbage) + sum(time_travel)
```
This algorithm iterates through the garbage and travel arrays simultaneously. It keeps track of two sets of time counters: one for the time spent on picking up each type of garbage and one for the time spent on traveling between houses. In each iteration, it counts the number of 'M', 'P', and 'G' in a house's garbage string and adds it to the respective time_garbage counters. It also adds the travel[i] value to the respective time_travel counters for all three types of garbage. Finally, it returns the total time spent on picking up garbage and traveling for all three types.

## A solution in Javascript

```javascript
function min_minutes(garbage, travel) {
    let time_garbage = [0, 0, 0];
    let time_travel = [0, 0, 0];

    for (let i = 0; i < garbage.length; i++) {
        let m = 0, p = 0, g = 0;
        for (let c of garbage[i]) {
            if (c === 'M') m++;
            else if (c === 'P') p++;
            else g++;
        }
        time_garbage[0] += m;
        time_garbage[1] += p;
        time_garbage[2] += g;
        if (i < garbage.length - 1) {
            time_travel[0] += travel[i];
            time_travel[1] += travel[i];
            time_travel[2] += travel[i];
        }
    }
    return time_garbage[0] + time_travel[0] + time_garbage[1] + time_travel[1] + time_garbage[2] + time_travel[2];
}
```
This algorithm iterates through the garbage and travel arrays simultaneously. It keeps track of two sets of time counters: one for the time spent on picking up each type of garbage and one for the time spent on traveling between houses. In each iteration, it counts the number of 'M', 'P', and 'G' in a house's garbage string and adds it to the respective time_garbage counters. It also adds the travel[i] value to the respective time_travel counters for all three types of garbage. Finally, it returns the total time spent on picking up garbage and traveling for all three types.


# Build a Matrix With Conditions

- slug: build-a-matrix-with-conditions
- difficulty: Hard

You are given a **positive** integer `k`. You are also given:

*   a 2D integer array `rowConditions` of size `n` where `rowConditions[i] = [abovei, belowi]`, and
*   a 2D integer array `colConditions` of size `m` where `colConditions[i] = [lefti, righti]`.

The two arrays contain integers from `1` to `k`.

You have to build a `k x k` matrix that contains each of the numbers from `1` to `k` **exactly once**. The remaining cells should have the value `0`.

The matrix should also satisfy the following conditions:

*   The number `abovei` should appear in a **row** that is strictly **above** the row at which the number `belowi` appears for all `i` from `0` to `n - 1`.
*   The number `lefti` should appear in a **column** that is strictly **left** of the column at which the number `righti` appears for all `i` from `0` to `m - 1`.

Return _**any** matrix that satisfies the conditions_. If no answer exists, return an empty matrix.

**Example 1:**

**Input:** k = 3, rowConditions = \[\[1,2\],\[3,2\]\], colConditions = \[\[2,1\],\[3,2\]\]
**Output:** \[\[3,0,0\],\[0,0,1\],\[0,2,0\]\]
**Explanation:** The diagram above shows a valid example of a matrix that satisfies all the conditions.
The row conditions are the following:
- Number 1 is in row 1, and number 2 is in row 2, so 1 is above 2 in the matrix.
- Number 3 is in row 0, and number 2 is in row 2, so 3 is above 2 in the matrix.
The column conditions are the following:
- Number 2 is in column 1, and number 1 is in column 2, so 2 is left of 1 in the matrix.
- Number 3 is in column 0, and number 2 is in column 1, so 3 is left of 2 in the matrix.
Note that there may be multiple correct answers.

**Example 2:**

**Input:** k = 3, rowConditions = \[\[1,2\],\[2,3\],\[3,1\],\[2,3\]\], colConditions = \[\[2,1\]\]
**Output:** \[\]
**Explanation:** From the first two conditions, 3 has to be below 1 but the third conditions needs 3 to be above 1 to be satisfied.
No matrix can satisfy all the conditions, so we return the empty matrix.

**Constraints:**

*   `2 <= k <= 400`
*   `1 <= rowConditions.length, colConditions.length <= 104`
*   `rowConditions[i].length == colConditions[i].length == 2`
*   `1 <= abovei, belowi, lefti, righti <= k`
*   `abovei != belowi`
*   `lefti != righti`

## A solution in Java

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

public int[][] buildMatrix(int k, List<List<Integer>> rowConditions, List<List<Integer>> colConditions) {
    int[] row = new int[k + 1], col = new int[k + 1];
    for (List<Integer> condition : rowConditions) {
        if (row[condition.get(0)] >= row[condition.get(1)]) return new int[][]{};
        row[condition.get(1)] = row[condition.get(0)] + 1;
    }
    for (List<Integer> condition : colConditions) {
        if (col[condition.get(0)] >= col[condition.get(1)]) return new int[][]{};
        col[condition.get(1)] = col[condition.get(0)] + 1;
    }
    int[][] matrix = new int[k][k];
    for (int i = 1; i <= k; ++i) {
        matrix[row[i]][col[i]] = i;
    }
    return matrix;
}
```
1. Initialize two arrays `row` and `col` of length `k+1`. They are used to store the row and column positions of each number respectively.
2. Iterate through `rowConditions` and do the following:
   a. If `row[a]` is greater than or equal to `row[b]`, then return an empty matrix as no answer exists.
   b. Update `row[b]` to `row[a] + 1`. This ensures that number `b` is strictly below number `a`.
3. Iterate through `colConditions` and do the following:
   a. If `col[a]` is greater than or equal to `col[b]`, then return an empty matrix as no answer exists.
   b. Update `col[b]` to `col[a] + 1`. This ensures that number `b` is strictly right of number `a`.
4. Create a k x k matrix filled with zeroes.
5. Iterate from 1 to k and fill the matrix with numbers from 1 to k at their respective row and column positions, as stored in the `row` and `col` arrays.
6. Return the filled matrix as the result.

## A solution in C++

```cpp
#include <vector>

std::vector<std::vector<int>> buildMatrix(int k, std::vector<std::vector<int>>& rowConditions, std::vector<std::vector<int>>& colConditions) {
    std::vector<int> row(k + 1, 0), col(k + 1, 0);
    for (const auto& condition : rowConditions) {
        if (row[condition[0]] >= row[condition[1]]) return {};
        row[condition[1]] = row[condition[0]] + 1;
    }
    for (const auto& condition : colConditions) {
        if (col[condition[0]] >= col[condition[1]]) return {};
        col[condition[1]] = col[condition[0]] + 1;
    }
    std::vector<std::vector<int>> matrix(k, std::vector<int>(k));
    for (int i = 1; i <= k; ++i) {
        matrix[row[i]][col[i]] = i;
    }
    return matrix;
}
```
1. Initialize two arrays `row` and `col` of length `k+1`. They are used to store the row and column positions of each number respectively.
2. Iterate through `rowConditions` and do the following:
   a. If `row[a]` is greater than or equal to `row[b]`, then return an empty matrix as no answer exists.
   b. Update `row[b]` to `row[a] + 1`. This ensures that number `b` is strictly below number `a`.
3. Iterate through `colConditions` and do the following:
   a. If `col[a]` is greater than or equal to `col[b]`, then return an empty matrix as no answer exists.
   b. Update `col[b]` to `col[a] + 1`. This ensures that number `b` is strictly right of number `a`.
4. Create a k x k matrix filled with zeroes.
5. Iterate from 1 to k and fill the matrix with numbers from 1 to k at their respective row and column positions, as stored in the `row` and `col` arrays.
6. Return the filled matrix as the result.

## A solution in Python

```python
def build_matrix(k: int, row_conditions: List[List[int]], col_conditions: List[List[int]]) -> List[List[int]]:
    row, col = [0] * (k + 1), [0] * (k + 1)
    for condition in row_conditions:
        if row[condition[0]] >= row[condition[1]]:
            return []
        row[condition[1]] = row[condition[0]] + 1
    for condition in col_conditions:
        if col[condition[0]] >= col[condition[1]]:
            return []
        col[condition[1]] = col[condition[0]] + 1
    matrix = [[0] * k for _ in range(k)]
    for i in range(1, k + 1):
        matrix[row[i]][col[i]] = i
    return matrix
```
1. Initialize two arrays `row` and `col` of length `k+1`. They are used to store the row and column positions of each number respectively.
2. Iterate through `rowConditions` and do the following:
   a. If `row[a]` is greater than or equal to `row[b]`, then return an empty matrix as no answer exists.
   b. Update `row[b]` to `row[a] + 1`. This ensures that number `b` is strictly below number `a`.
3. Iterate through `colConditions` and do the following:
   a. If `col[a]` is greater than or equal to `col[b]`, then return an empty matrix as no answer exists.
   b. Update `col[b]` to `col[a] + 1`. This ensures that number `b` is strictly right of number `a`.
4. Create a k x k matrix filled with zeroes.
5. Iterate from 1 to k and fill the matrix with numbers from 1 to k at their respective row and column positions, as stored in the `row` and `col` arrays.
6. Return the filled matrix as the result.

## A solution in Javascript

```javascript
function buildMatrix(k, rowConditions, colConditions) {
    let row = new Array(k + 1).fill(0), col = new Array(k + 1).fill(0);
    for (const condition of rowConditions) {
        if (row[condition[0]] >= row[condition[1]]) return [];
        row[condition[1]] = row[condition[0]] + 1;
    }
    for (const condition of colConditions) {
        if (col[condition[0]] >= col[condition[1]]) return [];
        col[condition[1]] = col[condition[0]] + 1;
    }
    let matrix = Array.from({length: k}, () => new Array(k).fill(0));
    for (let i = 1; i <= k; ++i) {
        matrix[row[i]][col[i]] = i;
    }
    return matrix;
}
```
1. Initialize two arrays `row` and `col` of length `k+1`. They are used to store the row and column positions of each number respectively.
2. Iterate through `rowConditions` and do the following:
   a. If `row[a]` is greater than or equal to `row[b]`, then return an empty matrix as no answer exists.
   b. Update `row[b]` to `row[a] + 1`. This ensures that number `b` is strictly below number `a`.
3. Iterate through `colConditions` and do the following:
   a. If `col[a]` is greater than or equal to `col[b]`, then return an empty matrix as no answer exists.
   b. Update `col[b]` to `col[a] + 1`. This ensures that number `b` is strictly right of number `a`.
4. Create a k x k matrix filled with zeroes.
5. Iterate from 1 to k and fill the matrix with numbers from 1 to k at their respective row and column positions, as stored in the `row` and `col` arrays.
6. Return the filled matrix as the result.


# Count Strictly Increasing Subarrays

- slug: count-strictly-increasing-subarrays
- difficulty: Medium

You are given an array `nums` consisting of **positive** integers.

Return _the number of **subarrays** of_ `nums` _that are in **strictly increasing** order._

A **subarray** is a **contiguous** part of an array.

**Example 1:**

**Input:** nums = \[1,3,5,4,4,6\]
**Output:** 10
**Explanation:** The strictly increasing subarrays are the following:
- Subarrays of length 1: \[1\], \[3\], \[5\], \[4\], \[4\], \[6\].
- Subarrays of length 2: \[1,3\], \[3,5\], \[4,6\].
- Subarrays of length 3: \[1,3,5\].
The total number of subarrays is 6 + 3 + 1 = 10.

**Example 2:**

**Input:** nums = \[1,2,3,4,5\]
**Output:** 15
**Explanation:** Every subarray is strictly increasing. There are 15 possible subarrays that we can take.

**Constraints:**

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

## A solution in Java

```java
public int numStrictlyIncreasingSubarrays(int[] nums) {
    int n = nums.length;
    int count = 0, sum = 0;
    for (int i = 1; i < n; ++i) {
        if (nums[i] > nums[i - 1]) {
            count++;
        } else {
            count = 0;
        }
        sum += count;
    }
    return sum + n;
}
```
In this solution, we iterate through the array once, whereas we maintain two variables: `count` and `sum`. `count` is the length of the current increasing subarray, and `sum` keeps the sum of all lengths.
For each element, starting with the second one, we check whether it is greater than the previous element. If so, we increment the `count`, otherwise we reset the `count` to zero. We add the `count` to the `sum` at each iteration.
When the loop finishes, we have the total number of strictly increasing subarrays of length 2 or more. We finally add the length of the original array `n` to the result to include the length 1 subarrays, and return the final result.

## A solution in C++

```cpp
int numStrictlyIncreasingSubarrays(vector<int>& nums) {
    int n = nums.size();
    int count = 0, sum = 0;
    for (int i = 1; i < n; ++i) {
        if (nums[i] > nums[i - 1]) {
            count++;
        } else {
            count = 0;
        }
        sum += count;
    }
    return sum + n;
}
```
In this solution, we iterate through the array once, whereas we maintain two variables: `count` and `sum`. `count` is the length of the current increasing subarray, and `sum` keeps the sum of all lengths.
For each element, starting with the second one, we check whether it is greater than the previous element. If so, we increment the `count`, otherwise we reset the `count` to zero. We add the `count` to the `sum` at each iteration.
When the loop finishes, we have the total number of strictly increasing subarrays of length 2 or more. We finally add the length of the original array `n` to the result to include the length 1 subarrays, and return the final result.

## A solution in Python

```python
def num_strictly_increasing_subarrays(nums):
    n = len(nums)
    count = 0
    sum = 0
    for i in range(1, n):
        if nums[i] > nums[i - 1]:
            count += 1
        else:
            count = 0
        sum += count
    return sum + n
```
In this solution, we iterate through the array once, whereas we maintain two variables: `count` and `sum`. `count` is the length of the current increasing subarray, and `sum` keeps the sum of all lengths.
For each element, starting with the second one, we check whether it is greater than the previous element. If so, we increment the `count`, otherwise we reset the `count` to zero. We add the `count` to the `sum` at each iteration.
When the loop finishes, we have the total number of strictly increasing subarrays of length 2 or more. We finally add the length of the original array `n` to the result to include the length 1 subarrays, and return the final result.

## A solution in Javascript

```javascript
function numStrictlyIncreasingSubarrays(nums) {
    const n = nums.length;
    let count = 0;
    let sum = 0;
    for (let i = 1; i < n; ++i) {
        if (nums[i] > nums[i - 1]) {
            count++;
        } else {
            count = 0;
        }
        sum += count;
    }
    return sum + n;
}
```
In this solution, we iterate through the array once, whereas we maintain two variables: `count` and `sum`. `count` is the length of the current increasing subarray, and `sum` keeps the sum of all lengths.
For each element, starting with the second one, we check whether it is greater than the previous element. If so, we increment the `count`, otherwise we reset the `count` to zero. We add the `count` to the `sum` at each iteration.
When the loop finishes, we have the total number of strictly increasing subarrays of length 2 or more. We finally add the length of the original array `n` to the result to include the length 1 subarrays, and return the final result.


# Find Subarrays With Equal Sum

- slug: find-subarrays-with-equal-sum
- difficulty: Easy

Given a **0-indexed** integer array `nums`, determine whether there exist **two** subarrays of length `2` with **equal** sum. Note that the two subarrays must begin at **different** indices.

Return `true` _if these subarrays exist, and_ `false` _otherwise._

A **subarray** is a contiguous non-empty sequence of elements within an array.

**Example 1:**

**Input:** nums = \[4,2,4\]
**Output:** true
**Explanation:** The subarrays with elements \[4,2\] and \[2,4\] have the same sum of 6.

**Example 2:**

**Input:** nums = \[1,2,3,4,5\]
**Output:** false
**Explanation:** No two subarrays of size 2 have the same sum.

**Example 3:**

**Input:** nums = \[0,0,0\]
**Output:** true
**Explanation:** The subarrays \[nums\[0\],nums\[1\]\] and \[nums\[1\],nums\[2\]\] have the same sum of 0.
Note that even though the subarrays have the same content, the two subarrays are considered different because they are in different positions in the original array.

**Constraints:**

*   `2 <= nums.length <= 1000`
*   `-109 <= nums[i] <= 109`

## A solution in Java

```java
public boolean equalSumSubarrays(int[] nums) {
    Set<Integer> sums = new HashSet<>();
    for (int i = 1; i < nums.length; ++i) {
        int sum = nums[i] + nums[i - 1];
        if (sums.contains(sum)) return true;
        sums.add(sum);
    }
    return false;
}
```
The algorithm works by iterating through the array, calculating the sum of each pair of adjacent elements, and using a set to store the seen sums. If the current sum already exists in the set, it means that there are two subarrays with equal sums, so the function returns `true`. At the end of the loop, if no such subarrays were found, the function returns `false`.

Time complexity is O(n), where n is the size of the input array, since we are iterating through the elements only once. Space complexity is also O(n) as at worst we have to store all possible sums in the set.

## A solution in C++

```cpp
bool equalSumSubarrays(vector<int>& nums) {
    unordered_set<int> sums;
    for (int i = 1; i < nums.size(); ++i) {
        int sum = nums[i] + nums[i - 1];
        if (sums.count(sum)) return true;
        sums.insert(sum);
    }
    return false;
}
```
The algorithm works by iterating through the array, calculating the sum of each pair of adjacent elements, and using a set to store the seen sums. If the current sum already exists in the set, it means that there are two subarrays with equal sums, so the function returns `true`. At the end of the loop, if no such subarrays were found, the function returns `false`.

Time complexity is O(n), where n is the size of the input array, since we are iterating through the elements only once. Space complexity is also O(n) as at worst we have to store all possible sums in the set.

## A solution in Python

```python
def equal_sum_subarrays(nums):
    sums = set()
    for i in range(1, len(nums)):
        current_sum = nums[i] + nums[i - 1]
        if current_sum in sums:
            return True
        sums.add(current_sum)
    return False
```
The algorithm works by iterating through the array, calculating the sum of each pair of adjacent elements, and using a set to store the seen sums. If the current sum already exists in the set, it means that there are two subarrays with equal sums, so the function returns `true`. At the end of the loop, if no such subarrays were found, the function returns `false`.

Time complexity is O(n), where n is the size of the input array, since we are iterating through the elements only once. Space complexity is also O(n) as at worst we have to store all possible sums in the set.

## A solution in Javascript

```javascript
function equalSumSubarrays(nums) {
    const sums = new Set();
    for (let i = 1; i < nums.length; ++i) {
        const sum = nums[i] + nums[i - 1];
        if (sums.has(sum)) return true;
        sums.add(sum);
    }
    return false;
}
```
The algorithm works by iterating through the array, calculating the sum of each pair of adjacent elements, and using a set to store the seen sums. If the current sum already exists in the set, it means that there are two subarrays with equal sums, so the function returns `true`. At the end of the loop, if no such subarrays were found, the function returns `false`.

Time complexity is O(n), where n is the size of the input array, since we are iterating through the elements only once. Space complexity is also O(n) as at worst we have to store all possible sums in the set.


# Strictly Palindromic Number

- slug: strictly-palindromic-number
- difficulty: Medium

An integer `n` is **strictly palindromic** if, for **every** base `b` between `2` and `n - 2` (**inclusive**), the string representation of the integer `n` in base `b` is **palindromic**.

Given an integer `n`, return `true` _if_ `n` _is **strictly palindromic** and_ `false` _otherwise_.

A string is **palindromic** if it reads the same forward and backward.

**Example 1:**

**Input:** n = 9
**Output:** false
**Explanation:** In base 2: 9 = 1001 (base 2), which is palindromic.
In base 3: 9 = 100 (base 3), which is not palindromic.
Therefore, 9 is not strictly palindromic so we return false.
Note that in bases 4, 5, 6, and 7, n = 9 is also not palindromic.

**Example 2:**

**Input:** n = 4
**Output:** false
**Explanation:** We only consider base 2: 4 = 100 (base 2), which is not palindromic.
Therefore, we return false.

**Constraints:**

*   `4 <= n <= 105`

## A solution in Java

```java
public boolean isPalindrome(String s) {
    int start = 0;
    int end = s.length() - 1;
    while (start < end) {
        if (s.charAt(start) != s.charAt(end)) {
            return false;
        }
        start++;
        end--;
    }
    return true;
}

public String toBaseString(int n, int base) {
    StringBuilder sb = new StringBuilder();
    while (n > 0) {
        sb.append(n % base);
        n /= base;
    }
    return sb.reverse().toString();
}

public boolean isStrictlyPalindromic(int n) {
    for (int b = 2; b <= n - 2; b++) {
        if (!isPalindrome(toBaseString(n, b))) {
            return false;
        }
    }
    return true;
}
```
The algorithm first defines two helper functions: `is_palindrome` and `to_base_str`. `is_palindrome` checks if the input string is palindrome and `to_base_str` converts an integer `n` to its string representation in the given base.

The main algorithm follows these steps:
1. Loop through all bases `b` between 2 and `n - 2`.
2. For each base `b`, convert the integer `n` to its string representation using the `to_base_str` function.
3. Check if the resulting string is palindrome using the `is_palindrome` function.
4. If any string from step 3 is not palindrome, return `false`.
5. If all strings from step 3 are palindrome, return `true` after completing the loop.

This approach effectively checks if the given number is strictly palindromic for all required bases.

## A solution in C++

```cpp
bool is_palindrome(const std::string& s) {
    return std::equal(s.begin(), s.end(), s.rbegin());
}

std::string to_base_str(int n, int base) {
    std::string s;
    while (n > 0) {
        s.push_back(n % base);
        n /= base;
    }
    return s;
}

bool isStrictlyPalindromic(int n) {
    for (int b = 2; b <= n - 2; b++) {
        if (!is_palindrome(to_base_str(n, b))) {
            return false;
        }
    }
    return true;
}
```
The algorithm first defines two helper functions: `is_palindrome` and `to_base_str`. `is_palindrome` checks if the input string is palindrome and `to_base_str` converts an integer `n` to its string representation in the given base.

The main algorithm follows these steps:
1. Loop through all bases `b` between 2 and `n - 2`.
2. For each base `b`, convert the integer `n` to its string representation using the `to_base_str` function.
3. Check if the resulting string is palindrome using the `is_palindrome` function.
4. If any string from step 3 is not palindrome, return `false`.
5. If all strings from step 3 are palindrome, return `true` after completing the loop.

This approach effectively checks if the given number is strictly palindromic for all required bases.

## A solution in Python

```python
def is_palindrome(s: str) -> bool:
    return s == s[::-1]

def to_base_str(n: int, base: int) -> str:
    s = []
    while n > 0:
        s.append(str(n % base))
        n //= base
    return "".join(reversed(s))

def is_strictly_palindromic(n: int) -> bool:
    for b in range(2, n - 1):
        if not is_palindrome(to_base_str(n, b)):
            return False
    return True
```
The algorithm first defines two helper functions: `is_palindrome` and `to_base_str`. `is_palindrome` checks if the input string is palindrome and `to_base_str` converts an integer `n` to its string representation in the given base.

The main algorithm follows these steps:
1. Loop through all bases `b` between 2 and `n - 2`.
2. For each base `b`, convert the integer `n` to its string representation using the `to_base_str` function.
3. Check if the resulting string is palindrome using the `is_palindrome` function.
4. If any string from step 3 is not palindrome, return `false`.
5. If all strings from step 3 are palindrome, return `true` after completing the loop.

This approach effectively checks if the given number is strictly palindromic for all required bases.

## A solution in Javascript

```javascript
function isPalindrome(s) {
    return s === s.split("").reverse().join("")
}

function toBaseString(n, base) {
    let s = [];
    while (n > 0) {
        s.push(n % base);
        n = Math.floor(n / base);
    }
    return s.reverse().join("");
}

function isStrictlyPalindromic(n) {
    for (let b = 2; b <= n - 2; b++) {
        if (!isPalindrome(toBaseString(n, b))) {
            return false;
        }
    }
    return true;
}
```
The algorithm first defines two helper functions: `is_palindrome` and `to_base_str`. `is_palindrome` checks if the input string is palindrome and `to_base_str` converts an integer `n` to its string representation in the given base.

The main algorithm follows these steps:
1. Loop through all bases `b` between 2 and `n - 2`.
2. For each base `b`, convert the integer `n` to its string representation using the `to_base_str` function.
3. Check if the resulting string is palindrome using the `is_palindrome` function.
4. If any string from step 3 is not palindrome, return `false`.
5. If all strings from step 3 are palindrome, return `true` after completing the loop.

This approach effectively checks if the given number is strictly palindromic for all required bases.


# Maximum Rows Covered by Columns

- slug: maximum-rows-covered-by-columns
- difficulty: Medium

You are given a **0-indexed** `m x n` binary matrix `matrix` and an integer `numSelect`, which denotes the number of **distinct** columns you must select from `matrix`.

Let us consider `s = {c1, c2, ...., cnumSelect}` as the set of columns selected by you. A row `row` is **covered** by `s` if:

*   For each cell `matrix[row][col]` (`0 <= col <= n - 1`) where `matrix[row][col] == 1`, `col` is present in `s` or,
*   **No cell** in `row` has a value of `1`.

You need to choose `numSelect` columns such that the number of rows that are covered is **maximized**.

Return _the **maximum** number of rows that can be **covered** by a set of_ `numSelect` _columns._

**Example 1:**

**Input:** matrix = \[\[0,0,0\],\[1,0,1\],\[0,1,1\],\[0,0,1\]\], numSelect = 2
**Output:** 3
**Explanation:** One possible way to cover 3 rows is shown in the diagram above.
We choose s = {0, 2}.
- Row 0 is covered because it has no occurrences of 1.
- Row 1 is covered because the columns with value 1, i.e. 0 and 2 are present in s.
- Row 2 is not covered because matrix\[2\]\[1\] == 1 but 1 is not present in s.
- Row 3 is covered because matrix\[2\]\[2\] == 1 and 2 is present in s.
Thus, we can cover three rows.
Note that s = {1, 2} will also cover 3 rows, but it can be shown that no more than three rows can be covered.

**Example 2:**

**Input:** matrix = \[\[1\],\[0\]\], numSelect = 1
**Output:** 2
**Explanation:** Selecting the only column will result in both rows being covered since the entire matrix is selected.
Therefore, we return 2.

**Constraints:**

*   `m == matrix.length`
*   `n == matrix[i].length`
*   `1 <= m, n <= 12`
*   `matrix[i][j]` is either `0` or `1`.
*   `1 <= numSelect <= n`

## A solution in Java

```java
import java.util.*;

public int maxCoveredRows(int[][] matrix, int numSelect) {
    int m = matrix.length;
    int n = matrix[0].length;
    int maxCovered = 0;

    for (int i = 0; i < (1 << n); ++i) {
        if (Integer.bitCount(i) == numSelect) {
            int covered = 0;
            for (int row = 0; row < m; ++row) {
                for (int col = 0; col < n; ++col) {
                    if ((matrix[row][col] == 1) && ((i & (1 << col)) > 0)) {
                        covered++;
                        break;
                    }
                }
            }
            maxCovered = Math.max(maxCovered, covered);
        }
    }
    return maxCovered;
}
```
The algorithm is a brute-force method that iterates through all possible combinations of columns (there are 2^n total combinations), as these are represented by binary numbers from 0 to 2^n-1. After selecting a column combination, that is, when the number of set bits (1s) in this combination is equal to 'num_select', the algorithm iterates through the rows and checks if that row is covered by the selected columns. The maximum number of rows covered for all column combinations is then returned.

## A solution in C++

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

int maxCoveredRows(std::vector<std::vector<int>>& matrix, int numSelect) {
    int m = matrix.size();
    int n = matrix[0].size();
    int max_covered = 0;

    for (int i = 0; i < (1 << n); ++i) {
        if (__builtin_popcount(i) == numSelect) {
            int covered = 0;
            for (int row = 0; row < m; ++row) {
                for (int col = 0; col < n; ++col) {
                    if ((matrix[row][col] == 1) && (i & (1 << col))) {
                        covered++;
                        break;
                    }
                }
            }
            max_covered = std::max(max_covered, covered);
        }
    }
    return max_covered;
}
```
The algorithm is a brute-force method that iterates through all possible combinations of columns (there are 2^n total combinations), as these are represented by binary numbers from 0 to 2^n-1. After selecting a column combination, that is, when the number of set bits (1s) in this combination is equal to 'num_select', the algorithm iterates through the rows and checks if that row is covered by the selected columns. The maximum number of rows covered for all column combinations is then returned.

## A solution in Python

```python
def max_covered_rows(matrix, num_select):
    m, n = len(matrix), len(matrix[0])
    max_covered = 0
    for i in range(1 << n):
        if bin(i).count('1') == num_select:
            covered = 0
            for row in range(m):
                for col in range(n):
                    if matrix[row][col] == 1 and i & (1 << col):
                        covered += 1
                        break
            max_covered = max(max_covered, covered)
    return max_covered
```
The algorithm is a brute-force method that iterates through all possible combinations of columns (there are 2^n total combinations), as these are represented by binary numbers from 0 to 2^n-1. After selecting a column combination, that is, when the number of set bits (1s) in this combination is equal to 'num_select', the algorithm iterates through the rows and checks if that row is covered by the selected columns. The maximum number of rows covered for all column combinations is then returned.

## A solution in Javascript

```javascript
function maxCoveredRows(matrix, numSelect) {
    const m = matrix.length;
    const n = matrix[0].length;
    let maxCovered = 0;

    for (let i = 0; i < (1 << n); ++i) {
        if (i.toString(2).split('1').length - 1 === numSelect) {
            let covered = 0;
            for (let row = 0; row < m; ++row) {
                for (let col = 0; col < n; ++col) {
                    if ((matrix[row][col] === 1) && (i & (1 << col))) {
                        covered++;
                        break;
                    }
                }
            }
            maxCovered = Math.max(maxCovered, covered);
        }
    }
    return maxCovered;
}
```
The algorithm is a brute-force method that iterates through all possible combinations of columns (there are 2^n total combinations), as these are represented by binary numbers from 0 to 2^n-1. After selecting a column combination, that is, when the number of set bits (1s) in this combination is equal to 'num_select', the algorithm iterates through the rows and checks if that row is covered by the selected columns. The maximum number of rows covered for all column combinations is then returned.


# Maximum Number of Robots Within Budget

- slug: maximum-number-of-robots-within-budget
- difficulty: Hard

You have `n` robots. You are given two **0-indexed** integer arrays, `chargeTimes` and `runningCosts`, both of length `n`. The `ith` robot costs `chargeTimes[i]` units to charge and costs `runningCosts[i]` units to run. You are also given an integer `budget`.

The **total cost** of running `k` chosen robots is equal to `max(chargeTimes) + k * sum(runningCosts)`, where `max(chargeTimes)` is the largest charge cost among the `k` robots and `sum(runningCosts)` is the sum of running costs among the `k` robots.

Return _the **maximum** number of **consecutive** robots you can run such that the total cost **does not** exceed_ `budget`.

**Example 1:**

**Input:** chargeTimes = \[3,6,1,3,4\], runningCosts = \[2,1,3,4,5\], budget = 25
**Output:** 3
**Explanation:**
It is possible to run all individual and consecutive pairs of robots within budget.
To obtain answer 3, consider the first 3 robots. The total cost will be max(3,6,1) + 3 \* sum(2,1,3) = 6 + 3 \* 6 = 24 which is less than 25.
It can be shown that it is not possible to run more than 3 consecutive robots within budget, so we return 3.

**Example 2:**

**Input:** chargeTimes = \[11,12,19\], runningCosts = \[10,8,7\], budget = 19
**Output:** 0
**Explanation:** No robot can be run that does not exceed the budget, so we return 0.

**Constraints:**

*   `chargeTimes.length == runningCosts.length == n`
*   `1 <= n <= 5 * 104`
*   `1 <= chargeTimes[i], runningCosts[i] <= 105`
*   `1 <= budget <= 1015`

## A solution in Java

```java
public int maxConsecutiveRobots(int[] chargeTimes, int[] runningCosts, long budget) {
    int n = chargeTimes.length;
    int maxRobots = 0;
    for (int i = 0; i < n; i++) {
        int maxCharge = 0;
        long runningSum = 0;
        for (int j = i; j < n; j++) {
            maxCharge = Math.max(maxCharge, chargeTimes[j]);
            runningSum += runningCosts[j];
            long cost = maxCharge + runningSum * (j - i + 1);
            if (cost <= budget)
                maxRobots = Math.max(maxRobots, j - i + 1);
            else
                break;
        }
    }
    return maxRobots;
}
```
1. Initialize `maxRobots` as 0
2. Iterate from the first robot to the last robot as the starting point (`i`)
3. Initialize `maxCharge` as 0 (to store the maximum charge cost) and `runningSum` as 0 (to store the sum of running costs)
4. Iterate from the starting point robot to the last robot (`j`)
5. Update `maxCharge` and `runningSum`
6. Calculate the total cost (`cost`) by `maxCharge + runningSum * (j - i + 1)`
7. If the total cost is less than or equal to the budget, update `maxRobots` as the maximum of `maxRobots` and `j - i + 1`
8. If the total cost exceeds the budget, break the inner loop
9. Continue the outer loop
10. Return `maxRobots` as the maximum number of consecutive robots that can be run within the budget.

## A solution in C++

```cpp
int maxConsecutiveRobots(vector<int>& chargeTimes, vector<int>& runningCosts, long long budget) {
    int n = chargeTimes.size();
    int maxRobots = 0;
    for (int i = 0; i < n; i++) {
        int maxCharge = 0;
        long long runningSum = 0;
        for (int j = i; j < n; j++) {
            maxCharge = max(maxCharge, chargeTimes[j]);
            runningSum += runningCosts[j];
            long long cost = maxCharge + runningSum * (j - i + 1);
            if (cost <= budget)
                maxRobots = max(maxRobots, j - i + 1);
            else
                break;
        }
    }
    return maxRobots;
}
```
1. Initialize `maxRobots` as 0
2. Iterate from the first robot to the last robot as the starting point (`i`)
3. Initialize `maxCharge` as 0 (to store the maximum charge cost) and `runningSum` as 0 (to store the sum of running costs)
4. Iterate from the starting point robot to the last robot (`j`)
5. Update `maxCharge` and `runningSum`
6. Calculate the total cost (`cost`) by `maxCharge + runningSum * (j - i + 1)`
7. If the total cost is less than or equal to the budget, update `maxRobots` as the maximum of `maxRobots` and `j - i + 1`
8. If the total cost exceeds the budget, break the inner loop
9. Continue the outer loop
10. Return `maxRobots` as the maximum number of consecutive robots that can be run within the budget.

## A solution in Python

```python
def max_consecutive_robots(charge_times, running_costs, budget):
    n = len(charge_times)
    max_robots = 0
    for i in range(n):
        max_charge = 0
        running_sum = 0
        for j in range(i, n):
            max_charge = max(max_charge, charge_times[j])
            running_sum += running_costs[j]
            cost = max_charge + running_sum * (j - i + 1)
            if cost <= budget:
                max_robots = max(max_robots, j - i + 1)
            else:
                break
    return max_robots
```
1. Initialize `maxRobots` as 0
2. Iterate from the first robot to the last robot as the starting point (`i`)
3. Initialize `maxCharge` as 0 (to store the maximum charge cost) and `runningSum` as 0 (to store the sum of running costs)
4. Iterate from the starting point robot to the last robot (`j`)
5. Update `maxCharge` and `runningSum`
6. Calculate the total cost (`cost`) by `maxCharge + runningSum * (j - i + 1)`
7. If the total cost is less than or equal to the budget, update `maxRobots` as the maximum of `maxRobots` and `j - i + 1`
8. If the total cost exceeds the budget, break the inner loop
9. Continue the outer loop
10. Return `maxRobots` as the maximum number of consecutive robots that can be run within the budget.

## A solution in Javascript

```javascript
function maxConsecutiveRobots(chargeTimes, runningCosts, budget) {
    const n = chargeTimes.length;
    let maxRobots = 0;
    for (let i = 0; i < n; i++) {
        let maxCharge = 0;
        let runningSum = 0;
        for (let j = i; j < n; j++) {
            maxCharge = Math.max(maxCharge, chargeTimes[j]);
            runningSum += runningCosts[j];
            const cost = maxCharge + runningSum * (j - i + 1);
            if (cost <= budget)
                maxRobots = Math.max(maxRobots, j - i + 1);
            else
                break;
        }
    }
    return maxRobots;
}
```
1. Initialize `maxRobots` as 0
2. Iterate from the first robot to the last robot as the starting point (`i`)
3. Initialize `maxCharge` as 0 (to store the maximum charge cost) and `runningSum` as 0 (to store the sum of running costs)
4. Iterate from the starting point robot to the last robot (`j`)
5. Update `maxCharge` and `runningSum`
6. Calculate the total cost (`cost`) by `maxCharge + runningSum * (j - i + 1)`
7. If the total cost is less than or equal to the budget, update `maxRobots` as the maximum of `maxRobots` and `j - i + 1`
8. If the total cost exceeds the budget, break the inner loop
9. Continue the outer loop
10. Return `maxRobots` as the maximum number of consecutive robots that can be run within the budget.


# Check Distances Between Same Letters

- slug: check-distances-between-same-letters
- difficulty: Easy

You are given a **0-indexed** string `s` consisting of only lowercase English letters, where each letter in `s` appears **exactly** **twice**. You are also given a **0-indexed** integer array `distance` of length `26`.

Each letter in the alphabet is numbered from `0` to `25` (i.e. `'a' -> 0`, `'b' -> 1`, `'c' -> 2`, ... , `'z' -> 25`).

In a **well-spaced** string, the number of letters between the two occurrences of the `ith` letter is `distance[i]`. If the `ith` letter does not appear in `s`, then `distance[i]` can be **ignored**.

Return `true` _if_ `s` _is a **well-spaced** string, otherwise return_ `false`.

**Example 1:**

**Input:** s =  "abaccb ", distance = \[1,3,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\]
**Output:** true
**Explanation:**
- 'a' appears at indices 0 and 2 so it satisfies distance\[0\] = 1.
- 'b' appears at indices 1 and 5 so it satisfies distance\[1\] = 3.
- 'c' appears at indices 3 and 4 so it satisfies distance\[2\] = 0.
Note that distance\[3\] = 5, but since 'd' does not appear in s, it can be ignored.
Return true because s is a well-spaced string.

**Example 2:**

**Input:** s =  "aa ", distance = \[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\]
**Output:** false
**Explanation:**
- 'a' appears at indices 0 and 1 so there are zero letters between them.
Because distance\[0\] = 1, s is not a well-spaced string.

**Constraints:**

*   `2 <= s.length <= 52`
*   `s` consists only of lowercase English letters.
*   Each letter appears in `s` exactly twice.
*   `distance.length == 26`
*   `0 <= distance[i] <= 50`

## A solution in Java

```java
public boolean wellSpacedString(String s, int[] distance) {
    Integer[] first = new Integer[26];
    for (int i = 0; i < s.length(); ++i) {
        char c = s.charAt(i);
        if (first[c - 'a'] == null) {
            first[c - 'a'] = i;
        } else {
            if (distance[c - 'a'] != i - first[c - 'a'] - 1) {
                return false;
            }
        }
    }
    return true;
}
```
The algorithm iterates through the characters of the given string `s`. If it encounters a character for the first time, it stores the character along with its index in a map `first`. If it encounters the character for the second time, it checks whether the difference between the current index and the first occurrence of the character minus 1 is equal to the required distance given in the `distance` array. If this condition is not met, the function returns `false`. If the iteration is completed without failing the condition, the function returns `true`.

## A solution in C++

```cpp
bool wellSpacedString(std::string s, std::vector<int> distance) {
    std::unordered_map<char, int> first;
    for (int i = 0; i < s.size(); ++i) {
        char c = s[i];
        if (first.find(c) == first.end()) {
            first[c] = i;
        } else {
            if (distance[c - 'a'] != i - first[c] - 1) {
                return false;
            }
        }
    }
    return true;
}
```
The algorithm iterates through the characters of the given string `s`. If it encounters a character for the first time, it stores the character along with its index in a map `first`. If it encounters the character for the second time, it checks whether the difference between the current index and the first occurrence of the character minus 1 is equal to the required distance given in the `distance` array. If this condition is not met, the function returns `false`. If the iteration is completed without failing the condition, the function returns `true`.

## A solution in Python

```python
def well_spaced_string(s: str, distance: List[int]) -> bool:
    first = {}
    for i, c in enumerate(s):
        if c not in first:
            first[c] = i
        else:
            if distance[ord(c) - ord('a')] != i - first[c] - 1:
                return False
    return True
```
The algorithm iterates through the characters of the given string `s`. If it encounters a character for the first time, it stores the character along with its index in a map `first`. If it encounters the character for the second time, it checks whether the difference between the current index and the first occurrence of the character minus 1 is equal to the required distance given in the `distance` array. If this condition is not met, the function returns `false`. If the iteration is completed without failing the condition, the function returns `true`.

## A solution in Javascript

```javascript
function wellSpacedString(s, distance) {
    const first = {};
    for (let i = 0; i < s.length; ++i) {
        const c = s[i];
        if (c in first === false) {
            first[c] = i;
        } else {
            if (distance[c.charCodeAt(0) - 'a'.charCodeAt(0)] !== i - first[c] - 1) {
                return false;
            }
        }
    }
    return true;
}
```
The algorithm iterates through the characters of the given string `s`. If it encounters a character for the first time, it stores the character along with its index in a map `first`. If it encounters the character for the second time, it checks whether the difference between the current index and the first occurrence of the character minus 1 is equal to the required distance given in the `distance` array. If this condition is not met, the function returns `false`. If the iteration is completed without failing the condition, the function returns `true`.


# Number of Ways to Reach a Position After Exactly k Steps

- slug: number-of-ways-to-reach-a-position-after-exactly-k-steps
- difficulty: Medium

You are given two **positive** integers `startPos` and `endPos`. Initially, you are standing at position `startPos` on an **infinite** number line. With one step, you can move either one position to the left, or one position to the right.

Given a positive integer `k`, return _the number of **different** ways to reach the position_ `endPos` _starting from_ `startPos`_, such that you perform **exactly**_ `k` _steps_. Since the answer may be very large, return it **modulo** `109 + 7`.

Two ways are considered different if the order of the steps made is not exactly the same.

**Note** that the number line includes negative integers.

**Example 1:**

**Input:** startPos = 1, endPos = 2, k = 3
**Output:** 3
**Explanation:** We can reach position 2 from 1 in exactly 3 steps in three ways:
- 1 -> 2 -> 3 -> 2.
- 1 -> 2 -> 1 -> 2.
- 1 -> 0 -> 1 -> 2.
It can be proven that no other way is possible, so we return 3.

**Example 2:**

**Input:** startPos = 2, endPos = 5, k = 10
**Output:** 0
**Explanation:** It is impossible to reach position 5 from position 2 in exactly 10 steps.

**Constraints:**

*   `1 <= startPos, endPos, k <= 1000`

## A solution in Java

```java
final int MOD = 1000000007;
final int MAX = 1001;

int ways(int startPos, int endPos, int k, int[][] dp) {
    if (k == 0) return startPos == endPos ? 1 : 0;
    if (startPos < 0 || endPos < 0 || startPos >= MAX || endPos >= MAX) return 0;

    if (dp[startPos][k] != -1) return dp[startPos][k];

    int left = ways(startPos - 1, endPos, k - 1, dp);
    int right = ways(startPos + 1, endPos, k - 1, dp);

    return dp[startPos][k] = (left + right) % MOD;
}

int numberOfWays(int startPos, int endPos, int k) {
    int[][] dp = new int[MAX][k + 1];
    for (int[] row : dp) Arrays.fill(row, -1);
    return ways(startPos, endPos, k, dp);
}
```
The problem can be solved using dynamic programming. We can create a helper function `ways(startPos, endPos, k, dp)` to calculate the number of different ways to reach the position `endPos` from `startPos` with `k` steps remaining. The `dp` parameter is a memoization table, and stores the calculated results.

The base condition of the recursion is when `k == 0`, which means we have used up all our steps. If `startPos` is equal to `endPos`, it means we have reached the desired position using `k` steps, and we return 1, otherwise, we return 0.

If `startPos` or `endPos` is out of the given bounds, we return 0 as it is not possible to reach the destination in that case.

We check if the current state (`startPos` and `k`) has already been calculated, if so, we return the value from the memoization table.

We make a recursive call by moving one step to the left (`ways(startPos - 1, endPos, k - 1, dp)`), and one step to the right (`ways(startPos + 1, endPos, k - 1, dp)`), and sum the results modulo `MOD`. This sum represents the number of different ways to reach `endPos` from current `startPos` with remaining `k` steps.

We store and return the calculated result for the current state (`startPos` and `k`) in the memoization table.

The main `numberOfWays` function just initializes the memoization table `dp` and calls the `ways` function with the given input parameters.

## A solution in C++

```cpp
const int MOD = 1e9 + 7;
const int MAX = 1001;

int ways(int startPos, int endPos, int k, vector<vector<int>>& dp) {
    if (k == 0) return startPos == endPos;
    if (startPos < 0 || endPos < 0 || startPos >= MAX || endPos >= MAX) return 0;

    if (dp[startPos][k] != -1) return dp[startPos][k];

    int left = ways(startPos - 1, endPos, k - 1, dp);
    int right = ways(startPos + 1, endPos, k - 1, dp);

    return dp[startPos][k] = (left + right) % MOD;
}

int numberOfWays(int startPos, int endPos, int k) {
    vector<vector<int>> dp(MAX, vector<int>(k + 1, -1));
    return ways(startPos, endPos, k, dp);
}
```
The problem can be solved using dynamic programming. We can create a helper function `ways(startPos, endPos, k, dp)` to calculate the number of different ways to reach the position `endPos` from `startPos` with `k` steps remaining. The `dp` parameter is a memoization table, and stores the calculated results.

The base condition of the recursion is when `k == 0`, which means we have used up all our steps. If `startPos` is equal to `endPos`, it means we have reached the desired position using `k` steps, and we return 1, otherwise, we return 0.

If `startPos` or `endPos` is out of the given bounds, we return 0 as it is not possible to reach the destination in that case.

We check if the current state (`startPos` and `k`) has already been calculated, if so, we return the value from the memoization table.

We make a recursive call by moving one step to the left (`ways(startPos - 1, endPos, k - 1, dp)`), and one step to the right (`ways(startPos + 1, endPos, k - 1, dp)`), and sum the results modulo `MOD`. This sum represents the number of different ways to reach `endPos` from current `startPos` with remaining `k` steps.

We store and return the calculated result for the current state (`startPos` and `k`) in the memoization table.

The main `numberOfWays` function just initializes the memoization table `dp` and calls the `ways` function with the given input parameters.

## A solution in Python

```python
MOD = 10**9 + 7
MAX = 1001

def ways(startPos, endPos, k, dp):
    if k == 0: return 1 if startPos == endPos else 0
    if startPos < 0 or endPos < 0 or startPos >= MAX or endPos >= MAX: return 0

    if dp[startPos][k] != -1: return dp[startPos][k]

    left = ways(startPos - 1, endPos, k - 1, dp)
    right = ways(startPos + 1, endPos, k - 1, dp)

    dp[startPos][k] = (left + right) % MOD
    return dp[startPos][k]

def numberOfWays(startPos, endPos, k):
    dp = [[-1 for _ in range(k + 1)] for _ in range(MAX)]
    return ways(startPos, endPos, k, dp)
```
The problem can be solved using dynamic programming. We can create a helper function `ways(startPos, endPos, k, dp)` to calculate the number of different ways to reach the position `endPos` from `startPos` with `k` steps remaining. The `dp` parameter is a memoization table, and stores the calculated results.

The base condition of the recursion is when `k == 0`, which means we have used up all our steps. If `startPos` is equal to `endPos`, it means we have reached the desired position using `k` steps, and we return 1, otherwise, we return 0.

If `startPos` or `endPos` is out of the given bounds, we return 0 as it is not possible to reach the destination in that case.

We check if the current state (`startPos` and `k`) has already been calculated, if so, we return the value from the memoization table.

We make a recursive call by moving one step to the left (`ways(startPos - 1, endPos, k - 1, dp)`), and one step to the right (`ways(startPos + 1, endPos, k - 1, dp)`), and sum the results modulo `MOD`. This sum represents the number of different ways to reach `endPos` from current `startPos` with remaining `k` steps.

We store and return the calculated result for the current state (`startPos` and `k`) in the memoization table.

The main `numberOfWays` function just initializes the memoization table `dp` and calls the `ways` function with the given input parameters.

## A solution in Javascript

```javascript
const MOD = 1e9 + 7;
const MAX = 1001;

function ways(startPos, endPos, k, dp) {
    if (k === 0) return startPos === endPos ? 1 : 0;
    if (startPos < 0 || endPos < 0 || startPos >= MAX || endPos >= MAX) return 0;

    if (dp[startPos][k] !== -1) return dp[startPos][k];

    const left = ways(startPos - 1, endPos, k - 1, dp);
    const right = ways(startPos + 1, endPos, k - 1, dp);

    return dp[startPos][k] = (left + right) % MOD;
}

function numberOfWays(startPos, endPos, k) {
    const dp = Array.from({ length: MAX }, () => Array(k + 1).fill(-1));
    return ways(startPos, endPos, k, dp)
}
```
The problem can be solved using dynamic programming. We can create a helper function `ways(startPos, endPos, k, dp)` to calculate the number of different ways to reach the position `endPos` from `startPos` with `k` steps remaining. The `dp` parameter is a memoization table, and stores the calculated results.

The base condition of the recursion is when `k == 0`, which means we have used up all our steps. If `startPos` is equal to `endPos`, it means we have reached the desired position using `k` steps, and we return 1, otherwise, we return 0.

If `startPos` or `endPos` is out of the given bounds, we return 0 as it is not possible to reach the destination in that case.

We check if the current state (`startPos` and `k`) has already been calculated, if so, we return the value from the memoization table.

We make a recursive call by moving one step to the left (`ways(startPos - 1, endPos, k - 1, dp)`), and one step to the right (`ways(startPos + 1, endPos, k - 1, dp)`), and sum the results modulo `MOD`. This sum represents the number of different ways to reach `endPos` from current `startPos` with remaining `k` steps.

We store and return the calculated result for the current state (`startPos` and `k`) in the memoization table.

The main `numberOfWays` function just initializes the memoization table `dp` and calls the `ways` function with the given input parameters.


# Longest Nice Subarray

- slug: longest-nice-subarray
- difficulty: Medium

You are given an array `nums` consisting of **positive** integers.

We call a subarray of `nums` **nice** if the bitwise **AND** of every pair of elements that are in **different** positions in the subarray is equal to `0`.

Return _the length of the **longest** nice subarray_.

A **subarray** is a **contiguous** part of an array.

**Note** that subarrays of length `1` are always considered nice.

**Example 1:**

**Input:** nums = \[1,3,8,48,10\]
**Output:** 3
**Explanation:** The longest nice subarray is \[3,8,48\]. This subarray satisfies the conditions:
- 3 AND 8 = 0.
- 3 AND 48 = 0.
- 8 AND 48 = 0.
It can be proven that no longer nice subarray can be obtained, so we return 3.

**Example 2:**

**Input:** nums = \[3,1,5,11,13\]
**Output:** 1
**Explanation:** The length of the longest nice subarray is 1. Any subarray of length 1 can be chosen.

**Constraints:**

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

## A solution in Java

```java
public int longestNiceSubarray(int[] nums) {
    int n = nums.length;
    int maxLen = 1;
    for (int i = 0; i < n; i++) {
        int mask = 0;
        for (int j = i; j < n; j++) {
            mask |= nums[j];
            if ((mask & (mask - 1)) == 0) {
                maxLen = Math.max(maxLen, j - i + 1);
            }
        }
    }
    return maxLen;
}
```
The algorithm iterates through all possible subarrays of the input array. For each subarray, a bitwise-OR mask is maintained, such that its bits represent the union of bits in all elements of the subarray. We check if the mask is a power of two (i.e., if there is only one bit set to 1). If the mask is a power of two, that means all bits in every pair of elements in the subarray do not overlap and hence their pairwise bitwise-AND is zero, satisfying the nice subarray condition. In this case, we update the maximum length of the nice subarray.

The time complexity of the algorithm is O(n^2) since we iterate through all possible subarrays. The space complexity is O(1) as we only maintain a mask and max_len.

## A solution in C++

```cpp
int longestNiceSubarray(vector<int>& nums) {
    int n = nums.size();
    int max_len = 1;
    for (int i = 0; i < n; ++i) {
        int mask = 0;
        for (int j = i; j < n; ++j) {
            mask |= nums[j];
            if ((mask & (mask - 1)) == 0) {
                max_len = max(max_len, j - i + 1);
            }
        }
    }
    return max_len;
}
```
The algorithm iterates through all possible subarrays of the input array. For each subarray, a bitwise-OR mask is maintained, such that its bits represent the union of bits in all elements of the subarray. We check if the mask is a power of two (i.e., if there is only one bit set to 1). If the mask is a power of two, that means all bits in every pair of elements in the subarray do not overlap and hence their pairwise bitwise-AND is zero, satisfying the nice subarray condition. In this case, we update the maximum length of the nice subarray.

The time complexity of the algorithm is O(n^2) since we iterate through all possible subarrays. The space complexity is O(1) as we only maintain a mask and max_len.

## A solution in Python

```python
def longestNiceSubarray(nums):
    n = len(nums)
    max_len = 1
    for i in range(n):
        mask = 0
        for j in range(i, n):
            mask |= nums[j]
            if mask & (mask - 1) == 0:
                max_len = max(max_len, j - i + 1)
    return max_len
```
The algorithm iterates through all possible subarrays of the input array. For each subarray, a bitwise-OR mask is maintained, such that its bits represent the union of bits in all elements of the subarray. We check if the mask is a power of two (i.e., if there is only one bit set to 1). If the mask is a power of two, that means all bits in every pair of elements in the subarray do not overlap and hence their pairwise bitwise-AND is zero, satisfying the nice subarray condition. In this case, we update the maximum length of the nice subarray.

The time complexity of the algorithm is O(n^2) since we iterate through all possible subarrays. The space complexity is O(1) as we only maintain a mask and max_len.

## A solution in Javascript

```javascript
function longestNiceSubarray(nums) {
    const n = nums.length;
    let maxLen = 1;
    for (let i = 0; i < n; i++) {
        let mask = 0;
        for (let j = i; j < n; j++) {
            mask |= nums[j];
            if ((mask & (mask - 1)) === 0) {
                maxLen = Math.max(maxLen, j - i + 1);
            }
        }
    }
    return maxLen;
}
```
The algorithm iterates through all possible subarrays of the input array. For each subarray, a bitwise-OR mask is maintained, such that its bits represent the union of bits in all elements of the subarray. We check if the mask is a power of two (i.e., if there is only one bit set to 1). If the mask is a power of two, that means all bits in every pair of elements in the subarray do not overlap and hence their pairwise bitwise-AND is zero, satisfying the nice subarray condition. In this case, we update the maximum length of the nice subarray.

The time complexity of the algorithm is O(n^2) since we iterate through all possible subarrays. The space complexity is O(1) as we only maintain a mask and max_len.