# Generate Random Point in a Circle

- slug: generate-random-point-in-a-circle
- difficulty: Medium

Given the radius and the position of the center of a circle, implement the function `randPoint` which generates a uniform random point inside the circle.

Implement the `Solution` class:

*   `Solution(double radius, double x_center, double y_center)` initializes the object with the radius of the circle `radius` and the position of the center `(x_center, y_center)`.
*   `randPoint()` returns a random point inside the circle. A point on the circumference of the circle is considered to be in the circle. The answer is returned as an array `[x, y]`.

**Example 1:**

**Input**
\[ "Solution ",  "randPoint ",  "randPoint ",  "randPoint "\]
\[\[1.0, 0.0, 0.0\], \[\], \[\], \[\]\]
**Output**
\[null, \[-0.02493, -0.38077\], \[0.82314, 0.38945\], \[0.36572, 0.17248\]\]

**Explanation**
Solution solution = new Solution(1.0, 0.0, 0.0);
solution.randPoint(); // return \[-0.02493, -0.38077\]
solution.randPoint(); // return \[0.82314, 0.38945\]
solution.randPoint(); // return \[0.36572, 0.17248\]

**Constraints:**

*   `0 < radius <= 108`
*   `-107 <= x_center, y_center <= 107`
*   At most `3 * 104` calls will be made to `randPoint`.

## A solution in Java

```java
import java.util.Random;

public class Solution {
    private double radius;
    private double x_center;
    private double y_center;
    private Random random;

    public Solution(double radius, double x_center, double y_center) {
        this.radius = radius;
        this.x_center = x_center;
        this.y_center = y_center;
        random = new Random();
    }

    public double[] randPoint() {
        double r = Math.sqrt(random.nextDouble()) * radius;
        double theta = random.nextDouble() * 2 * Math.PI;
        return new double[]{x_center + r * Math.cos(theta), y_center + r * Math.sin(theta)};
    }
}
```
We first generate a random radius `r` within the circle by generating a random value between 0 and 1, taking the square root of the value, and multiplying it with the circle's `radius`. We do this sqrt operation because the area of a circle is A=πr², which means that the random point distribution is proportional to r², so the uniform rectilinear random generator is transformed to be a uniform circular one.

Next, we generate a random angle `theta` between 0 and 2π, which represents the angle of the polar coordinate inside the circle.

With the random radius `r` and angle `theta`, we can use trigonometry to calculate the x and y offsets from the circle's center: `r * cos(theta)` for the x-coordinate and `r * sin(theta)` for the y-coordinate.

Finally, we add the circle's x_center and y_center to the x and y offsets to get the absolute x and y coordinate of the random point within the circle.

## A solution in C++

```cpp
#include <random>
#include <cmath>

class Solution {
public:
    std::default_random_engine gen;
    std::uniform_real_distribution<double> dist;
    double radius, x_center, y_center;

    Solution(double radius, double x_center, double y_center): dist(0, 1), radius(radius), x_center(x_center), y_center(y_center) {}

    vector<double> randPoint() {
        double r = sqrt(dist(gen)) * radius;
        double theta = dist(gen) * 2 * M_PI;
        return {x_center + r * cos(theta), y_center + r * sin(theta)};
    }
};
```
We first generate a random radius `r` within the circle by generating a random value between 0 and 1, taking the square root of the value, and multiplying it with the circle's `radius`. We do this sqrt operation because the area of a circle is A=πr², which means that the random point distribution is proportional to r², so the uniform rectilinear random generator is transformed to be a uniform circular one.

Next, we generate a random angle `theta` between 0 and 2π, which represents the angle of the polar coordinate inside the circle.

With the random radius `r` and angle `theta`, we can use trigonometry to calculate the x and y offsets from the circle's center: `r * cos(theta)` for the x-coordinate and `r * sin(theta)` for the y-coordinate.

Finally, we add the circle's x_center and y_center to the x and y offsets to get the absolute x and y coordinate of the random point within the circle.

## A solution in Python

```python
import random
from math import sqrt, pi, cos, sin

class Solution:

    def __init__(self, radius: float, x_center: float, y_center: float):
        self.radius = radius
        self.x_center = x_center
        self.y_center = y_center

    def randPoint(self):
        r = sqrt(random.random()) * self.radius
        theta = random.random() * 2 * pi
        return [self.x_center + r * cos(theta), self.y_center + r * sin(theta)]
```
We first generate a random radius `r` within the circle by generating a random value between 0 and 1, taking the square root of the value, and multiplying it with the circle's `radius`. We do this sqrt operation because the area of a circle is A=πr², which means that the random point distribution is proportional to r², so the uniform rectilinear random generator is transformed to be a uniform circular one.

Next, we generate a random angle `theta` between 0 and 2π, which represents the angle of the polar coordinate inside the circle.

With the random radius `r` and angle `theta`, we can use trigonometry to calculate the x and y offsets from the circle's center: `r * cos(theta)` for the x-coordinate and `r * sin(theta)` for the y-coordinate.

Finally, we add the circle's x_center and y_center to the x and y offsets to get the absolute x and y coordinate of the random point within the circle.

## A solution in Javascript

```javascript
class Solution {
    constructor(radius, x_center, y_center) {
        this.radius = radius;
        this.x_center = x_center;
        this.y_center = y_center;
    }

    randPoint() {
        const r = Math.sqrt(Math.random()) * this.radius;
        const theta = Math.random() * 2 * Math.PI;
        return [this.x_center + r * Math.cos(theta), this.y_center + r * Math.sin(theta)];
    }
}
```
We first generate a random radius `r` within the circle by generating a random value between 0 and 1, taking the square root of the value, and multiplying it with the circle's `radius`. We do this sqrt operation because the area of a circle is A=πr², which means that the random point distribution is proportional to r², so the uniform rectilinear random generator is transformed to be a uniform circular one.

Next, we generate a random angle `theta` between 0 and 2π, which represents the angle of the polar coordinate inside the circle.

With the random radius `r` and angle `theta`, we can use trigonometry to calculate the x and y offsets from the circle's center: `r * cos(theta)` for the x-coordinate and `r * sin(theta)` for the y-coordinate.

Finally, we add the circle's x_center and y_center to the x and y offsets to get the absolute x and y coordinate of the random point within the circle.


# Largest Palindrome Product

- slug: largest-palindrome-product
- difficulty: Hard

Given an integer n, return _the **largest palindromic integer** that can be represented as the product of two `n`\-digits integers_. Since the answer can be very large, return it **modulo** `1337`.

**Example 1:**

**Input:** n = 2
**Output:** 987
Explanation: 99 x 91 = 9009, 9009 % 1337 = 987

**Example 2:**

**Input:** n = 1
**Output:** 9

**Constraints:**

*   `1 <= n <= 8`

## A solution in Java

```java
int largestPalindrome(int n) {
    if (n == 1) return 9;
    int upper_limit = (int) Math.pow(10, n) - 1;
    int lower_limit = upper_limit / 10;
    for (int i = upper_limit; i > lower_limit; --i) {
        long temp = i;
        long reverse = 0;
        while (temp != 0) {
            reverse = reverse * 10 + temp % 10;
            temp /= 10;
        }
        long palindrome = i * (long) Math.pow(10, n) + reverse;
        for (long j = upper_limit; j > lower_limit; --j) {
            long product = palindrome / j;
            if (palindrome % j == 0 && product <= upper_limit) {
                return (int) (palindrome % 1337);
            }
        }
    }
    return -1;
}
```
1. If n is 1, return 9 (the largest palindromic product of two 1-digit numbers is 9).
2. Calculate the upper and lower limits for the n-digit numbers.
3. Loop through the numbers in reverse order, starting from the upper limit down to the lower limit.
4. Within the loop, find the reverse of the current iteration number.
5. Calculate the possible palindrome by concatenating the current number and its reverse.
6. Loop through the numbers again to find the two factors of the palindrome.
7. If a palindrome with valid factors is found, return the palindrome modulo 1337.
8. If no such palindrome is found, return -1.

## A solution in C++

```cpp
int largestPalindrome(int n) {
    if (n == 1) return 9;
    int upper_limit = pow(10, n) - 1;
    int lower_limit = upper_limit / 10;
    for (int i = upper_limit; i > lower_limit; --i) {
        long long temp = i;
        long long reverse = 0;
        while (temp != 0) {
            reverse = reverse * 10 + temp % 10;
            temp /= 10;
        }
        long long palindrome = i * pow(10, n) + reverse;
        for (long long j = upper_limit; j > lower_limit; --j) {
            long long product = palindrome / j;
            if (palindrome % j == 0 && product <= upper_limit) {
                return palindrome % 1337;
            }
        }
    }
    return -1;
}
```
1. If n is 1, return 9 (the largest palindromic product of two 1-digit numbers is 9).
2. Calculate the upper and lower limits for the n-digit numbers.
3. Loop through the numbers in reverse order, starting from the upper limit down to the lower limit.
4. Within the loop, find the reverse of the current iteration number.
5. Calculate the possible palindrome by concatenating the current number and its reverse.
6. Loop through the numbers again to find the two factors of the palindrome.
7. If a palindrome with valid factors is found, return the palindrome modulo 1337.
8. If no such palindrome is found, return -1.

## A solution in Python

```python
def largestPalindrome(n):
    if n == 1:
        return 9
    upper_limit = 10**n - 1
    lower_limit = upper_limit // 10
    for i in range(upper_limit, lower_limit, -1):
        temp = i
        reverse = 0
        while temp != 0:
            reverse = reverse * 10 + temp % 10
            temp //= 10
        palindrome = i * (10**n) + reverse
        for j in range(upper_limit, lower_limit, -1):
            product = palindrome // j
            if palindrome % j == 0 and product <= upper_limit:
                return palindrome % 1337
    return -1
```
1. If n is 1, return 9 (the largest palindromic product of two 1-digit numbers is 9).
2. Calculate the upper and lower limits for the n-digit numbers.
3. Loop through the numbers in reverse order, starting from the upper limit down to the lower limit.
4. Within the loop, find the reverse of the current iteration number.
5. Calculate the possible palindrome by concatenating the current number and its reverse.
6. Loop through the numbers again to find the two factors of the palindrome.
7. If a palindrome with valid factors is found, return the palindrome modulo 1337.
8. If no such palindrome is found, return -1.

## A solution in Javascript

```javascript
function largestPalindrome(n) {
    if (n === 1) return 9; // Handle 1-digit numbers
    let upper_limit = Math.pow(10, n) - 1;
    let lower_limit = Math.floor(upper_limit / 10);
    for (let i = upper_limit; i > lower_limit; i--) {
        let temp = i;
        let reverse = 0;
        while (temp !== 0) {
            reverse = reverse * 10 + temp % 10;
            temp = Math.floor(temp / 10);
        }
        let palindrome = i * Math.pow(10, n) + reverse;
        for (let j = upper_limit; j > lower_limit; j--) {
            let product = Math.floor(palindrome / j);
            if (palindrome % j === 0 && product <= upper_limit) {
                return palindrome % 1337;
            }
        }
    }
    return -1;
}
```
1. If n is 1, return 9 (the largest palindromic product of two 1-digit numbers is 9).
2. Calculate the upper and lower limits for the n-digit numbers.
3. Loop through the numbers in reverse order, starting from the upper limit down to the lower limit.
4. Within the loop, find the reverse of the current iteration number.
5. Calculate the possible palindrome by concatenating the current number and its reverse.
6. Loop through the numbers again to find the two factors of the palindrome.
7. If a palindrome with valid factors is found, return the palindrome modulo 1337.
8. If no such palindrome is found, return -1.


# Sliding Window Median

- slug: sliding-window-median
- difficulty: Hard

The **median** is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle values.

*   For examples, if `arr = [2,3,4]`, the median is `3`.
*   For examples, if `arr = [1,2,3,4]`, the median is `(2 + 3) / 2 = 2.5`.

You are given an integer array `nums` and an integer `k`. There is a sliding window of size `k` which is moving from the very left of the array to the very right. You can only see the `k` numbers in the window. Each time the sliding window moves right by one position.

Return _the median array for each window in the original array_. Answers within `10-5` of the actual value will be accepted.

**Example 1:**

**Input:** nums = \[1,3,-1,-3,5,3,6,7\], k = 3
**Output:** \[1.00000,-1.00000,-1.00000,3.00000,5.00000,6.00000\]
**Explanation:**
Window position                Median
---------------                -----
\[**1  3  -1**\] -3  5  3  6  7        1
 1 \[**3  -1  -3**\] 5  3  6  7       -1
 1  3 \[**\-1  -3  5**\] 3  6  7       -1
 1  3  -1 \[**\-3  5  3**\] 6  7        3
 1  3  -1  -3 \[**5  3  6**\] 7        5
 1  3  -1  -3  5 \[**3  6  7**\]       6

**Example 2:**

**Input:** nums = \[1,2,3,4,2,3,1,4,2\], k = 3
**Output:** \[2.00000,3.00000,3.00000,3.00000,2.00000,3.00000,2.00000\]

**Constraints:**

*   `1 <= k <= nums.length <= 105`
*   `-231 <= nums[i] <= 231 - 1`

## A solution in Java

```java
import java.util.TreeMap;

public double[] medianSlidingWindow(int[] nums, int k) {
    TreeMap<Integer, Integer> window = new TreeMap<>();
    int n = nums.length;
    double[] result = new double[n - k + 1];

    for (int i = 0; i < k; i++) {
        window.put(nums[i], window.getOrDefault(nums[i], 0) + 1);
    }

    for (int i = k; i <= n; i++) {
        int cnt = 0, mid1 = 0, mid2 = 0;
        for (Integer num : window.keySet()) {
            cnt += window.get(num);
            if (cnt >= (k + 1) / 2 && mid1 == 0) {
                mid1 = num;
            }
            if (cnt >= (k + 2) / 2) {
                mid2 = num;
                break;
            }
        }

        result[i - k] = ((double) mid1 + mid2) / 2;

        if (i < n) {
            window.put(nums[i], window.getOrDefault(nums[i], 0) + 1);
            window.put(nums[i - k], window.get(nums[i - k]) - 1);
            if (window.get(nums[i - k]) == 0) {
                window.remove(nums[i - k]);
            }
        }
    }

    return result;
}
```
The algorithm initializes a sliding window of size `k`. The sliding window is used as a data structure that keeps track of the current `k` elements and maintains the ordering of the values, which can be a multiset or sorted list.

Loop through the array from position `k` until the end. For each iteration, calculate the median of the current sliding window. If `k` is even, the median is the mean of the two middle values; if `k` is odd, the median is the middle value. Push the median value into a result array.

Remove the leftmost element of the sliding window (the one that is out of the window now), and insert the next element in the array into the sliding window. Continue this process until the end of the array, and return the result array containing the median values.

This algorithm takes advantage of the ordered data structure to achieve an efficient median retrieval for each sliding window.

## A solution in C++

```cpp
#include <vector>
#include <set>

std::vector<double> medianSlidingWindow(std::vector<int>& nums, int k) {
    std::multiset<int> window(nums.begin(), nums.begin() + k);
    auto mid = std::next(window.begin(), k / 2);
    std::vector<double> medians;

    for (int i = k;; i++) {
        medians.push_back((double(*mid) + *std::prev(mid, 1 - k % 2)) / 2);

        if (i == nums.size()) {
            return medians;
        }
        window.insert(nums[i]);
        if (nums[i] < *mid) {
            mid--;
        }
        if (nums[i - k] <= *mid) {
            mid++;
        }
        window.erase(window.lower_bound(nums[i - k]));
    }
}
```
The algorithm initializes a sliding window of size `k`. The sliding window is used as a data structure that keeps track of the current `k` elements and maintains the ordering of the values, which can be a multiset or sorted list.

Loop through the array from position `k` until the end. For each iteration, calculate the median of the current sliding window. If `k` is even, the median is the mean of the two middle values; if `k` is odd, the median is the middle value. Push the median value into a result array.

Remove the leftmost element of the sliding window (the one that is out of the window now), and insert the next element in the array into the sliding window. Continue this process until the end of the array, and return the result array containing the median values.

This algorithm takes advantage of the ordered data structure to achieve an efficient median retrieval for each sliding window.

## A solution in Python

```python
from sortedcontainers import SortedList

def medianSlidingWindow(nums, k):
    window = SortedList(nums[:k])
    medians = []

    for i in range(k, len(nums) + 1):
        medians.append((window[k // 2 - 1] + window[k // 2]) / 2 if k % 2 == 0 else float(window[k // 2]))

        if i < len(nums):
            window.remove(nums[i - k])
            window.add(nums[i])

    return medians
```
The algorithm initializes a sliding window of size `k`. The sliding window is used as a data structure that keeps track of the current `k` elements and maintains the ordering of the values, which can be a multiset or sorted list.

Loop through the array from position `k` until the end. For each iteration, calculate the median of the current sliding window. If `k` is even, the median is the mean of the two middle values; if `k` is odd, the median is the middle value. Push the median value into a result array.

Remove the leftmost element of the sliding window (the one that is out of the window now), and insert the next element in the array into the sliding window. Continue this process until the end of the array, and return the result array containing the median values.

This algorithm takes advantage of the ordered data structure to achieve an efficient median retrieval for each sliding window.

## A solution in Javascript

```javascript
function medianSlidingWindow(nums, k) {
    const window = new SortedSet();
    const medians = [];

    for (let i = 0; i < k; i++) {
        window.add(nums[i]);
    }

    for (let i = k; i <= nums.length; i++) {
        const mid1 = window.at(Math.floor((k - 1) / 2));
        const mid2 = window.at(Math.floor(k / 2));

        medians.push((mid1 + mid2) / 2);

        if (i < nums.length) {
            window.delete(nums[i - k]);
            window.add(nums[i]);
        }
    }

    return medians;
}
```
The algorithm initializes a sliding window of size `k`. The sliding window is used as a data structure that keeps track of the current `k` elements and maintains the ordering of the values, which can be a multiset or sorted list.

Loop through the array from position `k` until the end. For each iteration, calculate the median of the current sliding window. If `k` is even, the median is the mean of the two middle values; if `k` is odd, the median is the middle value. Push the median value into a result array.

Remove the leftmost element of the sliding window (the one that is out of the window now), and insert the next element in the array into the sliding window. Continue this process until the end of the array, and return the result array containing the median values.

This algorithm takes advantage of the ordered data structure to achieve an efficient median retrieval for each sliding window.


# Magical String

- slug: magical-string
- difficulty: Medium

A magical string `s` consists of only `'1'` and `'2'` and obeys the following rules:

*   The string s is magical because concatenating the number of contiguous occurrences of characters `'1'` and `'2'` generates the string `s` itself.

The first few elements of `s` is `s = "1221121221221121122...... "`. If we group the consecutive `1`'s and `2`'s in `s`, it will be `"1 22 11 2 1 22 1 22 11 2 11 22 ...... "` and the occurrences of `1`'s or `2`'s in each group are `"1 2 2 1 1 2 1 2 2 1 2 2 ...... "`. You can see that the occurrence sequence is `s` itself.

Given an integer `n`, return the number of `1`'s in the first `n` number in the magical string `s`.

**Example 1:**

**Input:** n = 6
**Output:** 3
**Explanation:** The first 6 elements of magical string s is  "122112 " and it contains three 1's, so return 3.

**Example 2:**

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

**Constraints:**

*   `1 <= n <= 105`

## A solution in Java

```java
public int magicalString(int n) {
    if (n == 0) return 0;
    if (n <= 3) return 1;

    int[] magic = new int[n + 1];
    magic[0] = 1;
    magic[1] = 2;
    magic[2] = 2;
    int count_ones = 1;
    int index = 2;
    int value = 1;

    while (index < n) {
        for (int i = 0; i < magic[index] && index < n; i++) {
            magic[++index] = value;
            if (value == 1) count_ones++;
        }
        value = 3 - value;
    }

    return count_ones;
}
```
1. If n is 0, return 0. If n is 1, 2 or 3, return 1.
2. Initialize the magic array with the first 3 elements: [1, 2, 2].
3. Initialize count_ones to 1, index to 2, and value to 1.
4. While the length of the magic array is less than n, loop through the following steps:
   a. Loop from 0 to magic[index] (exclusive), pushing the current value to the magic array.
   b. If the value is 1 and the length of the magic array is less than or equal to n, increment count_ones by 1.
   c. Switch the value between 1 and 2 by setting value to 3 - value.
   d. Increment the index by 1.
5. Return the count_ones variable.

## A solution in C++

```cpp
int magicalString(int n) {
    if (n == 0) return 0;
    if (n <= 3) return 1;

    vector<int> magic = {1, 2, 2};
    int count_ones = 1;
    int index = 2;
    int value = 1;

    while (magic.size() < n) {
        for (int i = 0; i < magic[index]; ++i) {
            magic.push_back(value);
            if (value == 1 && magic.size() <= n) count_ones++;
        }
        value = 3 - value;
        index++;
    }

    return count_ones;
}
```
1. If n is 0, return 0. If n is 1, 2 or 3, return 1.
2. Initialize the magic array with the first 3 elements: [1, 2, 2].
3. Initialize count_ones to 1, index to 2, and value to 1.
4. While the length of the magic array is less than n, loop through the following steps:
   a. Loop from 0 to magic[index] (exclusive), pushing the current value to the magic array.
   b. If the value is 1 and the length of the magic array is less than or equal to n, increment count_ones by 1.
   c. Switch the value between 1 and 2 by setting value to 3 - value.
   d. Increment the index by 1.
5. Return the count_ones variable.

## A solution in Python

```python
def magical_string(n: int) -> int:
    if n == 0:
        return 0
    if n <= 3:
        return 1

    magic = [1, 2, 2]
    count_ones = 1
    index = 2
    value = 1

    while len(magic) < n:
        for _ in range(magic[index]):
            magic.append(value)
            if value == 1 and len(magic) <= n:
                count_ones += 1
        value = 3 - value
        index += 1

    return count_ones
```
1. If n is 0, return 0. If n is 1, 2 or 3, return 1.
2. Initialize the magic array with the first 3 elements: [1, 2, 2].
3. Initialize count_ones to 1, index to 2, and value to 1.
4. While the length of the magic array is less than n, loop through the following steps:
   a. Loop from 0 to magic[index] (exclusive), pushing the current value to the magic array.
   b. If the value is 1 and the length of the magic array is less than or equal to n, increment count_ones by 1.
   c. Switch the value between 1 and 2 by setting value to 3 - value.
   d. Increment the index by 1.
5. Return the count_ones variable.

## A solution in Javascript

```javascript
function magicalString(n) {
    if (n === 0) return 0;
    if (n <= 3) return 1;

    let magic = [1, 2, 2];
    let countOnes = 1;
    let index = 2;
    let value = 1;

    while (magic.length < n) {
        for (let i = 0; i < magic[index]; i++) {
            magic.push(value);
            if (value === 1 && magic.length <= n) countOnes++;
        }
        value = 3 - value;
        index++;
    }

    return countOnes;
}
```
1. If n is 0, return 0. If n is 1, 2 or 3, return 1.
2. Initialize the magic array with the first 3 elements: [1, 2, 2].
3. Initialize count_ones to 1, index to 2, and value to 1.
4. While the length of the magic array is less than n, loop through the following steps:
   a. Loop from 0 to magic[index] (exclusive), pushing the current value to the magic array.
   b. If the value is 1 and the length of the magic array is less than or equal to n, increment count_ones by 1.
   c. Switch the value between 1 and 2 by setting value to 3 - value.
   d. Increment the index by 1.
5. Return the count_ones variable.


# License Key Formatting

- slug: license-key-formatting
- difficulty: Easy

You are given a license key represented as a string `s` that consists of only alphanumeric characters and dashes. The string is separated into `n + 1` groups by `n` dashes. You are also given an integer `k`.

We want to reformat the string `s` such that each group contains exactly `k` characters, except for the first group, which could be shorter than `k` but still must contain at least one character. Furthermore, there must be a dash inserted between two groups, and you should convert all lowercase letters to uppercase.

Return _the reformatted license key_.

**Example 1:**

**Input:** s =  "5F3Z-2e-9-w ", k = 4
**Output:**  "5F3Z-2E9W "
**Explanation:** The string s has been split into two parts, each part has 4 characters.
Note that the two extra dashes are not needed and can be removed.

**Example 2:**

**Input:** s =  "2-5g-3-J ", k = 2
**Output:**  "2-5G-3J "
**Explanation:** The string s has been split into three parts, each part has 2 characters except the first part as it could be shorter as mentioned above.

**Constraints:**

*   `1 <= s.length <= 105`
*   `s` consists of English letters, digits, and dashes `'-'`.
*   `1 <= k <= 104`

## A solution in Java

```java
public String licenseKeyFormatting(String s, int k) {
    StringBuilder result = new StringBuilder();
    int count = 0;
    for (int i = s.length() - 1; i >= 0; i--) {
        if (s.charAt(i) != '-') {
            if (count == k) {
                result.append('-');
                count = 0;
            }
            result.append(Character.toUpperCase(s.charAt(i)));
            count++;
        }
    }
    return result.reverse().toString();
}
```
The algorithm starts by iterating the string s from the end to the beginning, skipping the dashes. During the iteration, we check whether the current group has reached k characters. If so, we append a dash to the result string. We then add the current character, converting it to uppercase, to the result string. After the iteration, we reverse the result string for C++, Java, and Python implementations (for JavaScript, we prepend characters so no need to reverse in the end). This is because we built the reformatted license key in reverse order. Finally, we return the result string.

## A solution in C++

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

string licenseKeyFormatting(string s, int k) {
    string result = "";
    int count = 0;
    for (int i = s.size() - 1; i >= 0; i--) {
        if (s[i] != '-') {
            if (count == k) {
                result.push_back('-');
                count = 0;
            }
            result.push_back(toupper(s[i]));
            count++;
        }
    }
    reverse(result.begin(), result.end());
    return result;
}
```
The algorithm starts by iterating the string s from the end to the beginning, skipping the dashes. During the iteration, we check whether the current group has reached k characters. If so, we append a dash to the result string. We then add the current character, converting it to uppercase, to the result string. After the iteration, we reverse the result string for C++, Java, and Python implementations (for JavaScript, we prepend characters so no need to reverse in the end). This is because we built the reformatted license key in reverse order. Finally, we return the result string.

## A solution in Python

```python
def license_key_formatting(s: str, k: int) -> str:
    result = []
    count = 0
    for c in reversed(s):
        if c != '-':
            if count == k:
                result.append('-')
                count = 0
            result.append(c.upper())
            count += 1
    return ''.join(reversed(result))
```
The algorithm starts by iterating the string s from the end to the beginning, skipping the dashes. During the iteration, we check whether the current group has reached k characters. If so, we append a dash to the result string. We then add the current character, converting it to uppercase, to the result string. After the iteration, we reverse the result string for C++, Java, and Python implementations (for JavaScript, we prepend characters so no need to reverse in the end). This is because we built the reformatted license key in reverse order. Finally, we return the result string.

## A solution in Javascript

```javascript
function licenseKeyFormatting(s, k) {
    let result = '';
    let count = 0;
    for (let i = s.length - 1; i >= 0; i--) {
        if (s[i] !== '-') {
            if (count === k) {
                result = '-' + result;
                count = 0;
            }
            result = s[i].toUpperCase() + result;
            count++;
        }
    }
    return result;
}
```
The algorithm starts by iterating the string s from the end to the beginning, skipping the dashes. During the iteration, we check whether the current group has reached k characters. If so, we append a dash to the result string. We then add the current character, converting it to uppercase, to the result string. After the iteration, we reverse the result string for C++, Java, and Python implementations (for JavaScript, we prepend characters so no need to reverse in the end). This is because we built the reformatted license key in reverse order. Finally, we return the result string.


# Smallest Good Base

- slug: smallest-good-base
- difficulty: Hard

Given an integer `n` represented as a string, return _the smallest **good base** of_ `n`.

We call `k >= 2` a **good base** of `n`, if all digits of `n` base `k` are `1`'s.

**Example 1:**

**Input:** n =  "13 "
**Output:**  "3 "
**Explanation:** 13 base 3 is 111.

**Example 2:**

**Input:** n =  "4681 "
**Output:**  "8 "
**Explanation:** 4681 base 8 is 11111.

**Example 3:**

**Input:** n =  "1000000000000000000 "
**Output:**  "999999999999999999 "
**Explanation:** 1000000000000000000 base 999999999999999999 is 11.

**Constraints:**

*   `n` is an integer in the range `[3, 1018]`.
*   `n` does not contain any leading zeros.

## A solution in Java

```java
public class SmallestGoodBase {
    public String smallestGoodBase(String n) {
        long num_n = Long.parseLong(n);

        for(int m = (int)(Math.log(num_n)/Math.log(2)) + 1; m >= 1; m--) {
            long k = (long)Math.pow((double)num_n, 1.0 / m);
            long sum = 0;
            for(int i=0; i <= m; i++) {
                sum = sum * k + 1;
            }
            if(sum == num_n) {
                return String.valueOf(k);
            }
        }

        return "-1";
    }
}
```
1. First we convert the given string `n` into an integer (in respective format for each language)
2. We loop through possible values of `m` (the number of digits in base `k`) in reverse order
3. We calculate the value of `k` using `k = n^(1/m)` (using the power operator `**` in python and JS and `pow` function in C++ and Java)
4. We calculate the sum of the series `k^0 + k^1 + ... + k^m` which will give us the value when all the digits of `n` are 1 in base `k`
5. If the sum of the series is equal to `n`, we found the smallest good base and return it
6. If we haven't found a good base at the end of the loop, return -1 (which shouldn't happen given the problem statement)

## A solution in C++

```cpp
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

ll smallestGoodBase(string n) {
    ll num_n = stoll(n);

    for(int m = log2(num_n) + 1; m >= 1; m--) {
        ll k = pow(num_n, 1.0 / m);
        ll sum = 0;
        for(int i=0; i <= m; i++) {
            sum = sum * k + 1;
        }
        if(sum == num_n) {
            return k;
        }
    }

    return -1;
}
```
1. First we convert the given string `n` into an integer (in respective format for each language)
2. We loop through possible values of `m` (the number of digits in base `k`) in reverse order
3. We calculate the value of `k` using `k = n^(1/m)` (using the power operator `**` in python and JS and `pow` function in C++ and Java)
4. We calculate the sum of the series `k^0 + k^1 + ... + k^m` which will give us the value when all the digits of `n` are 1 in base `k`
5. If the sum of the series is equal to `n`, we found the smallest good base and return it
6. If we haven't found a good base at the end of the loop, return -1 (which shouldn't happen given the problem statement)

## A solution in Python

```python
def smallest_good_base(n: str) -> str:
    num_n = int(n)

    for m in range(int(num_n.bit_length()), 0, -1):
        k = int(num_n ** (1.0 / m))
        if sum(k**i for i in range(m+1)) == num_n:
            return str(k)

    return "-1"
```
1. First we convert the given string `n` into an integer (in respective format for each language)
2. We loop through possible values of `m` (the number of digits in base `k`) in reverse order
3. We calculate the value of `k` using `k = n^(1/m)` (using the power operator `**` in python and JS and `pow` function in C++ and Java)
4. We calculate the sum of the series `k^0 + k^1 + ... + k^m` which will give us the value when all the digits of `n` are 1 in base `k`
5. If the sum of the series is equal to `n`, we found the smallest good base and return it
6. If we haven't found a good base at the end of the loop, return -1 (which shouldn't happen given the problem statement)

## A solution in Javascript

```javascript
function smallestGoodBase(n) {
    const num_n = BigInt(n);

    for(let m = BigInt(Math.floor(Math.log2(Number(n))) + 1); m >= 1; m--) {
        const k = BigInt(Math.floor(num_n ** (1n / m)));
        let sum = 0n;
        for(let i=0n; i <= m; i++) {
            sum = sum * k + 1n;
        }
        if(sum === num_n) {
            return String(k);
        }
    }

    return "-1";
}
```
1. First we convert the given string `n` into an integer (in respective format for each language)
2. We loop through possible values of `m` (the number of digits in base `k`) in reverse order
3. We calculate the value of `k` using `k = n^(1/m)` (using the power operator `**` in python and JS and `pow` function in C++ and Java)
4. We calculate the sum of the series `k^0 + k^1 + ... + k^m` which will give us the value when all the digits of `n` are 1 in base `k`
5. If the sum of the series is equal to `n`, we found the smallest good base and return it
6. If we haven't found a good base at the end of the loop, return -1 (which shouldn't happen given the problem statement)


# Find Permutation

- slug: find-permutation
- difficulty: Medium

A permutation `perm` of `n` integers of all the integers in the range `[1, n]` can be represented as a string `s` of length `n - 1` where:

*   `s[i] == 'I'` if `perm[i] < perm[i + 1]`, and
*   `s[i] == 'D'` if `perm[i] > perm[i + 1]`.

Given a string `s`, reconstruct the lexicographically smallest permutation `perm` and return it.

**Example 1:**

**Input:** s =  "I "
**Output:** \[1,2\]
**Explanation:** \[1,2\] is the only legal permutation that can represented by s, where the number 1 and 2 construct an increasing relationship.

**Example 2:**

**Input:** s =  "DI "
**Output:** \[2,1,3\]
**Explanation:** Both \[2,1,3\] and \[3,1,2\] can be represented as  "DI ", but since we want to find the smallest lexicographical permutation, you should return \[2,1,3\]

**Constraints:**

*   `1 <= s.length <= 105`
*   `s[i]` is either `'I'` or `'D'`.

## A solution in Java

```java
import java.util.*;

class Solution {
    public int[] findPermutation(String s) {
        int[] perm = new int[s.length() + 1];
        int left = 1;
        for(int i = 0; i < s.length(); i++) {
            if(s.charAt(i) == 'I') {
                perm[i] = left++;
                while(i + 1 < s.length() && s.charAt(i + 1) == 'D')
                    i++;
            }
        }
        perm[s.length()] = left++;
        for(int i = s.length() - 1; i >= 0; i--)
            if(s.charAt(i) == 'D')
                perm[i] = left++;
        return perm;
    }
}
```
The algorithm works as follows:

1. Initialize an empty permutation array `perm` of length `n+1` (where `n` is the length of string `s`).
2. Initialize a variable `left` with the value 1. This variable will keep track of the next unused smallest number.
3. Iterate through the given string `s`. If the character at index `i` is 'I', place the value of `left` at the same index in the `perm` array and increment `left`. If there is a sequence of 'D's following current 'I', jump directly to the end of this sequence.
4. After iterating through the whole string, assign the value of `left` to the last position of the `perm` array and increment `left`.
5. Iterate through the string `s` in reverse order. If the character at index `i` is 'D', place the value of `left` at the same index in the `perm` array and increment `left`.
6. At the end of the process, the filled `perm` array represents the lexicographically smallest permutation.

The time complexity of this algorithm is O(n) as it iterates through the string `s` and fills the `perm` array in linear time.

## A solution in C++

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

std::vector<int> findPermutation(std::string s) {
    std::vector<int> perm(s.length() + 1);
    int left = 1;
    for(int i = 0; i < s.length(); i++) {
        if(s[i] == 'I') {
            perm[i] = left++;
            while(i + 1 < s.length() && s[i + 1] == 'D')
                i++;
        }
    }
    perm[s.length()] = left++;
    for(int i = s.length() - 1; i >= 0; i--)
        if(s[i] == 'D')
            perm[i] = left++;
    return perm;
}
```
The algorithm works as follows:

1. Initialize an empty permutation array `perm` of length `n+1` (where `n` is the length of string `s`).
2. Initialize a variable `left` with the value 1. This variable will keep track of the next unused smallest number.
3. Iterate through the given string `s`. If the character at index `i` is 'I', place the value of `left` at the same index in the `perm` array and increment `left`. If there is a sequence of 'D's following current 'I', jump directly to the end of this sequence.
4. After iterating through the whole string, assign the value of `left` to the last position of the `perm` array and increment `left`.
5. Iterate through the string `s` in reverse order. If the character at index `i` is 'D', place the value of `left` at the same index in the `perm` array and increment `left`.
6. At the end of the process, the filled `perm` array represents the lexicographically smallest permutation.

The time complexity of this algorithm is O(n) as it iterates through the string `s` and fills the `perm` array in linear time.

## A solution in Python

```python
def findPermutation(s: str) -> list[int]:
    perm = [0] * (len(s) + 1)
    left = 1
    i = 0
    while i < len(s):
        if s[i] == 'I':
            perm[i] = left
            left += 1
            while i + 1 < len(s) and s[i + 1] == 'D':
                i += 1
        i += 1
    perm[len(s)] = left
    left += 1
    for i in reversed(range(len(s))):
        if s[i] == 'D':
            perm[i] = left
            left += 1
    return perm
```
The algorithm works as follows:

1. Initialize an empty permutation array `perm` of length `n+1` (where `n` is the length of string `s`).
2. Initialize a variable `left` with the value 1. This variable will keep track of the next unused smallest number.
3. Iterate through the given string `s`. If the character at index `i` is 'I', place the value of `left` at the same index in the `perm` array and increment `left`. If there is a sequence of 'D's following current 'I', jump directly to the end of this sequence.
4. After iterating through the whole string, assign the value of `left` to the last position of the `perm` array and increment `left`.
5. Iterate through the string `s` in reverse order. If the character at index `i` is 'D', place the value of `left` at the same index in the `perm` array and increment `left`.
6. At the end of the process, the filled `perm` array represents the lexicographically smallest permutation.

The time complexity of this algorithm is O(n) as it iterates through the string `s` and fills the `perm` array in linear time.

## A solution in Javascript

```javascript
function findPermutation(s) {
    let perm = new Array(s.length + 1).fill(0);
    let left = 1;
    for(let i = 0; i < s.length; i++) {
        if(s[i] === 'I') {
            perm[i] = left++;
            while(i + 1 < s.length && s[i + 1] === 'D')
                i++;
        }
    }
    perm[s.length] = left++;
    for(let i = s.length - 1; i >= 0; i--)
        if(s[i] === 'D')
            perm[i] = left++;
    return perm;
}
```
The algorithm works as follows:

1. Initialize an empty permutation array `perm` of length `n+1` (where `n` is the length of string `s`).
2. Initialize a variable `left` with the value 1. This variable will keep track of the next unused smallest number.
3. Iterate through the given string `s`. If the character at index `i` is 'I', place the value of `left` at the same index in the `perm` array and increment `left`. If there is a sequence of 'D's following current 'I', jump directly to the end of this sequence.
4. After iterating through the whole string, assign the value of `left` to the last position of the `perm` array and increment `left`.
5. Iterate through the string `s` in reverse order. If the character at index `i` is 'D', place the value of `left` at the same index in the `perm` array and increment `left`.
6. At the end of the process, the filled `perm` array represents the lexicographically smallest permutation.

The time complexity of this algorithm is O(n) as it iterates through the string `s` and fills the `perm` array in linear time.


# Max Consecutive Ones

- slug: max-consecutive-ones
- difficulty: Easy

Given a binary array `nums`, return _the maximum number of consecutive_ `1`_'s in the array_.

**Example 1:**

**Input:** nums = \[1,1,0,1,1,1\]
**Output:** 3
**Explanation:** The first two digits or the last three digits are consecutive 1s. The maximum number of consecutive 1s is 3.

**Example 2:**

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

**Constraints:**

*   `1 <= nums.length <= 105`
*   `nums[i]` is either `0` or `1`.

## A solution in Java

```java
public int findMaxConsecutiveOnes(int[] nums) {
    int maxConsecutive = 0, currentConsecutive = 0;
    for (int num : nums) {
        currentConsecutive = (num == 1) ? currentConsecutive + 1 : 0;
        maxConsecutive = Math.max(maxConsecutive, currentConsecutive);
    }
    return maxConsecutive;
}
```
The algorithm iterates through the given binary array `nums`. For each element, it checks if the current number is 1, then it increments the `current_consecutive` counter; otherwise, it resets the counter to 0. After updating the counter, it compares the current value of `current_consecutive` with the current maximum consecutive ones count (`max_consecutive`) and updates the maximum count if the current count is higher. After iterating through the entire array, the algorithm returns the maximum number of consecutive 1's found.

## A solution in C++

```cpp
int findMaxConsecutiveOnes(vector<int>& nums) {
    int max_consecutive = 0, current_consecutive = 0;
    for (int num : nums) {
        current_consecutive = (num == 1) ? current_consecutive + 1 : 0;
        max_consecutive = max(max_consecutive, current_consecutive);
    }
    return max_consecutive;
}
```
The algorithm iterates through the given binary array `nums`. For each element, it checks if the current number is 1, then it increments the `current_consecutive` counter; otherwise, it resets the counter to 0. After updating the counter, it compares the current value of `current_consecutive` with the current maximum consecutive ones count (`max_consecutive`) and updates the maximum count if the current count is higher. After iterating through the entire array, the algorithm returns the maximum number of consecutive 1's found.

## A solution in Python

```python
def findMaxConsecutiveOnes(nums):
    max_consecutive, current_consecutive = 0, 0
    for num in nums:
        current_consecutive = current_consecutive + 1 if num == 1 else 0
        max_consecutive = max(max_consecutive, current_consecutive)
    return max_consecutive
```
The algorithm iterates through the given binary array `nums`. For each element, it checks if the current number is 1, then it increments the `current_consecutive` counter; otherwise, it resets the counter to 0. After updating the counter, it compares the current value of `current_consecutive` with the current maximum consecutive ones count (`max_consecutive`) and updates the maximum count if the current count is higher. After iterating through the entire array, the algorithm returns the maximum number of consecutive 1's found.

## A solution in Javascript

```javascript
function findMaxConsecutiveOnes(nums) {
    let maxConsecutive = 0, currentConsecutive = 0;
    for (let num of nums) {
        currentConsecutive = (num === 1) ? currentConsecutive + 1 : 0;
        maxConsecutive = Math.max(maxConsecutive, currentConsecutive);
    }
    return maxConsecutive;
}
```
The algorithm iterates through the given binary array `nums`. For each element, it checks if the current number is 1, then it increments the `current_consecutive` counter; otherwise, it resets the counter to 0. After updating the counter, it compares the current value of `current_consecutive` with the current maximum consecutive ones count (`max_consecutive`) and updates the maximum count if the current count is higher. After iterating through the entire array, the algorithm returns the maximum number of consecutive 1's found.


# Predict the Winner

- slug: predict-the-winner
- difficulty: Medium

You are given an integer array `nums`. Two players are playing a game with this array: player 1 and player 2.

Player 1 and player 2 take turns, with player 1 starting first. Both players start the game with a score of `0`. At each turn, the player takes one of the numbers from either end of the array (i.e., `nums[0]` or `nums[nums.length - 1]`) which reduces the size of the array by `1`. The player adds the chosen number to their score. The game ends when there are no more elements in the array.

Return `true` if Player 1 can win the game. If the scores of both players are equal, then player 1 is still the winner, and you should also return `true`. You may assume that both players are playing optimally.

**Example 1:**

**Input:** nums = \[1,5,2\]
**Output:** false
**Explanation:** Initially, player 1 can choose between 1 and 2.
If he chooses 2 (or 1), then player 2 can choose from 1 (or 2) and 5. If player 2 chooses 5, then player 1 will be left with 1 (or 2).
So, final score of player 1 is 1 + 2 = 3, and player 2 is 5.
Hence, player 1 will never be the winner and you need to return false.

**Example 2:**

**Input:** nums = \[1,5,233,7\]
**Output:** true
**Explanation:** Player 1 first chooses 1. Then player 2 has to choose between 5 and 7. No matter which number player 2 choose, player 1 can choose 233.
Finally, player 1 has more score (234) than player 2 (12), so you need to return True representing player1 can win.

**Constraints:**

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

## A solution in Java

```java
public boolean canWin(int[] nums) {
    int n = nums.length;
    int[][] dp = new int[n][n];
    for (int i = 0; i < n; i++) {
        dp[i][i] = nums[i];
    }
    for (int len = 1; len < n; len++) {
        for (int i = 0; i < n - len; i++) {
            int j = i + len;
            dp[i][j] = Math.max(nums[i] - dp[i + 1][j], nums[j] - dp[i][j - 1]);
        }
    }
    return dp[0][n - 1] >= 0;
}
```
We use dynamic programming to solve this problem. We create a 2D table `dp` of size `n x n` where `n` is the length of the input array `nums`. `dp[i][j]` represents the maximum score difference that player 1 can get when playing optimally on the subarray from index `i` to index `j`.

We initialize the diagonal elements of the table: `dp[i][i] = nums[i]`, since if there's only one element left in the game, the player will have to pick it up.

We iterate through the table by fixing the distance `len` between the start and end indices of the subarray. For each subarray `nums[i...j]` where `j = i + len`, player 1 has two choices: picking the first element of the subarray `nums[i]`, or picking the last element of the subarray `nums[j]`. Since both players play optimally, we consider the score difference after player 2 plays their turn. This can be found in the `dp` table from the following subproblems:

1. If player 1 picks `nums[i]`, then the score difference after player 2's turn will be `nums[i] - dp[i + 1][j]`.
2. If player 1 picks `nums[j]`, then the score difference after player 2's turn will be `nums[j] - dp[i][j - 1]`.

We choose the option which gives the maximum score difference for player 1: `dp[i][j] = max(nums[i] - dp[i + 1][j], nums[j] - dp[i][j - 1])`.

Finally, we return `true` if `dp[0][n - 1] >= 0`, which means that player 1 has a score greater than or equal to player 2 when playing optimally on the entire input array. Otherwise, we return `false`.

## A solution in C++

```cpp
#include <vector>

bool canWin(const std::vector<int>& nums) {
    int n = nums.size();
    std::vector<std::vector<int>> dp(n, std::vector<int>(n));
    for (int i = 0; i < n; i++) {
        dp[i][i] = nums[i];
    }
    for (int len = 1; len < n; len++) {
        for (int i = 0; i < n - len; i++) {
            int j = i + len;
            dp[i][j] = std::max(nums[i] - dp[i + 1][j], nums[j] - dp[i][j - 1]);
        }
    }
    return dp[0][n - 1] >= 0;
}
```
We use dynamic programming to solve this problem. We create a 2D table `dp` of size `n x n` where `n` is the length of the input array `nums`. `dp[i][j]` represents the maximum score difference that player 1 can get when playing optimally on the subarray from index `i` to index `j`.

We initialize the diagonal elements of the table: `dp[i][i] = nums[i]`, since if there's only one element left in the game, the player will have to pick it up.

We iterate through the table by fixing the distance `len` between the start and end indices of the subarray. For each subarray `nums[i...j]` where `j = i + len`, player 1 has two choices: picking the first element of the subarray `nums[i]`, or picking the last element of the subarray `nums[j]`. Since both players play optimally, we consider the score difference after player 2 plays their turn. This can be found in the `dp` table from the following subproblems:

1. If player 1 picks `nums[i]`, then the score difference after player 2's turn will be `nums[i] - dp[i + 1][j]`.
2. If player 1 picks `nums[j]`, then the score difference after player 2's turn will be `nums[j] - dp[i][j - 1]`.

We choose the option which gives the maximum score difference for player 1: `dp[i][j] = max(nums[i] - dp[i + 1][j], nums[j] - dp[i][j - 1])`.

Finally, we return `true` if `dp[0][n - 1] >= 0`, which means that player 1 has a score greater than or equal to player 2 when playing optimally on the entire input array. Otherwise, we return `false`.

## A solution in Python

```python
def can_win(nums):
    n = len(nums)
    dp = [[0] * n for _ in range(n)]
    for i in range(n):
        dp[i][i] = nums[i]
    for len in range(1, n):
        for i in range(n - len):
            j = i + len
            dp[i][j] = max(nums[i] - dp[i + 1][j], nums[j] - dp[i][j - 1])
    return dp[0][n - 1] >= 0
```
We use dynamic programming to solve this problem. We create a 2D table `dp` of size `n x n` where `n` is the length of the input array `nums`. `dp[i][j]` represents the maximum score difference that player 1 can get when playing optimally on the subarray from index `i` to index `j`.

We initialize the diagonal elements of the table: `dp[i][i] = nums[i]`, since if there's only one element left in the game, the player will have to pick it up.

We iterate through the table by fixing the distance `len` between the start and end indices of the subarray. For each subarray `nums[i...j]` where `j = i + len`, player 1 has two choices: picking the first element of the subarray `nums[i]`, or picking the last element of the subarray `nums[j]`. Since both players play optimally, we consider the score difference after player 2 plays their turn. This can be found in the `dp` table from the following subproblems:

1. If player 1 picks `nums[i]`, then the score difference after player 2's turn will be `nums[i] - dp[i + 1][j]`.
2. If player 1 picks `nums[j]`, then the score difference after player 2's turn will be `nums[j] - dp[i][j - 1]`.

We choose the option which gives the maximum score difference for player 1: `dp[i][j] = max(nums[i] - dp[i + 1][j], nums[j] - dp[i][j - 1])`.

Finally, we return `true` if `dp[0][n - 1] >= 0`, which means that player 1 has a score greater than or equal to player 2 when playing optimally on the entire input array. Otherwise, we return `false`.

## A solution in Javascript

```javascript
function canWin(nums) {
    const n = nums.length;
    const dp = Array.from({ length: n }, () => Array(n).fill(0));
    for (let i = 0; i < n; i++) {
        dp[i][i] = nums[i];
    }
    for (let len = 1; len < n; len++) {
        for (let i = 0; i < n - len; i++) {
            const j = i + len;
            dp[i][j] = Math.max(nums[i] - dp[i + 1][j], nums[j] - dp[i][j - 1]);
        }
    }
    return dp[0][n - 1] >= 0;
}
```
We use dynamic programming to solve this problem. We create a 2D table `dp` of size `n x n` where `n` is the length of the input array `nums`. `dp[i][j]` represents the maximum score difference that player 1 can get when playing optimally on the subarray from index `i` to index `j`.

We initialize the diagonal elements of the table: `dp[i][i] = nums[i]`, since if there's only one element left in the game, the player will have to pick it up.

We iterate through the table by fixing the distance `len` between the start and end indices of the subarray. For each subarray `nums[i...j]` where `j = i + len`, player 1 has two choices: picking the first element of the subarray `nums[i]`, or picking the last element of the subarray `nums[j]`. Since both players play optimally, we consider the score difference after player 2 plays their turn. This can be found in the `dp` table from the following subproblems:

1. If player 1 picks `nums[i]`, then the score difference after player 2's turn will be `nums[i] - dp[i + 1][j]`.
2. If player 1 picks `nums[j]`, then the score difference after player 2's turn will be `nums[j] - dp[i][j - 1]`.

We choose the option which gives the maximum score difference for player 1: `dp[i][j] = max(nums[i] - dp[i + 1][j], nums[j] - dp[i][j - 1])`.

Finally, we return `true` if `dp[0][n - 1] >= 0`, which means that player 1 has a score greater than or equal to player 2 when playing optimally on the entire input array. Otherwise, we return `false`.


# Max Consecutive Ones II

- slug: max-consecutive-ones-ii
- difficulty: Medium

Given a binary array `nums`, return _the maximum number of consecutive_ `1`_'s in the array if you can flip at most one_ `0`.

**Example 1:**

**Input:** nums = \[1,0,1,1,0\]
**Output:** 4
**Explanation:**
- If we flip the first zero, nums becomes \[1,1,1,1,0\] and we have 4 consecutive ones.
- If we flip the second zero, nums becomes \[1,0,1,1,1\] and we have 3 consecutive ones.
The max number of consecutive ones is 4.

**Example 2:**

**Input:** nums = \[1,0,1,1,0,1\]
**Output:** 4
**Explanation:**
- If we flip the first zero, nums becomes \[1,1,1,1,0,1\] and we have 4 consecutive ones.
- If we flip the second zero, nums becomes \[1,0,1,1,1,1\] and we have 4 consecutive ones.
The max number of consecutive ones is 4.

**Constraints:**

*   `1 <= nums.length <= 105`
*   `nums[i]` is either `0` or `1`.

**Follow up:** What if the input numbers come in one by one as an infinite stream? In other words, you can't store all numbers coming from the stream as it's too large to hold in memory. Could you solve it efficiently?

## A solution in Java

```java
public int findMaxConsecutiveOnes(int[] nums) {
    int maxCount = 0, countZeros = 0, left = 0;
    for (int right = 0; right < nums.length; ++right) {
        if (nums[right] == 0) countZeros++;
        while (countZeros > 1) {
            if (nums[left++] == 0) countZeros--;
        }
        maxCount = Math.max(maxCount, right - left + 1);
    }
    return maxCount;
}
```
We can use the sliding window technique to solve this problem. We maintain a window, and traverse through the array from the left side to the right side. When we find a 0, we increment the count of zeros in the window. If the count of zeros is greater than 1, we remove elements from the left side of the window until we have only 1 zero in the window. This way, we make sure we calculate the maximum number of consecutive ones when a single zero is flipped.

For each window, we update the maximum consecutive ones by comparing the current window size (right - left + 1) with max_count.

In the follow-up case where the input numbers come in one by one as an infinite stream, we can still use the same sliding window technique efficiently. We don't need to store all numbers, as we only need to store the current window of numbers which has at most size N (in the worst case where all numbers are 1). The time complexity is O(N) for the entire stream of numbers.

## A solution in C++

```cpp
int findMaxConsecutiveOnes(vector<int>& nums) {
    int max_count = 0, count_zeros = 0, left = 0;
    for (int right = 0; right < nums.size(); ++right) {
        if (nums[right] == 0) count_zeros++;
        while (count_zeros > 1) {
            if (nums[left++] == 0) count_zeros--;
        }
        max_count = max(max_count, right - left + 1);
    }
    return max_count;
}
```
We can use the sliding window technique to solve this problem. We maintain a window, and traverse through the array from the left side to the right side. When we find a 0, we increment the count of zeros in the window. If the count of zeros is greater than 1, we remove elements from the left side of the window until we have only 1 zero in the window. This way, we make sure we calculate the maximum number of consecutive ones when a single zero is flipped.

For each window, we update the maximum consecutive ones by comparing the current window size (right - left + 1) with max_count.

In the follow-up case where the input numbers come in one by one as an infinite stream, we can still use the same sliding window technique efficiently. We don't need to store all numbers, as we only need to store the current window of numbers which has at most size N (in the worst case where all numbers are 1). The time complexity is O(N) for the entire stream of numbers.

## A solution in Python

```python
def findMaxConsecutiveOnes(nums: List[int]) -> int:
    max_count, count_zeros, left = 0, 0, 0
    for right in range(len(nums)):
        if nums[right] == 0:
            count_zeros += 1
        while count_zeros > 1:
            if nums[left] == 0:
                count_zeros -= 1
            left += 1
        max_count = max(max_count, right - left + 1)
    return max_count
```
We can use the sliding window technique to solve this problem. We maintain a window, and traverse through the array from the left side to the right side. When we find a 0, we increment the count of zeros in the window. If the count of zeros is greater than 1, we remove elements from the left side of the window until we have only 1 zero in the window. This way, we make sure we calculate the maximum number of consecutive ones when a single zero is flipped.

For each window, we update the maximum consecutive ones by comparing the current window size (right - left + 1) with max_count.

In the follow-up case where the input numbers come in one by one as an infinite stream, we can still use the same sliding window technique efficiently. We don't need to store all numbers, as we only need to store the current window of numbers which has at most size N (in the worst case where all numbers are 1). The time complexity is O(N) for the entire stream of numbers.

## A solution in Javascript

```javascript
function findMaxConsecutiveOnes(nums) {
    let maxCount = 0, countZeros = 0, left = 0;
    for (let right = 0; right < nums.length; ++right) {
        if (nums[right] === 0) countZeros++;
        while (countZeros > 1) {
            if (nums[left++] === 0) countZeros--;
        }
        maxCount = Math.max(maxCount, right - left + 1);
    }
    return maxCount;
}
```
We can use the sliding window technique to solve this problem. We maintain a window, and traverse through the array from the left side to the right side. When we find a 0, we increment the count of zeros in the window. If the count of zeros is greater than 1, we remove elements from the left side of the window until we have only 1 zero in the window. This way, we make sure we calculate the maximum number of consecutive ones when a single zero is flipped.

For each window, we update the maximum consecutive ones by comparing the current window size (right - left + 1) with max_count.

In the follow-up case where the input numbers come in one by one as an infinite stream, we can still use the same sliding window technique efficiently. We don't need to store all numbers, as we only need to store the current window of numbers which has at most size N (in the worst case where all numbers are 1). The time complexity is O(N) for the entire stream of numbers.


# Zuma Game

- slug: zuma-game
- difficulty: Hard

You are playing a variation of the game Zuma.

In this variation of Zuma, there is a **single row** of colored balls on a board, where each ball can be colored red `'R'`, yellow `'Y'`, blue `'B'`, green `'G'`, or white `'W'`. You also have several colored balls in your hand.

Your goal is to **clear all** of the balls from the board. On each turn:

*   Pick **any** ball from your hand and insert it in between two balls in the row or on either end of the row.
*   If there is a group of **three or more consecutive balls** of the **same color**, remove the group of balls from the board.
    *   If this removal causes more groups of three or more of the same color to form, then continue removing each group until there are none left.
*   If there are no more balls on the board, then you win the game.
*   Repeat this process until you either win or do not have any more balls in your hand.

Given a string `board`, representing the row of balls on the board, and a string `hand`, representing the balls in your hand, return _the **minimum** number of balls you have to insert to clear all the balls from the board. If you cannot clear all the balls from the board using the balls in your hand, return_ `-1`.

**Example 1:**

**Input:** board =  "WRRBBW ", hand =  "RB "
**Output:** -1
**Explanation:** It is impossible to clear all the balls. The best you can do is:
- Insert 'R' so the board becomes WRRRBBW. WRRRBBW -> WBBW.
- Insert 'B' so the board becomes WBBBW. WBBBW -> WW.
There are still balls remaining on the board, and you are out of balls to insert.

**Example 2:**

**Input:** board =  "WWRRBBWW ", hand =  "WRBRW "
**Output:** 2
**Explanation:** To make the board empty:
- Insert 'R' so the board becomes WWRRRBBWW. WWRRRBBWW -> WWBBWW.
- Insert 'B' so the board becomes WWBBBWW. WWBBBWW -> WWWW -> empty.
2 balls from your hand were needed to clear the board.

**Example 3:**

**Input:** board =  "G ", hand =  "GGGGG "
**Output:** 2
**Explanation:** To make the board empty:
- Insert 'G' so the board becomes GG.
- Insert 'G' so the board becomes GGG. GGG -> empty.
2 balls from your hand were needed to clear the board.

**Constraints:**

*   `1 <= board.length <= 16`
*   `1 <= hand.length <= 5`
*   `board` and `hand` consist of the characters `'R'`, `'Y'`, `'B'`, `'G'`, and `'W'`.
*   The initial row of balls on the board will **not** have any groups of three or more consecutive balls of the same color.

## A solution in Java

```java
import java.util.*;

class Solution {
    public int findMinStep(String board, String hand) {
        HashMap<Character, Integer> handMap = new HashMap<>();
        for (char c : hand.toCharArray()) handMap.put(c, handMap.getOrDefault(c, 0) + 1);

        return findMinStepHelper(board, new HashMap<String, Integer>(), handMap);
    }

    private int findMinStepHelper(String board, HashMap<String, Integer> memo, HashMap<Character, Integer> hand) {
        if (board.isEmpty()) return 0;
        if (memo.containsKey(board)) return memo.get(board);

        int result = Integer.MAX_VALUE;
        for (int i = 0, j = 0; i < board.length(); i = j) {
            while (j < board.length() && board.charAt(i) == board.charAt(j)) ++j;
            char color = board.charAt(i);
            int required = 3 - (j - i);
            if (hand.getOrDefault(color, 0) >= required) {
                hand.put(color, hand.get(color) - required);
                String nextBoard = board.substring(0, i) + board.substring(j);
                int tmp = findMinStepHelper(nextBoard, memo, hand);
                if (tmp != -1) result = Math.min(result, tmp + required);
                hand.put(color, hand.get(color) + required);
            }
        }

        int res = (result == Integer.MAX_VALUE) ? -1 : result;
        memo.put(board, res);
        return res;
    }
}
```
The algorithm uses a backtracking approach along with memoization. The base case for the recursion is when there is an empty board, in which case the minimum number of balls to clear the board is 0.

The function loops through the board to find sequences of the same color. For each sequence, it calculates the number of balls needed to reach at least 3 in a row. If the required number of balls are available in hand, it removes the required balls from hand and proceeds recursively with the rest of the board.

After the recursive call, the removed balls are added back to the hand.

The memoization is used to store the results of subproblems based on the current state of the board.

The result is -1 if the balls in hand cannot clear the board, otherwise, the minimum number of balls required to clear the board is returned.

## A solution in C++

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

using namespace std;

int find_min_step_helper(string& board, unordered_map<string, int>& memo, unordered_map<char, int>& hand) {
    if (board.empty()) return 0;
    if (memo.count(board)) return memo[board];

    int result = INT_MAX;
    for (int i = 0, j = 0; i < board.size(); i = j) {
        while (j < board.size() and board[i] == board[j]) ++j;
        char color = board[i];
        int required = 3 - (j - i);
        if (hand[color] >= required) {
            hand[color] -= required;
            string next_board = board.substr(0, i) + board.substr(j);
            int tmp = find_min_step_helper(next_board, memo, hand);
            if (tmp != -1) result = min(result, tmp + required);
            hand[color] += required;
        }
    }

    memo[board] = result == INT_MAX ? -1 : result;
    return memo[board];
}

int find_min_step(string board, string hand) {
    unordered_map<char, int> hand_map;
    for (char c : hand) ++hand_map[c];
    unordered_map<string, int> memo;
    return find_min_step_helper(board, memo, hand_map);
}
```
The algorithm uses a backtracking approach along with memoization. The base case for the recursion is when there is an empty board, in which case the minimum number of balls to clear the board is 0.

The function loops through the board to find sequences of the same color. For each sequence, it calculates the number of balls needed to reach at least 3 in a row. If the required number of balls are available in hand, it removes the required balls from hand and proceeds recursively with the rest of the board.

After the recursive call, the removed balls are added back to the hand.

The memoization is used to store the results of subproblems based on the current state of the board.

The result is -1 if the balls in hand cannot clear the board, otherwise, the minimum number of balls required to clear the board is returned.

## A solution in Python

```python
from collections import Counter

def find_min_step(board: str, hand: str) -> int:
    def find_min_step_helper(board, memo, hand):
        if not board:
            return 0
        if board in memo:
            return memo[board]

        result = float('inf')
        i = 0
        while i < len(board):
            j = i
            while j < len(board) and board[i] == board[j]:
                j += 1

            color = board[i]
            required = 3 - (j - i)
            if hand[color] >= required:
                hand[color] -= required
                next_board = board[:i] + board[j:]
                tmp = find_min_step_helper(next_board, memo, hand)
                if tmp != -1:
                    result = min(result, tmp + required)
                hand[color] += required
            i = j

        memo[board] = -1 if result == float('inf') else result
        return memo[board]

    hand_count = Counter(hand)
    memo = {}
    return find_min_step_helper(board, memo, hand_count)
```
The algorithm uses a backtracking approach along with memoization. The base case for the recursion is when there is an empty board, in which case the minimum number of balls to clear the board is 0.

The function loops through the board to find sequences of the same color. For each sequence, it calculates the number of balls needed to reach at least 3 in a row. If the required number of balls are available in hand, it removes the required balls from hand and proceeds recursively with the rest of the board.

After the recursive call, the removed balls are added back to the hand.

The memoization is used to store the results of subproblems based on the current state of the board.

The result is -1 if the balls in hand cannot clear the board, otherwise, the minimum number of balls required to clear the board is returned.

## A solution in Javascript

```javascript
function findMinStep(board, hand) {
    function findMinStepHelper(board, memo, hand) {
        if (board.length === 0) return 0;
        if (memo.has(board)) return memo.get(board);

        let result = Infinity;
        let i = 0;
        while (i < board.length) {
            let j = i;
            while (j < board.length && board[i] === board[j]) j++;

            let color = board[i];
            let required = 3 - (j - i);
            if (hand[color] >= required) {
                hand[color] -= required;
                let nextBoard = board.slice(0, i) + board.slice(j);
                let tmp = findMinStepHelper(nextBoard, memo, hand);
                if (tmp !== -1) result = Math.min(result, tmp + required);
                hand[color] += required;
            }
            i = j;
        }

        let res = (result === Infinity) ? -1 : result;
        memo.set(board, res);
        return res;
    }

    let handMap = {};
    for (let c of hand) handMap[c] = (handMap[c] || 0) + 1;

    return findMinStepHelper(board, new Map(), handMap);
}
```
The algorithm uses a backtracking approach along with memoization. The base case for the recursion is when there is an empty board, in which case the minimum number of balls to clear the board is 0.

The function loops through the board to find sequences of the same color. For each sequence, it calculates the number of balls needed to reach at least 3 in a row. If the required number of balls are available in hand, it removes the required balls from hand and proceeds recursively with the rest of the board.

After the recursive call, the removed balls are added back to the hand.

The memoization is used to store the results of subproblems based on the current state of the board.

The result is -1 if the balls in hand cannot clear the board, otherwise, the minimum number of balls required to clear the board is returned.


# Robot Room Cleaner

- slug: robot-room-cleaner
- difficulty: Hard

You are controlling a robot that is located somewhere in a room. The room is modeled as an `m x n` binary grid where `0` represents a wall and `1` represents an empty slot.

The robot starts at an unknown location in the room that is guaranteed to be empty, and you do not have access to the grid, but you can move the robot using the given API `Robot`.

You are tasked to use the robot to clean the entire room (i.e., clean every empty cell in the room). The robot with the four given APIs can move forward, turn left, or turn right. Each turn is `90` degrees.

When the robot tries to move into a wall cell, its bumper sensor detects the obstacle, and it stays on the current cell.

Design an algorithm to clean the entire room using the following APIs:

interface Robot {
  // returns true if next cell is open and robot moves into the cell.
  // returns false if next cell is obstacle and robot stays on the current cell.
  boolean move();

  // Robot will stay on the same cell after calling turnLeft/turnRight.
  // Each turn will be 90 degrees.
  void turnLeft();
  void turnRight();

  // Clean the current cell.
  void clean();
}

**Note** that the initial direction of the robot will be facing up. You can assume all four edges of the grid are all surrounded by a wall.

**Custom testing:**

The input is only given to initialize the room and the robot's position internally. You must solve this problem "blindfolded ". In other words, you must control the robot using only the four mentioned APIs without knowing the room layout and the initial robot's position.

**Example 1:**

**Input:** room = \[\[1,1,1,1,1,0,1,1\],\[1,1,1,1,1,0,1,1\],\[1,0,1,1,1,1,1,1\],\[0,0,0,1,0,0,0,0\],\[1,1,1,1,1,1,1,1\]\], row = 1, col = 3
**Output:** Robot cleaned all rooms.
**Explanation:** All grids in the room are marked by either 0 or 1.
0 means the cell is blocked, while 1 means the cell is accessible.
The robot initially starts at the position of row=1, col=3.
From the top left corner, its position is one row below and three columns right.

**Example 2:**

**Input:** room = \[\[1\]\], row = 0, col = 0
**Output:** Robot cleaned all rooms.

**Constraints:**

*   `m == room.length`
*   `n == room[i].length`
*   `1 <= m <= 100`
*   `1 <= n <= 200`
*   `room[i][j]` is either `0` or `1`.
*   `0 <= row < m`
*   `0 <= col < n`
*   `room[row][col] == 1`
*   All the empty cells can be visited from the starting position.

## A solution in Java

```java
public class Solution {
    private int comb(int n, int r) {
        if(r > n - r) r = n - r;
        long res = 1;
        for(int i = 1; i <= r; i++) {
            res *= n - r + i;
            res /= i;
        }
        return (int)res;
    }

    public String kthSmallestPath(int[] destination, int k) {
        int row = destination[0];
        int col = destination[1];
        StringBuilder ans = new StringBuilder();

        for(int i = 0; i < row + col; i++) {
            if(row == 0) {
                ans.append('H');
                col--;
            } else if(col == 0) {
                ans.append('V');
                row--;
            } else if(k <= comb(row + col - 1, row - 1)) {
                ans.append('H');
                col--;
            } else {
                ans.append('V');
                k -= comb(row + col - 1, row - 1);
                row--;
            }
        }

        return ans.toString();
    }
}
```
The algorithm starts at the given location and loops through all possible paths until it reaches the destination cell, by only taking a right or down step. At each step, it compares the current path with lexicographically smaller path, and proceeds in either of the directions based on check conditions. In order to get the kth lexicographically smallest instruction, we use mathematical combination method to check if taking the horizontal step satisfies the condition or not. If it does, we take the horizontal step; otherwise, we take the vertical step.

The time complexity of this algorithm is O(row + col), where row and col are the coordinates of the destination cell, because we need to go through entire cells in row and column.

## A solution in C++

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

int comb(int n, int r) {
    if(r > n - r) r = n - r;
    long res = 1;
    for(int i = 1; i <= r; i++) {
        res *= n - r + i;
        res /= i;
    }
    return (int)res;
}

std::string kthSmallestPath(std::vector<int>& destination, int k) {
    int row = destination[0];
    int col = destination[1];
    std::string ans;

    for(int i = 0; i < row + col; i++) {
        if(row == 0) {
            ans += 'H';
            col--;
        } else if(col == 0) {
            ans += 'V';
            row--;
        } else if(k <= comb(row + col - 1, row - 1)) {
            ans += 'H';
            col--;
        } else {
            ans += 'V';
            k -= comb(row + col - 1, row - 1);
            row--;
        }
    }

    return ans;
}
```
The algorithm starts at the given location and loops through all possible paths until it reaches the destination cell, by only taking a right or down step. At each step, it compares the current path with lexicographically smaller path, and proceeds in either of the directions based on check conditions. In order to get the kth lexicographically smallest instruction, we use mathematical combination method to check if taking the horizontal step satisfies the condition or not. If it does, we take the horizontal step; otherwise, we take the vertical step.

The time complexity of this algorithm is O(row + col), where row and col are the coordinates of the destination cell, because we need to go through entire cells in row and column.

## A solution in Python

```python
from math import comb

def kthSmallestPath(destination, k):
    row, col = destination
    ans = ""

    for i in range(row + col):
        if row == 0:
            ans += 'H'
            col -= 1
        elif col == 0:
            ans += 'V'
            row -= 1
        elif k <= comb(row + col - 1, row - 1):
            ans += 'H'
            col -= 1
        else:
            ans += 'V'
            k -= comb(row + col - 1, row - 1)
            row -= 1

    return ans
```
The algorithm starts at the given location and loops through all possible paths until it reaches the destination cell, by only taking a right or down step. At each step, it compares the current path with lexicographically smaller path, and proceeds in either of the directions based on check conditions. In order to get the kth lexicographically smallest instruction, we use mathematical combination method to check if taking the horizontal step satisfies the condition or not. If it does, we take the horizontal step; otherwise, we take the vertical step.

The time complexity of this algorithm is O(row + col), where row and col are the coordinates of the destination cell, because we need to go through entire cells in row and column.

## A solution in Javascript

```javascript
function comb(n, r) {
    if(r > n - r) r = n - r;
    let res = 1;
    for(let i = 1; i <= r; i++) {
        res *= n - r + i;
        res /= i;
    }
    return res;
}

function kthSmallestPath(destination, k) {
    let row = destination[0];
    let col = destination[1];
    let ans = "";

    for(let i = 0; i < row + col; i++) {
        if(row === 0) {
            ans += 'H';
            col--;
        } else if(col === 0) {
            ans += 'V';
            row--;
        } else if(k <= comb(row + col - 1, row - 1)) {
            ans += 'H';
            col--;
        } else {
            ans += 'V';
            k -= comb(row + col - 1, row - 1);
            row--;
        }
    }

    return ans;
}
```
The algorithm starts at the given location and loops through all possible paths until it reaches the destination cell, by only taking a right or down step. At each step, it compares the current path with lexicographically smaller path, and proceeds in either of the directions based on check conditions. In order to get the kth lexicographically smallest instruction, we use mathematical combination method to check if taking the horizontal step satisfies the condition or not. If it does, we take the horizontal step; otherwise, we take the vertical step.

The time complexity of this algorithm is O(row + col), where row and col are the coordinates of the destination cell, because we need to go through entire cells in row and column.


# The Maze

- slug: the-maze
- difficulty: Medium

There is a ball in a `maze` with empty spaces (represented as `0`) and walls (represented as `1`). The ball can go through the empty spaces by rolling **up, down, left or right**, but it won't stop rolling until hitting a wall. When the ball stops, it could choose the next direction.

Given the `m x n` `maze`, the ball's `start` position and the `destination`, where `start = [startrow, startcol]` and `destination = [destinationrow, destinationcol]`, return `true` if the ball can stop at the destination, otherwise return `false`.

You may assume that **the borders of the maze are all walls** (see examples).

**Example 1:**

**Input:** maze = \[\[0,0,1,0,0\],\[0,0,0,0,0\],\[0,0,0,1,0\],\[1,1,0,1,1\],\[0,0,0,0,0\]\], start = \[0,4\], destination = \[4,4\]
**Output:** true
**Explanation:** One possible way is : left -> down -> left -> down -> right -> down -> right.

**Example 2:**

**Input:** maze = \[\[0,0,1,0,0\],\[0,0,0,0,0\],\[0,0,0,1,0\],\[1,1,0,1,1\],\[0,0,0,0,0\]\], start = \[0,4\], destination = \[3,2\]
**Output:** false
**Explanation:** There is no way for the ball to stop at the destination. Notice that you can pass through the destination but you cannot stop there.

**Example 3:**

**Input:** maze = \[\[0,0,0,0,0\],\[1,1,0,0,1\],\[0,0,0,0,0\],\[0,1,0,0,1\],\[0,1,0,0,0\]\], start = \[4,3\], destination = \[0,1\]
**Output:** false

**Constraints:**

*   `m == maze.length`
*   `n == maze[i].length`
*   `1 <= m, n <= 100`
*   `maze[i][j]` is `0` or `1`.
*   `start.length == 2`
*   `destination.length == 2`
*   `0 <= startrow, destinationrow <= m`
*   `0 <= startcol, destinationcol <= n`
*   Both the ball and the destination exist in an empty space, and they will not be in the same position initially.
*   The maze contains **at least 2 empty spaces**.

## A solution in Java

```java
public boolean hasPath(int[][] maze, int[] start, int[] destination) {
    int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    Queue<int[]> q = new LinkedList<>();
    q.add(start);
    while (!q.isEmpty()) {
        int[] curr = q.poll();
        int x = curr[0], y = curr[1];
        if (x == destination[0] && y == destination[1]) return true;
        for (int[] dir : dirs) {
            int i = x, j = y;
            while (i + dir[0] >= 0 && i + dir[0] < maze.length && j + dir[1] >= 0 && j + dir[1] < maze[0].length && maze[i + dir[0]][j + dir[1]] == 0) {
                i += dir[0];
                j += dir[1];
            }
            if (maze[i][j] == 0) {
                maze[i][j] = 1;
                q.add(new int[]{i, j});
            }
        }
    }
    return false;
}
```
The given problem can be solved using Breadth First Search (BFS). We start from the starting point, and at each step, we keep rolling in all possible directions (up, down, left, and right) till we hit a wall. We then add the final point (before hitting the wall) of each direction to the queue if it has not been visited before. If the destination is encountered while rolling, we return True. If the queue becomes empty, that means we have exhausted all possible rollings, and thus return False. In each language (C++, Java, Python, and JavaScript), we implement this BFS algorithm using the same logic inside a while loop, keeping track of the visited positions in the maze matrix itself by marking them as 1.

## A solution in C++

```cpp
bool hasPath(vector<vector<int>>& maze, vector<int>& start, vector<int>& destination) {
    vector<vector<int>> dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    queue<pair<int, int>> q;
    q.push({start[0], start[1]});
    while (!q.empty()) {
        auto [x, y] = q.front(); q.pop();
        if (x == destination[0] && y == destination[1]) return true;
        for (auto [dx, dy] : dirs) {
            int i = x, j = y;
            while (i + dx >= 0 && i + dx < maze.size() && j + dy >= 0 && j + dy < maze[0].size() && maze[i + dx][j + dy] == 0) {
                i += dx, j += dy;
            }
            if (maze[i][j] == 0) {
                maze[i][j] = 1;
                q.push({i, j});
            }
        }
    }
    return false;
}
```
The given problem can be solved using Breadth First Search (BFS). We start from the starting point, and at each step, we keep rolling in all possible directions (up, down, left, and right) till we hit a wall. We then add the final point (before hitting the wall) of each direction to the queue if it has not been visited before. If the destination is encountered while rolling, we return True. If the queue becomes empty, that means we have exhausted all possible rollings, and thus return False. In each language (C++, Java, Python, and JavaScript), we implement this BFS algorithm using the same logic inside a while loop, keeping track of the visited positions in the maze matrix itself by marking them as 1.

## A solution in Python

```python
def hasPath(maze, start, destination):
    dirs = ((0, 1), (0, -1), (1, 0), (-1, 0))
    q = [start]
    while q:
        x, y = q.pop(0)
        if x == destination[0] and y == destination[1]:
            return True
        for dx, dy in dirs:
            i, j = x, y
            while 0 <= i + dx < len(maze) and 0 <= j + dy < len(maze[0]) and maze[i + dx][j + dy] == 0:
                i += dx
                j += dy
            if maze[i][j] == 0:
                maze[i][j] = 1
                q.append((i, j))
    return False
```
The given problem can be solved using Breadth First Search (BFS). We start from the starting point, and at each step, we keep rolling in all possible directions (up, down, left, and right) till we hit a wall. We then add the final point (before hitting the wall) of each direction to the queue if it has not been visited before. If the destination is encountered while rolling, we return True. If the queue becomes empty, that means we have exhausted all possible rollings, and thus return False. In each language (C++, Java, Python, and JavaScript), we implement this BFS algorithm using the same logic inside a while loop, keeping track of the visited positions in the maze matrix itself by marking them as 1.

## A solution in Javascript

```javascript
function hasPath(maze, start, destination) {
    const dirs = [[0, 1], [0, -1], [1, 0], [-1, 0]];
    const q = [start];
    while (q.length > 0) {
        const [x, y] = q.shift();
        if (x === destination[0] && y === destination[1]) return true;
        for (const [dx, dy] of dirs) {
            let i = x, j = y;
            while (i + dx >= 0 && i + dx < maze.length && j + dy >= 0 && j + dy < maze[0].length && maze[i + dx][j + dy] === 0) {
                i += dx;
                j += dy;
            }
            if (maze[i][j] === 0) {
                maze[i][j] = 1;
                q.push([i, j]);
            }
        }
    }
    return false;
}
```
The given problem can be solved using Breadth First Search (BFS). We start from the starting point, and at each step, we keep rolling in all possible directions (up, down, left, and right) till we hit a wall. We then add the final point (before hitting the wall) of each direction to the queue if it has not been visited before. If the destination is encountered while rolling, we return True. If the queue becomes empty, that means we have exhausted all possible rollings, and thus return False. In each language (C++, Java, Python, and JavaScript), we implement this BFS algorithm using the same logic inside a while loop, keeping track of the visited positions in the maze matrix itself by marking them as 1.


# Non-decreasing Subsequences

- slug: non-decreasing-subsequences
- difficulty: Medium

Given an integer array `nums`, return _all the different possible non-decreasing subsequences of the given array with at least two elements_. You may return the answer in **any order**.

**Example 1:**

**Input:** nums = \[4,6,7,7\]
**Output:** \[\[4,6\],\[4,6,7\],\[4,6,7,7\],\[4,7\],\[4,7,7\],\[6,7\],\[6,7,7\],\[7,7\]\]

**Example 2:**

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

**Constraints:**

*   `1 <= nums.length <= 15`
*   `-100 <= nums[i] <= 100`

## A solution in Java

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

public List<List<Integer>> findSubsequences(int[] nums) {
    Set<List<Integer>> res = new HashSet<>();
    List<Integer> path = new ArrayList<>();
    dfs(nums, 0, path, res);
    return new ArrayList<>(res);
}

private void dfs(int[] nums, int start, List<Integer> path, Set<List<Integer>> res) {
    if (path.size() >= 2) {
        res.add(new ArrayList<>(path));
    }
    for (int i = start; i < nums.length; i++) {
        if (!path.isEmpty() && path.get(path.size() - 1) > nums[i]) {
            continue;
        }
        path.add(nums[i]);
        dfs(nums, i + 1, path, res);
        path.remove(path.size() - 1);
    }
}
```
We can solve this problem using Depth-First Search (DFS) approach. To generate all the possible subsequences, start by iterating through the array, for each element of the array perform DFS and insert it into the path.

During DFS:

1. If the path has at least 2 elements, consider this path as a valid increasing subsequence, and insert it into the set to avoid duplicates.
2. For each element, skip the current element if its index is greater than equal to the current array size or its value is smaller than the last element in the path.
3. Add the current element to the path, then perform DFS on the remaining array elements by incrementing the start index.
4. Remove the current element from the path before backtracking.

After completing the DFS traversal, convert the set of subsequences into the required format (vector or list) and return it.

## A solution in C++

```cpp
#include <vector>
#include <set>

std::vector<std::vector<int>> findSubsequences(std::vector<int>& nums) {
    std::set<std::vector<int>> res;
    std::vector<int> path;
    dfs(nums, 0, path, res);
    return std::vector<std::vector<int>>(res.begin(), res.end());
}

void dfs(std::vector<int>& nums, int start, std::vector<int>& path, std::set<std::vector<int>>& res) {
    if (path.size() >= 2) {
        res.insert(path);
    }
    for (int i = start; i < nums.size(); i++) {
        if (!path.empty() && path.back() > nums[i]) {
            continue;
        }
        path.push_back(nums[i]);
        dfs(nums, i + 1, path, res);
        path.pop_back();
    }
}
```
We can solve this problem using Depth-First Search (DFS) approach. To generate all the possible subsequences, start by iterating through the array, for each element of the array perform DFS and insert it into the path.

During DFS:

1. If the path has at least 2 elements, consider this path as a valid increasing subsequence, and insert it into the set to avoid duplicates.
2. For each element, skip the current element if its index is greater than equal to the current array size or its value is smaller than the last element in the path.
3. Add the current element to the path, then perform DFS on the remaining array elements by incrementing the start index.
4. Remove the current element from the path before backtracking.

After completing the DFS traversal, convert the set of subsequences into the required format (vector or list) and return it.

## A solution in Python

```python
from typing import List

def findSubsequences(nums: List[int]) -> List[List[int]]:
    res = set()
    dfs(nums, 0, [], res)
    return list(res)

def dfs(nums, start, path, res):
    if len(path) >= 2:
        res.add(tuple(path))
    for i in range(start, len(nums)):
        if path and path[-1] > nums[i]:
            continue
        dfs(nums, i + 1, path + [nums[i]], res)
```
We can solve this problem using Depth-First Search (DFS) approach. To generate all the possible subsequences, start by iterating through the array, for each element of the array perform DFS and insert it into the path.

During DFS:

1. If the path has at least 2 elements, consider this path as a valid increasing subsequence, and insert it into the set to avoid duplicates.
2. For each element, skip the current element if its index is greater than equal to the current array size or its value is smaller than the last element in the path.
3. Add the current element to the path, then perform DFS on the remaining array elements by incrementing the start index.
4. Remove the current element from the path before backtracking.

After completing the DFS traversal, convert the set of subsequences into the required format (vector or list) and return it.

## A solution in Javascript

```javascript
function findSubsequences(nums) {
    const res = new Set();
    dfs(nums, 0, [], res);
    return Array.from(res).map(x => Array.from(x));
}

function dfs(nums, start, path, res) {
    if (path.length >= 2) {
        res.add(path);
    }
    for (let i = start; i < nums.length; i++) {
        if (path.length && path[path.length - 1] > nums[i]) {
            continue;
        }
        dfs(nums, i + 1, [...path, nums[i]], res);
    }
}
```
We can solve this problem using Depth-First Search (DFS) approach. To generate all the possible subsequences, start by iterating through the array, for each element of the array perform DFS and insert it into the path.

During DFS:

1. If the path has at least 2 elements, consider this path as a valid increasing subsequence, and insert it into the set to avoid duplicates.
2. For each element, skip the current element if its index is greater than equal to the current array size or its value is smaller than the last element in the path.
3. Add the current element to the path, then perform DFS on the remaining array elements by incrementing the start index.
4. Remove the current element from the path before backtracking.

After completing the DFS traversal, convert the set of subsequences into the required format (vector or list) and return it.