# The Maze II

- slug: the-maze-ii
- 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 _the shortest **distance** for the ball to stop at the destination_. If the ball cannot stop at `destination`, return `-1`.

The **distance** is the number of **empty spaces** traveled by the ball from the start position (excluded) to the destination (included).

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:** 12
**Explanation:** One possible way is : left -> down -> left -> down -> right -> down -> right.
The length of the path is 1 + 1 + 3 + 1 + 2 + 2 + 2 = 12.

**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:** -1
**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:** -1

**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
import java.util.PriorityQueue;

public int shortestDistance(int[][] maze, int[] start, int[] destination) {
    int m = maze.length, n = maze[0].length;
    int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    int[][] dist = new int[m][n];

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            dist[i][j] = -1;
        }
    }

    PriorityQueue<int[]> q = new PriorityQueue<>((a, b) -> a[2] - b[2]);

    dist[start[0]][start[1]] = 0;
    q.offer(new int[]{start[0], start[1], 0});

    while (!q.isEmpty()) {
        int[] cur = q.poll();
        int x = cur[0], y = cur[1];

        for (int[] dir : directions) {
            int newX = x + dir[0];
            int newY = y + dir[1];
            int step = 0;

            while (newX >= 0 && newX < m && newY >= 0 && newY < n && maze[newX][newY] == 0) {
                newX += dir[0];
                newY += dir[1];
                step++;
            }

            newX -= dir[0];
            newY -= dir[1];

            if (dist[newX][newY] == -1 || dist[x][y] + step < dist[newX][newY]) {
                dist[newX][newY] = dist[x][y] + step;
                q.offer(new int[]{newX, newY, dist[newX][newY]});
            }
        }
    }

    return dist[destination[0]][destination[1]];
}
```
We can use a BFS (Breadth-First Search) algorithm to explore the maze, counting the distance travelled in each direction. When visiting an empty space, we can continue moving in each direction until hitting a wall. Once the wall is hit, we store the distance travelled and visit the new position.

We keep track of visited positions and their distances, updating them if a shorter path is found. Use a queue to hold positions to visit next, and continue the process until the queue is empty.

Finally, return the distance stored at the destination. If the destination hasn't been reached, return -1.

## A solution in C++

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

using namespace std;

int shortestDistance(vector<vector<int>>& maze, vector<int>& start, vector<int>& destination) {
    int m = maze.size(), n = maze[0].size();
    vector<pair<int, int>> directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    vector<vector<int>> dist(m, vector<int> (n, -1));

    queue<pair<int, int>> q;

    dist[start[0]][start[1]] = 0;
    q.push({start[0], start[1]});

    while (!q.empty()) {
        int x = q.front().first, y = q.front().second;
        q.pop();

        for (auto dir : directions) {
            int newX = x + dir.first;
            int newY = y + dir.second;
            int step = 0;

            while (newX >= 0 && newX < m && newY >= 0 && newY < n && maze[newX][newY] == 0) {
                newX += dir.first;
                newY += dir.second;
                step++;
            }

            newX -= dir.first;
            newY -= dir.second;

            if (dist[newX][newY] == -1 || dist[x][y] + step < dist[newX][newY]) {
                dist[newX][newY] = dist[x][y] + step;
                q.push({newX, newY});
            }
        }
    }

    return dist[destination[0]][destination[1]];
}
```
We can use a BFS (Breadth-First Search) algorithm to explore the maze, counting the distance travelled in each direction. When visiting an empty space, we can continue moving in each direction until hitting a wall. Once the wall is hit, we store the distance travelled and visit the new position.

We keep track of visited positions and their distances, updating them if a shorter path is found. Use a queue to hold positions to visit next, and continue the process until the queue is empty.

Finally, return the distance stored at the destination. If the destination hasn't been reached, return -1.

## A solution in Python

```python
from queue import PriorityQueue

def shortestDistance(maze, start, destination):
    m, n = len(maze), len(maze[0])
    directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
    dist = [[-1 for _ in range(n)] for _ in range(m)]

    q = PriorityQueue()

    dist[start[0]][start[1]] = 0
    q.put((0, start[0], start[1]))

    while not q.empty():
        cur = q.get()
        x, y = cur[1], cur[2]

        for dir in directions:
            newX, newY = x + dir[0], y + dir[1]
            step = 0

            while 0 <= newX < m and 0 <= newY < n and maze[newX][newY] == 0:
                newX += dir[0]
                newY += dir[1]
                step += 1

            newX -= dir[0]
            newY -= dir[1]

            if dist[newX][newY] == -1 or dist[x][y] + step < dist[newX][newY]:
                dist[newX][newY] = dist[x][y] + step
                q.put((dist[newX][newY], newX, newY))

    return dist[destination[0]][destination[1]]
```
We can use a BFS (Breadth-First Search) algorithm to explore the maze, counting the distance travelled in each direction. When visiting an empty space, we can continue moving in each direction until hitting a wall. Once the wall is hit, we store the distance travelled and visit the new position.

We keep track of visited positions and their distances, updating them if a shorter path is found. Use a queue to hold positions to visit next, and continue the process until the queue is empty.

Finally, return the distance stored at the destination. If the destination hasn't been reached, return -1.

## A solution in Javascript

```javascript
function shortestDistance(maze, start, destination) {
    const m = maze.length, n = maze[0].length;
    const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]];
    const dist = new Array(m).fill(null).map(() => new Array(n).fill(-1));

    const q = [[start[0], start[1], 0]];
    dist[start[0]][start[1]] = 0;

    while (q.length) {
        const [x, y, d] = q.shift();

        for (const dir of directions) {
            let newX = x + dir[0];
            let newY = y + dir[1];
            let step = 0;

            while (0 <= newX && newX < m && 0 <= newY && newY < n && maze[newX][newY] === 0) {
                newX += dir[0];
                newY += dir[1];
                step++;
            }

            newX -= dir[0];
            newY -= dir[1];

            if (dist[newX][newY] === -1 || dist[x][y] + step < dist[newX][newY]) {
                dist[newX][newY] = dist[x][y] + step;
                q.push([newX, newY, dist[newX][newY]]);
            }
        }
    }

    return dist[destination[0]][destination[1]];
}
```
We can use a BFS (Breadth-First Search) algorithm to explore the maze, counting the distance travelled in each direction. When visiting an empty space, we can continue moving in each direction until hitting a wall. Once the wall is hit, we store the distance travelled and visit the new position.

We keep track of visited positions and their distances, updating them if a shorter path is found. Use a queue to hold positions to visit next, and continue the process until the queue is empty.

Finally, return the distance stored at the destination. If the destination hasn't been reached, return -1.


# Relative Ranks

- slug: relative-ranks
- difficulty: Easy

You are given an integer array `score` of size `n`, where `score[i]` is the score of the `ith` athlete in a competition. All the scores are guaranteed to be **unique**.

The athletes are **placed** based on their scores, where the `1st` place athlete has the highest score, the `2nd` place athlete has the `2nd` highest score, and so on. The placement of each athlete determines their rank:

*   The `1st` place athlete's rank is `"Gold Medal "`.
*   The `2nd` place athlete's rank is `"Silver Medal "`.
*   The `3rd` place athlete's rank is `"Bronze Medal "`.
*   For the `4th` place to the `nth` place athlete, their rank is their placement number (i.e., the `xth` place athlete's rank is `"x "`).

Return an array `answer` of size `n` where `answer[i]` is the **rank** of the `ith` athlete.

**Example 1:**

**Input:** score = \[5,4,3,2,1\]
**Output:** \[ "Gold Medal ", "Silver Medal ", "Bronze Medal ", "4 ", "5 "\]
**Explanation:** The placements are \[1st, 2nd, 3rd, 4th, 5th\].

**Example 2:**

**Input:** score = \[10,3,8,9,4\]
**Output:** \[ "Gold Medal ", "5 ", "Bronze Medal ", "Silver Medal ", "4 "\]
**Explanation:** The placements are \[1st, 5th, 3rd, 2nd, 4th\].

**Constraints:**

*   `n == score.length`
*   `1 <= n <= 104`
*   `0 <= score[i] <= 106`
*   All the values in `score` are **unique**.

## A solution in Java

```java
import java.util.Arrays;

public int[] findRelativeRanks(int[] score) {
    Integer[] rank_sort = new Integer[score.length];
    for(int i = 0; i < score.length; ++i) rank_sort[i] = i;
    Arrays.sort(rank_sort, (i1, i2) -> Integer.compare(score[i2], score[i1]));
    int[] result = new int[score.length];
    for(int i = 0; i < rank_sort.length; ++i) result[rank_sort[i]] = i + 1;
    return result;
}
```
The algorithm works in the following steps:

1. Create an array of indices ranging from 0 to n-1, where n is the size of the given score array.

2. Sort the indices array based on their corresponding score values in descending order. So, after sorting, the first element will be the index of the highest score in the original score array.

3. Create a result array of size n.

4. Iterate over the sorted indices array and assign its rank (1-based) to the corresponding index in the result array.

5. Return the result array that now contains the ranks of athletes.

## A solution in C++

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

std::vector<int> findRelativeRanks(std::vector<int>& score) {
    std::vector<int> rank_sort(score.size());
    for(int i = 0; i < score.size(); ++i) rank_sort[i] = i;
    std::sort(rank_sort.begin(), rank_sort.end(), [&](int i1, int i2) { return score[i1] > score[i2]; });
    std::vector<int>  result(score.size());
    for(int i = 0; i < rank_sort.size(); ++i) result[rank_sort[i]] = i + 1;
    return result;
}
```
The algorithm works in the following steps:

1. Create an array of indices ranging from 0 to n-1, where n is the size of the given score array.

2. Sort the indices array based on their corresponding score values in descending order. So, after sorting, the first element will be the index of the highest score in the original score array.

3. Create a result array of size n.

4. Iterate over the sorted indices array and assign its rank (1-based) to the corresponding index in the result array.

5. Return the result array that now contains the ranks of athletes.

## A solution in Python

```python
def find_relative_ranks(score):
    rank_sort = sorted(range(len(score)), key=lambda i: score[i], reverse=True)
    result = [0] * len(score)
    for i, rank in enumerate(rank_sort):
        result[rank] = i + 1
    return result
```
The algorithm works in the following steps:

1. Create an array of indices ranging from 0 to n-1, where n is the size of the given score array.

2. Sort the indices array based on their corresponding score values in descending order. So, after sorting, the first element will be the index of the highest score in the original score array.

3. Create a result array of size n.

4. Iterate over the sorted indices array and assign its rank (1-based) to the corresponding index in the result array.

5. Return the result array that now contains the ranks of athletes.

## A solution in Javascript

```javascript
function findRelativeRanks(score) {
    const rankSort = [...Array(score.length).keys()].sort((a, b) => score[b] - score[a]);
    const result = new Array(score.length);
    for (let i = 0; i < rankSort.length; ++i) {
        result[rankSort[i]] = i + 1;
    }
    return result;
}
```
The algorithm works in the following steps:

1. Create an array of indices ranging from 0 to n-1, where n is the size of the given score array.

2. Sort the indices array based on their corresponding score values in descending order. So, after sorting, the first element will be the index of the highest score in the original score array.

3. Create a result array of size n.

4. Iterate over the sorted indices array and assign its rank (1-based) to the corresponding index in the result array.

5. Return the result array that now contains the ranks of athletes.


# Perfect Number

- slug: perfect-number
- difficulty: Easy

A [**perfect number**](https://en.wikipedia.org/wiki/Perfect_number) is a **positive integer** that is equal to the sum of its **positive divisors**, excluding the number itself. A **divisor** of an integer `x` is an integer that can divide `x` evenly.

Given an integer `n`, return `true` _if_ `n` _is a perfect number, otherwise return_ `false`.

**Example 1:**

**Input:** num = 28
**Output:** true
**Explanation:** 28 = 1 + 2 + 4 + 7 + 14
1, 2, 4, 7, and 14 are all divisors of 28.

**Example 2:**

**Input:** num = 7
**Output:** false

**Constraints:**

*   `1 <= num <= 108`

## A solution in Java

```java
boolean checkPerfectNumber(int num) {
    if (num <= 1) return false;
    int sum = 1;
    for (int i = 2; i * i <= num; i++) {
        if (num % i == 0) {
            sum += i;
            if (i * i != num) sum += num / i;
        }
    }
    return sum == num;
}
```
The algorithm checks if a given number `num` is a perfect number by iterating through the positive divisors of the number and adding them to a sum. If the number is less than or equal to 1, it returns false as these are not perfect numbers. The loop starts from 2 and goes until the square root of the number. If `i` is divisible by `num`, it's added to the sum. Also, check if `i * i` is not equal to `num`, we add `num / i` to the sum, this is because we don't want to add the same divisor twice. In the end, it checks if the calculated sum is equal to the given number. If it is, return true, else return false.

## A solution in C++

```cpp
bool checkPerfectNumber(int num) {
    if (num <= 1) return false;
    int sum = 1;
    for (int i = 2; i * i <= num; ++i) {
        if (num % i == 0) {
            sum += i;
            if (i * i != num) sum += num / i;
        }
    }
    return sum == num;
}
```
The algorithm checks if a given number `num` is a perfect number by iterating through the positive divisors of the number and adding them to a sum. If the number is less than or equal to 1, it returns false as these are not perfect numbers. The loop starts from 2 and goes until the square root of the number. If `i` is divisible by `num`, it's added to the sum. Also, check if `i * i` is not equal to `num`, we add `num / i` to the sum, this is because we don't want to add the same divisor twice. In the end, it checks if the calculated sum is equal to the given number. If it is, return true, else return false.

## A solution in Python

```python
def checkPerfectNumber(num: int) -> bool:
    if num <= 1:
        return False
    sum = 1
    i = 2
    while i * i <= num:
        if num % i == 0:
            sum += i
            if i * i != num:
                sum += num // i
        i += 1
    return sum == num
```
The algorithm checks if a given number `num` is a perfect number by iterating through the positive divisors of the number and adding them to a sum. If the number is less than or equal to 1, it returns false as these are not perfect numbers. The loop starts from 2 and goes until the square root of the number. If `i` is divisible by `num`, it's added to the sum. Also, check if `i * i` is not equal to `num`, we add `num / i` to the sum, this is because we don't want to add the same divisor twice. In the end, it checks if the calculated sum is equal to the given number. If it is, return true, else return false.

## A solution in Javascript

```javascript
function checkPerfectNumber(num) {
    if (num <= 1) return false;
    let sum = 1;
    for (let i = 2; i * i <= num; i++) {
        if (num % i === 0) {
            sum += i;
            if (i * i !== num) sum += num / i;
        }
    }
    return sum === num;
}
```
The algorithm checks if a given number `num` is a perfect number by iterating through the positive divisors of the number and adding them to a sum. If the number is less than or equal to 1, it returns false as these are not perfect numbers. The loop starts from 2 and goes until the square root of the number. If `i` is divisible by `num`, it's added to the sum. Also, check if `i * i` is not equal to `num`, we add `num / i` to the sum, this is because we don't want to add the same divisor twice. In the end, it checks if the calculated sum is equal to the given number. If it is, return true, else return false.


# Most Frequent Subtree Sum

- slug: most-frequent-subtree-sum
- difficulty: Medium

Given the `root` of a binary tree, return the most frequent **subtree sum**. If there is a tie, return all the values with the highest frequency in any order.

The **subtree sum** of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself).

**Example 1:**

**Input:** root = \[5,2,-3\]
**Output:** \[2,-3,4\]

**Example 2:**

**Input:** root = \[5,2,-5\]
**Output:** \[2\]

**Constraints:**

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

## A solution in Java

```java
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

public int helper(TreeNode root, HashMap<Integer, Integer> counts) {
    if (root == null) return 0;
    int sum = root.val + helper(root.left, counts) + helper(root.right, counts);
    counts.put(sum, counts.getOrDefault(sum, 0) + 1);
    return sum;
}

public int[] findFrequentTreeSum(TreeNode root) {
    if (root == null) return new int[0];
    HashMap<Integer, Integer> counts = new HashMap<>();
    helper(root, counts);
    int maxCount = 0;
    for (int count : counts.values()) {
        maxCount = Math.max(count, maxCount);
    }
    List<Integer> list = new LinkedList<>();
    for (int key : counts.keySet()) {
        if (counts.get(key) == maxCount) list.add(key);
    }
    return list.stream().mapToInt(i -> i).toArray();
}
```
The algorithm uses a helper function to recursively calculate the subtree sum for each node. The helper function returns the subtree sum of the node it's called on, and the results are combined to calculate the subtree sum of the parent nodes. The subtree sums are stored in a dictionary or map along with their frequencies. After calculating the sums and frequencies for all nodes, the maximum frequency is found by iterating through the values of the dictionary or map. Finally, the function loops through the dictionary or map and adds the keys with the maximum frequency to the result list or array. The result is then returned.

## A solution in C++

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

void helper(TreeNode* root, std::map<int, int>& counts, int& max_count) {
    if (!root) return;
    int sum = root->val + helper(root->left, counts, max_count) + helper(root->right, counts, max_count);
    counts[sum]++;
    max_count = std::max(max_count, counts[sum]);
}

std::vector<int> findFrequentTreeSum(TreeNode* root) {
    std::map<int, int> counts;
    int max_count = 0;
    helper(root, counts, max_count);
    std::vector<int> result;
    for (const auto& pair : counts) {
        if (pair.second == max_count) result.push_back(pair.first);
    }
    return result;
}
```
The algorithm uses a helper function to recursively calculate the subtree sum for each node. The helper function returns the subtree sum of the node it's called on, and the results are combined to calculate the subtree sum of the parent nodes. The subtree sums are stored in a dictionary or map along with their frequencies. After calculating the sums and frequencies for all nodes, the maximum frequency is found by iterating through the values of the dictionary or map. Finally, the function loops through the dictionary or map and adds the keys with the maximum frequency to the result list or array. The result is then returned.

## A solution in Python

```python
from collections import defaultdict

def helper(node, counts):
    if not node: return 0
    val = node.val + helper(node.left, counts) + helper(node.right, counts)
    counts[val] += 1
    return val

def findFrequentTreeSum(root):
    counts = defaultdict(int)
    helper(root, counts)
    max_count = max(counts.values(), default=0)
    return [s for s, c in counts.items() if c == max_count]
```
The algorithm uses a helper function to recursively calculate the subtree sum for each node. The helper function returns the subtree sum of the node it's called on, and the results are combined to calculate the subtree sum of the parent nodes. The subtree sums are stored in a dictionary or map along with their frequencies. After calculating the sums and frequencies for all nodes, the maximum frequency is found by iterating through the values of the dictionary or map. Finally, the function loops through the dictionary or map and adds the keys with the maximum frequency to the result list or array. The result is then returned.

## A solution in Javascript

```javascript
function helper(root, counts) {
    if (!root) return 0;
    const sum = root.val + helper(root.left, counts) + helper(root.right, counts);
    counts[sum] = (counts[sum] || 0) + 1;
    return sum;
}

function findFrequentTreeSum(root) {
    const counts = {};
    helper(root, counts);
    const maxCount = Math.max(...Object.values(counts));
    return Object.keys(counts).filter(key => counts[key] === maxCount).map(Number);
}
```
The algorithm uses a helper function to recursively calculate the subtree sum for each node. The helper function returns the subtree sum of the node it's called on, and the results are combined to calculate the subtree sum of the parent nodes. The subtree sums are stored in a dictionary or map along with their frequencies. After calculating the sums and frequencies for all nodes, the maximum frequency is found by iterating through the values of the dictionary or map. Finally, the function loops through the dictionary or map and adds the keys with the maximum frequency to the result list or array. The result is then returned.


# Fibonacci Number

- slug: fibonacci-number
- difficulty: Easy

The **Fibonacci numbers**, commonly denoted `F(n)` form a sequence, called the **Fibonacci sequence**, such that each number is the sum of the two preceding ones, starting from `0` and `1`. That is,

F(0) = 0, F(1) = 1
F(n) = F(n - 1) + F(n - 2), for n > 1.

Given `n`, calculate `F(n)`.

**Example 1:**

**Input:** n = 2
**Output:** 1
**Explanation:** F(2) = F(1) + F(0) = 1 + 0 = 1.

**Example 2:**

**Input:** n = 3
**Output:** 2
**Explanation:** F(3) = F(2) + F(1) = 1 + 1 = 2.

**Example 3:**

**Input:** n = 4
**Output:** 3
**Explanation:** F(4) = F(3) + F(2) = 2 + 1 = 3.

**Constraints:**

*   `0 <= n <= 30`

## A solution in Java

```java
public int fib(int n) {
    if(n < 2) {
        return n;
    }
    int a = 0, b = 1, c;
    for(int i = 2; i <= n; i++) {
        c = a + b;
        a = b;
        b = c;
    }
    return b;
}
```
The algorithm is an iterative approach to calculate the Fibonacci numbers. Instead of using the recursive formula, we maintain two variables `a` and `b` initialized with F(0) and F(1) respectively. On each iteration, we set `c = a + b`, then update `a` with the value of `b` and `b` with the value of `c`. This process increments both the Fibonacci numbers n times and the final result is stored in the variable `b`. This reduces the time complexity of the problem from exponential (recursive) to linear (iterative).

## A solution in C++

```cpp
int fib(int n) {
    if(n < 2) {
        return n;
    }
    int a = 0, b = 1, c;
    for(int i = 2; i <= n; ++i) {
        c = a + b;
        a = b;
        b = c;
    }
    return b;
}
```
The algorithm is an iterative approach to calculate the Fibonacci numbers. Instead of using the recursive formula, we maintain two variables `a` and `b` initialized with F(0) and F(1) respectively. On each iteration, we set `c = a + b`, then update `a` with the value of `b` and `b` with the value of `c`. This process increments both the Fibonacci numbers n times and the final result is stored in the variable `b`. This reduces the time complexity of the problem from exponential (recursive) to linear (iterative).

## A solution in Python

```python
def fib(n: int) -> int:
    if n < 2:
        return n
    a, b = 0, 1
    for _ in range(2, n + 1):
        a, b = b, a + b
    return b
```
The algorithm is an iterative approach to calculate the Fibonacci numbers. Instead of using the recursive formula, we maintain two variables `a` and `b` initialized with F(0) and F(1) respectively. On each iteration, we set `c = a + b`, then update `a` with the value of `b` and `b` with the value of `c`. This process increments both the Fibonacci numbers n times and the final result is stored in the variable `b`. This reduces the time complexity of the problem from exponential (recursive) to linear (iterative).

## A solution in Javascript

```javascript
function fib(n) {
    if(n < 2) {
        return n;
    }
    let a = 0, b = 1, c;
    for(let i = 2; i <= n; i++) {
        c = a + b;
        a = b;
        b = c;
    }
    return b;
}
```
The algorithm is an iterative approach to calculate the Fibonacci numbers. Instead of using the recursive formula, we maintain two variables `a` and `b` initialized with F(0) and F(1) respectively. On each iteration, we set `c = a + b`, then update `a` with the value of `b` and `b` with the value of `c`. This process increments both the Fibonacci numbers n times and the final result is stored in the variable `b`. This reduces the time complexity of the problem from exponential (recursive) to linear (iterative).


# Inorder Successor in BST II

- slug: inorder-successor-in-bst-ii
- difficulty: Medium

Given a `node` in a binary search tree, return _the in-order successor of that node in the BST_. If that node has no in-order successor, return `null`.

The successor of a `node` is the node with the smallest key greater than `node.val`.

You will have direct access to the node but not to the root of the tree. Each node will have a reference to its parent node. Below is the definition for `Node`:

class Node {
    public int val;
    public Node left;
    public Node right;
    public Node parent;
}

**Example 1:**

**Input:** tree = \[2,1,3\], node = 1
**Output:** 2
**Explanation:** 1's in-order successor node is 2. Note that both the node and the return value is of Node type.

**Example 2:**

**Input:** tree = \[5,3,6,2,4,null,null,1\], node = 6
**Output:** null
**Explanation:** There is no in-order successor of the current node, so the answer is null.

**Constraints:**

*   The number of nodes in the tree is in the range `[1, 104]`.
*   `-105 <= Node.val <= 105`
*   All Nodes will have unique values.

**Follow up:** Could you solve it without looking up any of the node's values?

## A solution in Java

```java
class Node {
    public int val;
    public Node left;
    public Node right;
    public Node parent;
}

public Node inorderSuccessor(Node node) {
    if (node.right != null) {
        node = node.right;
        while (node.left != null) {
            node = node.left;
        }
        return node;
    }
    while (node.parent != null && node == node.parent.right) {
        node = node.parent;
    }
    return node.parent;
}
```
Algorithm:

1. If the node has a right child, then the in-order successor of the node is the leftmost node in its right sub-tree.
2. If the node doesn't have a right child, follow the parent pointers until we either find a node that is a left child or we reach the root:
    - If we find a node that is a left child, then the in-order successor is its parent.
    - If we reach the root, then the current node is the last node in in-order traversal, so its in-order successor is `null`.

## A solution in C++

```cpp
class Node {
public:
    int val;
    Node* left;
    Node* right;
    Node* parent;
};

Node* inorderSuccessor(Node* node) {
    if (node->right) {
        node = node->right;
        while (node->left) {
            node = node->left;
        }
        return node;
    }
    while (node->parent && node == node->parent->right) {
        node = node->parent;
    }
    return node->parent;
}
```
Algorithm:

1. If the node has a right child, then the in-order successor of the node is the leftmost node in its right sub-tree.
2. If the node doesn't have a right child, follow the parent pointers until we either find a node that is a left child or we reach the root:
    - If we find a node that is a left child, then the in-order successor is its parent.
    - If we reach the root, then the current node is the last node in in-order traversal, so its in-order successor is `null`.

## A solution in Python

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

def inorder_successor(node: Node) -> Node:
    if node.right:
        node = node.right
        while node.left:
            node = node.left
        return node

    while node.parent and node == node.parent.right:
        node = node.parent

    return node.parent
```
Algorithm:

1. If the node has a right child, then the in-order successor of the node is the leftmost node in its right sub-tree.
2. If the node doesn't have a right child, follow the parent pointers until we either find a node that is a left child or we reach the root:
    - If we find a node that is a left child, then the in-order successor is its parent.
    - If we reach the root, then the current node is the last node in in-order traversal, so its in-order successor is `null`.

## A solution in Javascript

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

function inorderSuccessor(node) {
    if (node.right) {
        node = node.right;
        while (node.left) {
            node = node.left;
        }
        return node;
    }
    while (node.parent && node === node.parent.right) {
        node = node.parent;
    }
    return node.parent;
}
```
Algorithm:

1. If the node has a right child, then the in-order successor of the node is the leftmost node in its right sub-tree.
2. If the node doesn't have a right child, follow the parent pointers until we either find a node that is a left child or we reach the root:
    - If we find a node that is a left child, then the in-order successor is its parent.
    - If we reach the root, then the current node is the last node in in-order traversal, so its in-order successor is `null`.


# Find Bottom Left Tree Value

- slug: find-bottom-left-tree-value
- difficulty: Medium

Given the `root` of a binary tree, return the leftmost value in the last row of the tree.

**Example 1:**

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

**Example 2:**

**Input:** root = \[1,2,3,4,null,5,6,null,null,7\]
**Output:** 7

**Constraints:**

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

## A solution in Java

```java
public int findBottomLeftValue(TreeNode root) {
    int[] maxDepth = new int[1];
    int[] result = new int[1];
    helper(root, 1, maxDepth, result);
    return result[0];
}

private void helper(TreeNode node, int depth, int[] maxDepth, int[] result) {
    if (node == null) return;
    if (depth > maxDepth[0]) {
        maxDepth[0] = depth;
        result[0] = node.val;
    }
    helper(node.left, depth+1, maxDepth, result);
    helper(node.right, depth+1, maxDepth, result);
}
```
To find the leftmost value in the last row of a binary tree, we can use Depth First Search (DFS) traversal.

1. Create a helper function that takes the input node, current depth, and a result variable.
2. If the input node is null, then return.
3. For the given depth:
    a. If the current depth is greater than the previously recorded maximum depth, update the maximum depth and store the node value as the leftmost value.
    b. Recurse the helper function for the left child of the node, and increment the depth.
    c. Recurse the helper function for the right child of the node, and increment the depth.
4. After the DFS traversal, return the leftmost value found in the last row.

## A solution in C++

```cpp
int findBottomLeftValue(TreeNode* root) {
    int result = 0, maxDepth = 0;
    helper(root, 1, maxDepth, result);
    return result;
}

void helper(TreeNode* node, int depth, int& maxDepth, int& result) {
    if (!node) return;
    if (depth > maxDepth) {
        maxDepth = depth;
        result = node->val;
    }
    helper(node->left, depth+1, maxDepth, result);
    helper(node->right, depth+1, maxDepth, result);
}
```
To find the leftmost value in the last row of a binary tree, we can use Depth First Search (DFS) traversal.

1. Create a helper function that takes the input node, current depth, and a result variable.
2. If the input node is null, then return.
3. For the given depth:
    a. If the current depth is greater than the previously recorded maximum depth, update the maximum depth and store the node value as the leftmost value.
    b. Recurse the helper function for the left child of the node, and increment the depth.
    c. Recurse the helper function for the right child of the node, and increment the depth.
4. After the DFS traversal, return the leftmost value found in the last row.

## A solution in Python

```python
def findBottomLeftValue(self, root: TreeNode) -> int:
    result = [0, 0] # [depth, value]
    self.helper(root, 1, result)
    return result[1]

def helper(self, node, depth, result):
    if not node:
        return
    if depth > result[0]:
        result[0] = depth
        result[1] = node.val

    self.helper(node.left, depth+1, result)
    self.helper(node.right, depth+1, result)
```
To find the leftmost value in the last row of a binary tree, we can use Depth First Search (DFS) traversal.

1. Create a helper function that takes the input node, current depth, and a result variable.
2. If the input node is null, then return.
3. For the given depth:
    a. If the current depth is greater than the previously recorded maximum depth, update the maximum depth and store the node value as the leftmost value.
    b. Recurse the helper function for the left child of the node, and increment the depth.
    c. Recurse the helper function for the right child of the node, and increment the depth.
4. After the DFS traversal, return the leftmost value found in the last row.

## A solution in Javascript

```javascript
function findBottomLeftValue(root) {
    const result = { maxDepth: 0, value: 0 };
    helper(root, 1, result);
    return result.value;
};

function helper(node, depth, result) {
    if (!node) return;
    if (depth > result.maxDepth) {
        result.maxDepth = depth;
        result.value = node.val;
    }
    helper(node.left, depth+1, result);
    helper(node.right, depth+1, result);
}
```
To find the leftmost value in the last row of a binary tree, we can use Depth First Search (DFS) traversal.

1. Create a helper function that takes the input node, current depth, and a result variable.
2. If the input node is null, then return.
3. For the given depth:
    a. If the current depth is greater than the previously recorded maximum depth, update the maximum depth and store the node value as the leftmost value.
    b. Recurse the helper function for the left child of the node, and increment the depth.
    c. Recurse the helper function for the right child of the node, and increment the depth.
4. After the DFS traversal, return the leftmost value found in the last row.


# Freedom Trail

- slug: freedom-trail
- difficulty: Hard

In the video game Fallout 4, the quest **"Road to Freedom "** requires players to reach a metal dial called the **"Freedom Trail Ring "** and use the dial to spell a specific keyword to open the door.

Given a string `ring` that represents the code engraved on the outer ring and another string `key` that represents the keyword that needs to be spelled, return _the minimum number of steps to spell all the characters in the keyword_.

Initially, the first character of the ring is aligned at the `"12:00 "` direction. You should spell all the characters in `key` one by one by rotating `ring` clockwise or anticlockwise to make each character of the string key aligned at the `"12:00 "` direction and then by pressing the center button.

At the stage of rotating the ring to spell the key character `key[i]`:

1.  You can rotate the ring clockwise or anticlockwise by one place, which counts as **one step**. The final purpose of the rotation is to align one of `ring`'s characters at the `"12:00 "` direction, where this character must equal `key[i]`.
2.  If the character `key[i]` has been aligned at the `"12:00 "` direction, press the center button to spell, which also counts as **one step**. After the pressing, you could begin to spell the next character in the key (next stage). Otherwise, you have finished all the spelling.

**Example 1:**

**Input:** ring =  "godding ", key =  "gd "
**Output:** 4
**Explanation:**
For the first key character 'g', since it is already in place, we just need 1 step to spell this character.
For the second key character 'd', we need to rotate the ring  "godding " anticlockwise by two steps to make it become  "ddinggo ".
Also, we need 1 more step for spelling.
So the final output is 4.

**Example 2:**

**Input:** ring =  "godding ", key =  "godding "
**Output:** 13

**Constraints:**

*   `1 <= ring.length, key.length <= 100`
*   `ring` and `key` consist of only lower case English letters.
*   It is guaranteed that `key` could always be spelled by rotating `ring`.

## A solution in Java

```java
public int findRotateSteps(String ring, String key) {
    int n = ring.length(), m = key.length();
    int[][] dp = new int[m + 1][n];

    for (int i = m - 1; i >= 0; --i) {
        for (int j = 0; j < n; ++j) {
            dp[i][j] = Integer.MAX_VALUE;
            for (int k = 0; k < n; ++k) {
                if (ring.charAt(k) == key.charAt(i)) {
                    int diff = Math.abs(j - k);
                    int step = Math.min(diff, n - diff);
                    dp[i][j] = Math.min(dp[i][j], step + dp[i + 1][k]);
                }
            }
        }
    }

    return dp[0][0] + m;
}
```
The algorithm uses dynamic programming. Create a 2D table ("dp") with the dimensions of the length of the key + 1 as rows and the length of the ring as columns. The table represents the minimum number of steps required to reach each character in the key by aligning it to the 12:00 direction.

The main logic runs in reverse of the key string. For each character in the key, the outer ring positions are iterated and checked if the character in the ring matches the character in the key. The minimum steps to reach the matching character are calculated and updated in the "dp" table.

Finally, the first element in the "dp" table would represent the minimum number of steps required to complete the whole key. The result is the sum of that value and the length of the key.

## A solution in C++

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

int findRotateSteps(std::string ring, std::string key) {
    int n = ring.size(), m = key.size();
    std::vector<std::vector<int>> dp(m + 1, std::vector<int>(n, 0));

    for (int i = m - 1; i >= 0; --i) {
        for (int j = 0; j < n; ++j) {
            dp[i][j] = INT_MAX;
            for (int k = 0; k < n; ++k) {
                if (ring[k] == key[i]) {
                    int diff = abs(j - k);
                    int step = std::min(diff, n - diff);
                    dp[i][j] = std::min(dp[i][j], step + dp[i + 1][k]);
                }
            }
        }
    }

    return dp[0][0] + m;
}
```
The algorithm uses dynamic programming. Create a 2D table ("dp") with the dimensions of the length of the key + 1 as rows and the length of the ring as columns. The table represents the minimum number of steps required to reach each character in the key by aligning it to the 12:00 direction.

The main logic runs in reverse of the key string. For each character in the key, the outer ring positions are iterated and checked if the character in the ring matches the character in the key. The minimum steps to reach the matching character are calculated and updated in the "dp" table.

Finally, the first element in the "dp" table would represent the minimum number of steps required to complete the whole key. The result is the sum of that value and the length of the key.

## A solution in Python

```python
def find_rotate_steps(ring: str, key: str) -> int:
    n, m = len(ring), len(key)
    dp = [[0] * n for _ in range(m + 1)]

    for i in range(m - 1, -1, -1):
        for j in range(n):
            dp[i][j] = float('inf')
            for k in range(n):
                if ring[k] == key[i]:
                    diff = abs(j - k)
                    step = min(diff, n - diff)
                    dp[i][j] = min(dp[i][j], step + dp[i + 1][k])

    return dp[0][0] + m
```
The algorithm uses dynamic programming. Create a 2D table ("dp") with the dimensions of the length of the key + 1 as rows and the length of the ring as columns. The table represents the minimum number of steps required to reach each character in the key by aligning it to the 12:00 direction.

The main logic runs in reverse of the key string. For each character in the key, the outer ring positions are iterated and checked if the character in the ring matches the character in the key. The minimum steps to reach the matching character are calculated and updated in the "dp" table.

Finally, the first element in the "dp" table would represent the minimum number of steps required to complete the whole key. The result is the sum of that value and the length of the key.

## A solution in Javascript

```javascript
function findRotateSteps(ring, key) {
    const n = ring.length, m = key.length;
    const dp = Array.from({ length: m + 1 }, () => new Array(n).fill(0));

    for (let i = m - 1; i >= 0; --i) {
        for (let j = 0; j < n; ++j) {
            dp[i][j] = Infinity;
            for (let k = 0; k < n; ++k) {
                if (ring[k] === key[i]) {
                    const diff = Math.abs(j - k);
                    const step = Math.min(diff, n - diff);
                    dp[i][j] = Math.min(dp[i][j], step + dp[i + 1][k]);
                }
            }
        }
    }

    return dp[0][0] + m;
}
```
The algorithm uses dynamic programming. Create a 2D table ("dp") with the dimensions of the length of the key + 1 as rows and the length of the ring as columns. The table represents the minimum number of steps required to reach each character in the key by aligning it to the 12:00 direction.

The main logic runs in reverse of the key string. For each character in the key, the outer ring positions are iterated and checked if the character in the ring matches the character in the key. The minimum steps to reach the matching character are calculated and updated in the "dp" table.

Finally, the first element in the "dp" table would represent the minimum number of steps required to complete the whole key. The result is the sum of that value and the length of the key.


# Find Largest Value in Each Tree Row

- slug: find-largest-value-in-each-tree-row
- difficulty: Medium

Given the `root` of a binary tree, return _an array of the largest value in each row_ of the tree **(0-indexed)**.

**Example 1:**

**Input:** root = \[1,3,2,5,3,null,9\]
**Output:** \[1,3,9\]

**Example 2:**

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

**Constraints:**

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

## A solution in Java

```java
import java.util.*;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
}

public List<Integer> largestValues(TreeNode root) {
    if (root == null) return new ArrayList<>();
    List<Integer> result = new ArrayList<>();
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);

    while (!queue.isEmpty()) {
        int size = queue.size();
        int max_val = Integer.MIN_VALUE;
        for (int i = 0; i < size; i++) {
            TreeNode node = queue.poll();
            max_val = Math.max(max_val, node.val);

            if (node.left != null) queue.offer(node.left);
            if (node.right != null) queue.offer(node.right);
        }
        result.add(max_val);
    }
    return result;
}
```
The algorithm we used here is Breadth-First Search (BFS) traversal. We use a queue to store the nodes in each level of the tree. After we process all the nodes in the current level, we update the maxVal with the maximum element value found in that level and add it to the result array. We repeat this process until the queue is empty, which means we have processed all the nodes in the binary tree. The time and space complexity of this algorithm is O(N), where N is the number of nodes in the tree.

## A solution in C++

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

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
};

vector<int> largestValues(TreeNode* root) {
    if (!root) return {};
    vector<int> result;
    queue<TreeNode*> q;
    q.push(root);

    while (!q.empty()) {
        int size = q.size();
        int max_val = INT_MIN;
        for (int i = 0; i < size; ++i) {
            TreeNode* node = q.front();
            q.pop();
            max_val = max(max_val, node->val);

            if (node->left) q.push(node->left);
            if (node->right) q.push(node->right);
        }
        result.push_back(max_val);
    }
    return result;
}
```
The algorithm we used here is Breadth-First Search (BFS) traversal. We use a queue to store the nodes in each level of the tree. After we process all the nodes in the current level, we update the maxVal with the maximum element value found in that level and add it to the result array. We repeat this process until the queue is empty, which means we have processed all the nodes in the binary tree. The time and space complexity of this algorithm is O(N), where N is the number of nodes in the tree.

## A solution in Python

```python
from collections import deque

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

def largestValues(root: TreeNode):
    if not root:
        return []
    result = []
    queue = deque([root])

    while queue:
        size = len(queue)
        max_val = float('-inf')
        for _ in range(size):
            node = queue.popleft()
            max_val = max(max_val, node.val)

            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        result.append(max_val)

    return result
```
The algorithm we used here is Breadth-First Search (BFS) traversal. We use a queue to store the nodes in each level of the tree. After we process all the nodes in the current level, we update the maxVal with the maximum element value found in that level and add it to the result array. We repeat this process until the queue is empty, which means we have processed all the nodes in the binary tree. The time and space complexity of this algorithm is O(N), where N is the number of nodes in the tree.

## A solution in Javascript

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

function largestValues(root) {
    if (!root) return [];
    const result = [];
    const queue = [root];

    while (queue.length) {
        const size = queue.length;
        let maxVal = Number.MIN_SAFE_INTEGER;
        for (let i = 0; i < size; i++) {
            const node = queue.shift();
            maxVal = Math.max(maxVal, node.val);

            if (node.left) queue.push(node.left);
            if (node.right) queue.push(node.right);
        }
        result.push(maxVal);
    }
    return result;
}
```
The algorithm we used here is Breadth-First Search (BFS) traversal. We use a queue to store the nodes in each level of the tree. After we process all the nodes in the current level, we update the maxVal with the maximum element value found in that level and add it to the result array. We repeat this process until the queue is empty, which means we have processed all the nodes in the binary tree. The time and space complexity of this algorithm is O(N), where N is the number of nodes in the tree.


# Longest Palindromic Subsequence

- slug: longest-palindromic-subsequence
- difficulty: Medium

Given a string `s`, find _the longest palindromic **subsequence**'s length in_ `s`.

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

**Example 1:**

**Input:** s =  "bbbab "
**Output:** 4
**Explanation:** One possible longest palindromic subsequence is  "bbbb ".

**Example 2:**

**Input:** s =  "cbbd "
**Output:** 2
**Explanation:** One possible longest palindromic subsequence is  "bb ".

**Constraints:**

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

## A solution in Java

```java
public int longestPalindromeSubseq(String s) {
    int n = s.length();
    int[][] dp = new int[n][n];

    for (int i = n - 1; i >= 0; i--) {
        dp[i][i] = 1;
        for (int j = i + 1; j < n; j++) {
            if (s.charAt(i) == s.charAt(j)) {
                dp[i][j] = 2 + dp[i + 1][j - 1];
            } else {
                dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
            }
        }
    }
    return dp[0][n - 1];
}
```
The algorithm uses dynamic programming to find the longest palindromic subsequence's length. It initializes a 2D table (dp) of size nxn, where n is the length of the string. The entries `dp[i][j]` represent the length of the longest palindromic subsequence in the string for the substring starting from index i and ending at index j.

The algorithm first fills the diagonal creating a single character palindrome. Then, it iterates through the string comparing the characters. When equal, the length of the longest palindromic subsequence increases by 2 plus the length of the longest palindrome found inside of these characters. If unequal, the longer subsequence length between the substrings not containing those characters is taken.

Finally, the function returns the length of the longest palindromic subsequence found in the entire string (`dp[0][n-1]`).

## A solution in C++

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

int longestPalindromeSubseq(string s) {
    int n = s.size();
    vector<vector<int>> dp(n, vector<int>(n, 0));
    for (int i = n - 1; i >= 0; i--) {
        dp[i][i] = 1;
        for (int j = i + 1; j < n; j++) {
            if (s[i] == s[j]) {
                dp[i][j] = 2 + dp[i + 1][j - 1];
            } else {
                dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
            }
        }
    }
    return dp[0][n - 1];
}
```
The algorithm uses dynamic programming to find the longest palindromic subsequence's length. It initializes a 2D table (dp) of size nxn, where n is the length of the string. The entries `dp[i][j]` represent the length of the longest palindromic subsequence in the string for the substring starting from index i and ending at index j.

The algorithm first fills the diagonal creating a single character palindrome. Then, it iterates through the string comparing the characters. When equal, the length of the longest palindromic subsequence increases by 2 plus the length of the longest palindrome found inside of these characters. If unequal, the longer subsequence length between the substrings not containing those characters is taken.

Finally, the function returns the length of the longest palindromic subsequence found in the entire string (`dp[0][n-1]`).

## A solution in Python

```python
def longestPalindromeSubseq(s: str) -> int:
    n = len(s)
    dp = [[0] * n for _ in range(n)]

    for i in range(n - 1, -1, -1):
        dp[i][i] = 1
        for j in range(i + 1, n):
            if s[i] == s[j]:
                dp[i][j] = 2 + dp[i + 1][j - 1]
            else:
                dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])

    return dp[0][n - 1]
```
The algorithm uses dynamic programming to find the longest palindromic subsequence's length. It initializes a 2D table (dp) of size nxn, where n is the length of the string. The entries `dp[i][j]` represent the length of the longest palindromic subsequence in the string for the substring starting from index i and ending at index j.

The algorithm first fills the diagonal creating a single character palindrome. Then, it iterates through the string comparing the characters. When equal, the length of the longest palindromic subsequence increases by 2 plus the length of the longest palindrome found inside of these characters. If unequal, the longer subsequence length between the substrings not containing those characters is taken.

Finally, the function returns the length of the longest palindromic subsequence found in the entire string (`dp[0][n-1]`).

## A solution in Javascript

```javascript
function longestPalindromeSubseq(s) {
    const n = s.length;
    const dp = Array.from({ length: n }, () => Array(n).fill(0));

    for (let i = n - 1; i >= 0; i--) {
        dp[i][i] = 1;
        for (let j = i + 1; j < n; j++) {
            if (s[i] === s[j]) {
                dp[i][j] = 2 + dp[i + 1][j - 1];
            } else {
                dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
            }
        }
    }

    return dp[0][n - 1];
}
```
The algorithm uses dynamic programming to find the longest palindromic subsequence's length. It initializes a 2D table (dp) of size nxn, where n is the length of the string. The entries `dp[i][j]` represent the length of the longest palindromic subsequence in the string for the substring starting from index i and ending at index j.

The algorithm first fills the diagonal creating a single character palindrome. Then, it iterates through the string comparing the characters. When equal, the length of the longest palindromic subsequence increases by 2 plus the length of the longest palindrome found inside of these characters. If unequal, the longer subsequence length between the substrings not containing those characters is taken.

Finally, the function returns the length of the longest palindromic subsequence found in the entire string (`dp[0][n-1]`).


# Super Washing Machines

- slug: super-washing-machines
- difficulty: Hard

You have `n` super washing machines on a line. Initially, each washing machine has some dresses or is empty.

For each move, you could choose any `m` (`1 <= m <= n`) washing machines, and pass one dress of each washing machine to one of its adjacent washing machines at the same time.

Given an integer array `machines` representing the number of dresses in each washing machine from left to right on the line, return _the minimum number of moves to make all the washing machines have the same number of dresses_. If it is not possible to do it, return `-1`.

**Example 1:**

**Input:** machines = \[1,0,5\]
**Output:** 3
**Explanation:**
1st move:    1     0 <-- 5    =>    1     1     4
2nd move:    1 <-- 1 <-- 4    =>    2     1     3
3rd move:    2     1 <-- 3    =>    2     2     2

**Example 2:**

**Input:** machines = \[0,3,0\]
**Output:** 2
**Explanation:**
1st move:    0 <-- 3     0    =>    1     2     0
2nd move:    1     2 --> 0    =>    1     1     1

**Example 3:**

**Input:** machines = \[0,2,0\]
**Output:** -1
**Explanation:**
It's impossible to make all three washing machines have the same number of dresses.

**Constraints:**

*   `n == machines.length`
*   `1 <= n <= 104`
*   `0 <= machines[i] <= 105`

## A solution in Java

```java
public int findMinMoves(int[] machines) {
    int n = machines.length;
    int totalDresses = 0;
    for (int m : machines) totalDresses += m;
    if (totalDresses % n != 0) return -1;
    int average = totalDresses / n;
    int moves = 0, imbalance = 0;

    for (int i = 0; i < n; i++) {
        imbalance += machines[i] - average;
        moves = Math.max(moves, Math.max(Math.abs(imbalance), machines[i] - average));
    }

    return moves;
}
```
1. Calculate the total number of dresses and check if it can be evenly distributed among the machines. If it cannot, return -1.
2. Calculate the average number of dresses each machine should have.
3. Initialize the moves and imbalance count to 0.
4. Iterate through the machines and calculate the current imbalance for each machine.
5. Update the moves count by taking the maximum of the current moves, the absolute value of the current imbalance, and the difference between the current machine's dresses and the average value.
6. Return the moves count.

## A solution in C++

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

int findMinMoves(std::vector<int>& machines) {
    int n = machines.size();
    int totalDresses = std::accumulate(machines.begin(), machines.end(), 0);
    if (totalDresses % n != 0) return -1;
    int average = totalDresses / n;
    int moves = 0, imbalance = 0;

    for (int i = 0; i < n; i++) {
        imbalance += machines[i] - average;
        moves = std::max(moves, std::max(abs(imbalance), machines[i] - average));
    }

    return moves;
}
```
1. Calculate the total number of dresses and check if it can be evenly distributed among the machines. If it cannot, return -1.
2. Calculate the average number of dresses each machine should have.
3. Initialize the moves and imbalance count to 0.
4. Iterate through the machines and calculate the current imbalance for each machine.
5. Update the moves count by taking the maximum of the current moves, the absolute value of the current imbalance, and the difference between the current machine's dresses and the average value.
6. Return the moves count.

## A solution in Python

```python
def find_min_moves(machines):
    n = len(machines)
    total_dresses = sum(machines)
    if total_dresses % n != 0:
        return -1
    average = total_dresses // n
    moves = 0
    imbalance = 0

    for i in range(n):
        imbalance += machines[i] - average
        moves = max(moves, abs(imbalance), machines[i] - average)

    return moves
```
1. Calculate the total number of dresses and check if it can be evenly distributed among the machines. If it cannot, return -1.
2. Calculate the average number of dresses each machine should have.
3. Initialize the moves and imbalance count to 0.
4. Iterate through the machines and calculate the current imbalance for each machine.
5. Update the moves count by taking the maximum of the current moves, the absolute value of the current imbalance, and the difference between the current machine's dresses and the average value.
6. Return the moves count.

## A solution in Javascript

```javascript
function findMinMoves(machines) {
    let n = machines.length;
    let totalDresses = machines.reduce((a, b) => a + b, 0);
    if (totalDresses % n !== 0) return -1;
    let average = totalDresses / n;
    let moves = 0, imbalance = 0;

    for (let i = 0; i < n; i++) {
        imbalance += machines[i] - average;
        moves = Math.max(moves, Math.max(Math.abs(imbalance), machines[i] - average));
    }

    return moves;
}
```
1. Calculate the total number of dresses and check if it can be evenly distributed among the machines. If it cannot, return -1.
2. Calculate the average number of dresses each machine should have.
3. Initialize the moves and imbalance count to 0.
4. Iterate through the machines and calculate the current imbalance for each machine.
5. Update the moves count by taking the maximum of the current moves, the absolute value of the current imbalance, and the difference between the current machine's dresses and the average value.
6. Return the moves count.


# Coin Change II

- slug: coin-change-ii
- difficulty: Medium

You are given an integer array `coins` representing coins of different denominations and an integer `amount` representing a total amount of money.

Return _the number of combinations that make up that amount_. If that amount of money cannot be made up by any combination of the coins, return `0`.

You may assume that you have an infinite number of each kind of coin.

The answer is **guaranteed** to fit into a signed **32-bit** integer.

**Example 1:**

**Input:** amount = 5, coins = \[1,2,5\]
**Output:** 4
**Explanation:** there are four ways to make up the amount:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1

**Example 2:**

**Input:** amount = 3, coins = \[2\]
**Output:** 0
**Explanation:** the amount of 3 cannot be made up just with coins of 2.

**Example 3:**

**Input:** amount = 10, coins = \[10\]
**Output:** 1

**Constraints:**

*   `1 <= coins.length <= 300`
*   `1 <= coins[i] <= 5000`
*   All the values of `coins` are **unique**.
*   `0 <= amount <= 5000`

## A solution in Java

```java
public int change(int amount, int[] coins) {
    int[] dp = new int[amount + 1];
    dp[0] = 1;
    for (int coin : coins) {
        for (int i = coin; i <= amount; i++) {
            dp[i] += dp[i - coin];
        }
    }
    return dp[amount];
}
```
1. Initialize an array `dp` where `dp[i]` represents the number of combinations that make up the amount `i`. The length of the array is `amount + 1` to accommodate index 0. Set `dp[0]` to 1 as there is only one way to make up the amount 0 (by not picking any coins).
2. Loop through each coin in the `coins` array.
3. For each coin, iterate through the `dp` array, starting at the index equal to the coin value.
4. In each iteration, increment the value of `dp[i]` by `dp[i - coin]`. This is because the number of combinations that can make up `i` is increased by the number of combinations that can make up `i - coin`.
5. After iterating through all the coins and updating the `dp` array, return the value of `dp[amount]`, which represents the number of combinations that can make up the desired amount.

## A solution in C++

```cpp
int change(int amount, vector<int>& coins) {
    vector<int> dp(amount + 1, 0);
    dp[0] = 1;
    for (int coin : coins) {
        for (int i = coin; i <= amount; i++) {
            dp[i] += dp[i - coin];
        }
    }
    return dp[amount];
}
```
1. Initialize an array `dp` where `dp[i]` represents the number of combinations that make up the amount `i`. The length of the array is `amount + 1` to accommodate index 0. Set `dp[0]` to 1 as there is only one way to make up the amount 0 (by not picking any coins).
2. Loop through each coin in the `coins` array.
3. For each coin, iterate through the `dp` array, starting at the index equal to the coin value.
4. In each iteration, increment the value of `dp[i]` by `dp[i - coin]`. This is because the number of combinations that can make up `i` is increased by the number of combinations that can make up `i - coin`.
5. After iterating through all the coins and updating the `dp` array, return the value of `dp[amount]`, which represents the number of combinations that can make up the desired amount.

## A solution in Python

```python
def change(amount, coins):
    dp = [1] + [0] * amount
    for coin in coins:
        for i in range(coin, amount + 1):
            dp[i] += dp[i - coin]
    return dp[amount]
```
1. Initialize an array `dp` where `dp[i]` represents the number of combinations that make up the amount `i`. The length of the array is `amount + 1` to accommodate index 0. Set `dp[0]` to 1 as there is only one way to make up the amount 0 (by not picking any coins).
2. Loop through each coin in the `coins` array.
3. For each coin, iterate through the `dp` array, starting at the index equal to the coin value.
4. In each iteration, increment the value of `dp[i]` by `dp[i - coin]`. This is because the number of combinations that can make up `i` is increased by the number of combinations that can make up `i - coin`.
5. After iterating through all the coins and updating the `dp` array, return the value of `dp[amount]`, which represents the number of combinations that can make up the desired amount.

## A solution in Javascript

```javascript
function change(amount, coins) {
    let dp = new Array(amount + 1).fill(0);
    dp[0] = 1;
    for (let coin of coins) {
        for (let i = coin; i <= amount; i++) {
            dp[i] += dp[i - coin];
        }
    }
    return dp[amount];
}
```
1. Initialize an array `dp` where `dp[i]` represents the number of combinations that make up the amount `i`. The length of the array is `amount + 1` to accommodate index 0. Set `dp[0]` to 1 as there is only one way to make up the amount 0 (by not picking any coins).
2. Loop through each coin in the `coins` array.
3. For each coin, iterate through the `dp` array, starting at the index equal to the coin value.
4. In each iteration, increment the value of `dp[i]` by `dp[i - coin]`. This is because the number of combinations that can make up `i` is increased by the number of combinations that can make up `i - coin`.
5. After iterating through all the coins and updating the `dp` array, return the value of `dp[amount]`, which represents the number of combinations that can make up the desired amount.


# Random Flip Matrix

- slug: random-flip-matrix
- difficulty: Medium

There is an `m x n` binary grid `matrix` with all the values set `0` initially. Design an algorithm to randomly pick an index `(i, j)` where `matrix[i][j] == 0` and flips it to `1`. All the indices `(i, j)` where `matrix[i][j] == 0` should be equally likely to be returned.

Optimize your algorithm to minimize the number of calls made to the **built-in** random function of your language and optimize the time and space complexity.

Implement the `Solution` class:

*   `Solution(int m, int n)` Initializes the object with the size of the binary matrix `m` and `n`.
*   `int[] flip()` Returns a random index `[i, j]` of the matrix where `matrix[i][j] == 0` and flips it to `1`.
*   `void reset()` Resets all the values of the matrix to be `0`.

**Example 1:**

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

**Explanation**
Solution solution = new Solution(3, 1);
solution.flip();  // return \[1, 0\], \[0,0\], \[1,0\], and \[2,0\] should be equally likely to be returned.
solution.flip();  // return \[2, 0\], Since \[1,0\] was returned, \[2,0\] and \[0,0\]
solution.flip();  // return \[0, 0\], Based on the previously returned indices, only \[0,0\] can be returned.
solution.reset(); // All the values are reset to 0 and can be returned.
solution.flip();  // return \[2, 0\], \[0,0\], \[1,0\], and \[2,0\] should be equally likely to be returned.

**Constraints:**

*   `1 <= m, n <= 104`
*   There will be at least one free cell for each call to `flip`.
*   At most `1000` calls will be made to `flip` and `reset`.

## A solution in Java

```java
import java.util.Random;

class Solution {
    int m, n, total;
    int[][] matrix;
    Random random;

    public Solution(int m, int n) {
        this.m = m;
        this.n = n;
        total = m * n;
        matrix = new int[m][n];
        random = new Random();
    }

    public int[] flip() {
        int idx = random.nextInt(total);
        total--;

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == 0) {
                    if (idx == 0) {
                        matrix[i][j] = 1;
                        return new int[] { i, j };
                    }
                    idx--;
                }
            }
        }
        return new int[] { -1, -1 }; // This line should never be reached
    }

    public void reset() {
        total = m * n;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                matrix[i][j] = 0;
            }
        }
    }
}
```
1. Matrix is initialized with m and n, and a counter is initialized to keep track of the remaining number of 0's
2. When the flip function is called, a random index in the range of 0 to the remaining number of 0's is generated. Then, the matrix is iterated through to find the element corresponding to the random index.
3. In the flip function, for each cell with a 0, the random index is decremented. When the random index reaches 0, the cell is flipped to 1 and its position is returned.
4. Reset function resets the counter and sets all elements in the matrix back to 0.

This algorithm allows for equal probability of selecting any cell with a 0 while minimizing the number of calls to the built-in random function. The randomized selection ensures an equal chance for each candidate, and cells are only visited once. The reset function is O(m * n), but it is unlikely to be an issue in practice given the constraints.

## A solution in C++

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

class Solution {
    int rows, cols;
    int total;
    std::vector<std::vector<int>> matrix;

public:
    Solution(int m, int n) : rows(m), cols(n), total(m * n) {
        matrix = std::vector<std::vector<int>>(m, std::vector<int>(n, 0));
    }

    std::vector<int> flip() {
        int idx = rand() % total;
        total--;

        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                if (matrix[i][j] == 0) {
                    if (idx == 0) {
                        matrix[i][j] = 1;
                        return {i, j};
                    }
                    idx--;
                }
            }
        }
        return {-1, -1}; // This line should never be reached
    }

    void reset() {
        total = rows * cols;
        for (auto &row : matrix) {
            std::fill(row.begin(), row.end(), 0);
        }
    }
};
```
1. Matrix is initialized with m and n, and a counter is initialized to keep track of the remaining number of 0's
2. When the flip function is called, a random index in the range of 0 to the remaining number of 0's is generated. Then, the matrix is iterated through to find the element corresponding to the random index.
3. In the flip function, for each cell with a 0, the random index is decremented. When the random index reaches 0, the cell is flipped to 1 and its position is returned.
4. Reset function resets the counter and sets all elements in the matrix back to 0.

This algorithm allows for equal probability of selecting any cell with a 0 while minimizing the number of calls to the built-in random function. The randomized selection ensures an equal chance for each candidate, and cells are only visited once. The reset function is O(m * n), but it is unlikely to be an issue in practice given the constraints.

## A solution in Python

```python
import random

class Solution:
    def __init__(self, m: int, n: int):
        self.m, self.n = m, n
        self.total = m * n
        self.matrix = [[0] * n for _ in range(m)]

    def flip(self):
        idx = random.randint(0, self.total - 1)
        self.total -= 1

        for i in range(self.m):
            for j in range(self.n):
                if self.matrix[i][j] == 0:
                    if idx == 0:
                        self.matrix[i][j] = 1
                        return [i, j]
                    idx -= 1
        return [-1, -1] # This line should never be reached

    def reset(self):
        self.total = self.m * self.n
        for row in self.matrix:
            for j in range(self.n):
                row[j] = 0
```
1. Matrix is initialized with m and n, and a counter is initialized to keep track of the remaining number of 0's
2. When the flip function is called, a random index in the range of 0 to the remaining number of 0's is generated. Then, the matrix is iterated through to find the element corresponding to the random index.
3. In the flip function, for each cell with a 0, the random index is decremented. When the random index reaches 0, the cell is flipped to 1 and its position is returned.
4. Reset function resets the counter and sets all elements in the matrix back to 0.

This algorithm allows for equal probability of selecting any cell with a 0 while minimizing the number of calls to the built-in random function. The randomized selection ensures an equal chance for each candidate, and cells are only visited once. The reset function is O(m * n), but it is unlikely to be an issue in practice given the constraints.

## A solution in Javascript

```javascript
class Solution {
    constructor(m, n) {
        this.m = m;
        this.n = n;
        this.total = m * n;
        this.matrix = Array.from({ length: m }, () => new Array(n).fill(0));
    }

    flip() {
        const idx = Math.floor(Math.random() * this.total);
        this.total--;

        for (let i = 0; i < this.m; i++) {
            for (let j = 0; j < this.n; j++) {
                if (this.matrix[i][j] === 0) {
                    if (idx === 0) {
                        this.matrix[i][j] = 1;
                        return [i, j];
                    }
                    idx--;
                }
            }
        }
        return [-1, -1]; // This line should never be reached
    }

    reset() {
        this.total = this.m * this.n;
        for (let i = 0; i < this.m; i++) {
            for (let j = 0; j < this.n; j++) {
                this.matrix[i][j] = 0;
            }
        }
    }
}
```
1. Matrix is initialized with m and n, and a counter is initialized to keep track of the remaining number of 0's
2. When the flip function is called, a random index in the range of 0 to the remaining number of 0's is generated. Then, the matrix is iterated through to find the element corresponding to the random index.
3. In the flip function, for each cell with a 0, the random index is decremented. When the random index reaches 0, the cell is flipped to 1 and its position is returned.
4. Reset function resets the counter and sets all elements in the matrix back to 0.

This algorithm allows for equal probability of selecting any cell with a 0 while minimizing the number of calls to the built-in random function. The randomized selection ensures an equal chance for each candidate, and cells are only visited once. The reset function is O(m * n), but it is unlikely to be an issue in practice given the constraints.


# Detect Capital

- slug: detect-capital
- difficulty: Easy

We define the usage of capitals in a word to be right when one of the following cases holds:

*   All letters in this word are capitals, like `"USA "`.
*   All letters in this word are not capitals, like `"leetcode "`.
*   Only the first letter in this word is capital, like `"Google "`.

Given a string `word`, return `true` if the usage of capitals in it is right.

**Example 1:**

**Input:** word = "USA"
**Output:** true

**Example 2:**

**Input:** word = "FlaG"
**Output:** false

**Constraints:**

*   `1 <= word.length <= 100`
*   `word` consists of lowercase and uppercase English letters.

## A solution in Java

```java
public boolean detectCapitalUse(String word) {
    int numCapital = 0;
    for (char c : word.toCharArray()) {
        if (Character.isUpperCase(c)) numCapital++;
    }
    return numCapital == 0 || numCapital == word.length() || (numCapital == 1 && Character.isUpperCase(word.charAt(0)));
}
```
The algorithm keeps track of the count of capital letters in the word. It iterates over each character in the word, and if the character is uppercase, it increments the `numCapital` counter.

After iterating through the word, the algorithm checks if one of the three conditions holds:
1. There are no capital letters (`numCapital == 0`)
2. All letters are capital (`numCapital == word.size()` in C++ / `word.length` in Java and JavaScript / `len(word)` in Python)
3. Only the first letter is capital (`numCapital == 1` and the first letter is uppercase)

If any of these conditions hold, the function returns `true`, otherwise `false`.

## A solution in C++

```cpp
bool detectCapitalUse(string word) {
    int numCapital = 0;
    for (char c : word) {
        if (isupper(c)) numCapital++;
    }
    return numCapital == 0 || numCapital == word.size() || (numCapital == 1 && isupper(word[0]));
}
```
The algorithm keeps track of the count of capital letters in the word. It iterates over each character in the word, and if the character is uppercase, it increments the `numCapital` counter.

After iterating through the word, the algorithm checks if one of the three conditions holds:
1. There are no capital letters (`numCapital == 0`)
2. All letters are capital (`numCapital == word.size()` in C++ / `word.length` in Java and JavaScript / `len(word)` in Python)
3. Only the first letter is capital (`numCapital == 1` and the first letter is uppercase)

If any of these conditions hold, the function returns `true`, otherwise `false`.

## A solution in Python

```python
def detectCapitalUse(word: str) -> bool:
    numCapital = sum(1 for c in word if c.isupper())
    return numCapital == 0 or numCapital == len(word) or (numCapital == 1 and word[0].isupper())
```
The algorithm keeps track of the count of capital letters in the word. It iterates over each character in the word, and if the character is uppercase, it increments the `numCapital` counter.

After iterating through the word, the algorithm checks if one of the three conditions holds:
1. There are no capital letters (`numCapital == 0`)
2. All letters are capital (`numCapital == word.size()` in C++ / `word.length` in Java and JavaScript / `len(word)` in Python)
3. Only the first letter is capital (`numCapital == 1` and the first letter is uppercase)

If any of these conditions hold, the function returns `true`, otherwise `false`.

## A solution in Javascript

```javascript
function detectCapitalUse(word) {
    let numCapital = 0;
    for (let c of word) {
        if (c === c.toUpperCase()) numCapital++;
    }
    return numCapital === 0 || numCapital === word.length || (numCapital === 1 && word[0] === word[0].toUpperCase());
}
```
The algorithm keeps track of the count of capital letters in the word. It iterates over each character in the word, and if the character is uppercase, it increments the `numCapital` counter.

After iterating through the word, the algorithm checks if one of the three conditions holds:
1. There are no capital letters (`numCapital == 0`)
2. All letters are capital (`numCapital == word.size()` in C++ / `word.length` in Java and JavaScript / `len(word)` in Python)
3. Only the first letter is capital (`numCapital == 1` and the first letter is uppercase)

If any of these conditions hold, the function returns `true`, otherwise `false`.


# Longest Uncommon Subsequence I

- slug: longest-uncommon-subsequence-i
- difficulty: Easy

Given two strings `a` and `b`, return _the length of the **longest uncommon subsequence** between_ `a` _and_ `b`. If the longest uncommon subsequence does not exist, return `-1`.

An **uncommon subsequence** between two strings is a string that is a **subsequence of one but not the other**.

A **subsequence** of a string `s` is a string that can be obtained after deleting any number of characters from `s`.

*   For example, `"abc "` is a subsequence of `"aebdc "` because you can delete the underlined characters in `"aebdc "` to get `"abc "`. Other subsequences of `"aebdc "` include `"aebdc "`, `"aeb "`, and `" "` (empty string).

**Example 1:**

**Input:** a =  "aba ", b =  "cdc "
**Output:** 3
**Explanation:** One longest uncommon subsequence is  "aba " because  "aba " is a subsequence of  "aba " but not  "cdc ".
Note that  "cdc " is also a longest uncommon subsequence.

**Example 2:**

**Input:** a =  "aaa ", b =  "bbb "
**Output:** 3
**Explanation:** The longest uncommon subsequences are  "aaa " and  "bbb ".

**Example 3:**

**Input:** a =  "aaa ", b =  "aaa "
**Output:** -1
**Explanation:** Every subsequence of string a is also a subsequence of string b. Similarly, every subsequence of string b is also a subsequence of string a.

**Constraints:**

*   `1 <= a.length, b.length <= 100`
*   `a` and `b` consist of lower-case English letters.

## A solution in Java

```java
public int findLUSlength(String a, String b) {
    if (a.equals(b)) {
        return -1;
    }
    return Math.max(a.length(), b.length());
}
```
The algorithm is as follows:
1. First, we compare if the strings a and b are equal. If they are equal, it means that there is no uncommon subsequence between them, so we return -1.
2. If the strings are not equal, then we find the length of both strings and return the one with the maximum length. This is because the longest uncommon subsequence can be the longer of the two strings itself (since it is not a subsequence of the other string).

## A solution in C++

```cpp
int findLUSlength(string a, string b) {
    if (a == b) {
        return -1;
    }
    return max(a.length(), b.length());
}
```
The algorithm is as follows:
1. First, we compare if the strings a and b are equal. If they are equal, it means that there is no uncommon subsequence between them, so we return -1.
2. If the strings are not equal, then we find the length of both strings and return the one with the maximum length. This is because the longest uncommon subsequence can be the longer of the two strings itself (since it is not a subsequence of the other string).

## A solution in Python

```python
def findLUSlength(a: str, b: str) -> int:
    if a == b:
        return -1
    return max(len(a), len(b))
```
The algorithm is as follows:
1. First, we compare if the strings a and b are equal. If they are equal, it means that there is no uncommon subsequence between them, so we return -1.
2. If the strings are not equal, then we find the length of both strings and return the one with the maximum length. This is because the longest uncommon subsequence can be the longer of the two strings itself (since it is not a subsequence of the other string).

## A solution in Javascript

```javascript
function findLUSlength(a, b) {
    if (a === b) {
        return -1;
    }
    return Math.max(a.length, b.length);
}
```
The algorithm is as follows:
1. First, we compare if the strings a and b are equal. If they are equal, it means that there is no uncommon subsequence between them, so we return -1.
2. If the strings are not equal, then we find the length of both strings and return the one with the maximum length. This is because the longest uncommon subsequence can be the longer of the two strings itself (since it is not a subsequence of the other string).


# Longest Uncommon Subsequence II

- slug: longest-uncommon-subsequence-ii
- difficulty: Medium

Given an array of strings `strs`, return _the length of the **longest uncommon subsequence** between them_. If the longest uncommon subsequence does not exist, return `-1`.

An **uncommon subsequence** between an array of strings is a string that is a **subsequence of one string but not the others**.

A **subsequence** of a string `s` is a string that can be obtained after deleting any number of characters from `s`.

*   For example, `"abc "` is a subsequence of `"aebdc "` because you can delete the underlined characters in `"aebdc "` to get `"abc "`. Other subsequences of `"aebdc "` include `"aebdc "`, `"aeb "`, and `" "` (empty string).

**Example 1:**

**Input:** strs = \["aba","cdc","eae"\]
**Output:** 3

**Example 2:**

**Input:** strs = \["aaa","aaa","aa"\]
**Output:** -1

**Constraints:**

*   `2 <= strs.length <= 50`
*   `1 <= strs[i].length <= 10`
*   `strs[i]` consists of lowercase English letters.

## A solution in Java

```java
import java.util.List;

public int findLUSlength(List<String> strs) {
    int maxLength = -1;
    for(int i = 0; i < strs.size(); ++i) {
        boolean isUncommon = true;
        for(int j = 0; j < strs.size(); ++j) {
            if(i != j && strs.get(j).contains(strs.get(i))) {
                isUncommon = false;
                break;
            }
        }
        if(isUncommon) {
            maxLength = Math.max(maxLength, strs.get(i).length());
        }
    }
    return maxLength;
}
```
The algorithm first initializes a variable `maxLength` which will store the maximum length of the uncommon subsequence. Then it iterates through the input array of strings. For each string, it checks if it is an uncommon subsequence among the array elements. This check is done by iterating through the input array again, comparing the current string with all other strings in the array. If it's found that the current string is a subsequence of another string in the array, the current string cannot be the uncommon subsequence. If the current string is uncommon, its length is compared to the current value of `maxLength` and the maximum value is stored in `maxLength`. Finally, the `maxLength` will contain the length of the longest uncommon subsequence, or -1 if such a subsequence does not exist.

## A solution in C++

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

int findLUSlength(std::vector<std::string>& strs) {
    int maxLength = -1;
    for(int i = 0; i < strs.size(); ++i) {
        bool isUncommon = true;
        for(int j = 0; j < strs.size(); ++j) {
            if(i != j && std::search(strs[j].begin(), strs[j].end(), strs[i].begin(), strs[i].end()) != strs[j].end()) {
                isUncommon = false;
                break;
            }
        }
        if(isUncommon) {
            maxLength = std::max(maxLength, static_cast<int>(strs[i].length()));
        }
    }
    return maxLength;
}
```
The algorithm first initializes a variable `maxLength` which will store the maximum length of the uncommon subsequence. Then it iterates through the input array of strings. For each string, it checks if it is an uncommon subsequence among the array elements. This check is done by iterating through the input array again, comparing the current string with all other strings in the array. If it's found that the current string is a subsequence of another string in the array, the current string cannot be the uncommon subsequence. If the current string is uncommon, its length is compared to the current value of `maxLength` and the maximum value is stored in `maxLength`. Finally, the `maxLength` will contain the length of the longest uncommon subsequence, or -1 if such a subsequence does not exist.

## A solution in Python

```python
def find_lus_length(strs):
    max_length = -1
    for i in range(len(strs)):
        is_uncommon = True
        for j in range(len(strs)):
            if i != j and strs[i] in strs[j]:
                is_uncommon = False
                break
        if is_uncommon:
            max_length = max(max_length, len(strs[i]))
    return max_length
```
The algorithm first initializes a variable `maxLength` which will store the maximum length of the uncommon subsequence. Then it iterates through the input array of strings. For each string, it checks if it is an uncommon subsequence among the array elements. This check is done by iterating through the input array again, comparing the current string with all other strings in the array. If it's found that the current string is a subsequence of another string in the array, the current string cannot be the uncommon subsequence. If the current string is uncommon, its length is compared to the current value of `maxLength` and the maximum value is stored in `maxLength`. Finally, the `maxLength` will contain the length of the longest uncommon subsequence, or -1 if such a subsequence does not exist.

## A solution in Javascript

```javascript
function findLUSlength(strs) {
    let maxLength = -1;
    for(let i = 0; i < strs.length; ++i) {
        let isUncommon = true;
        for(let j = 0; j < strs.length; ++j) {
            if(i != j && strs[j].includes(strs[i])) {
                isUncommon = false;
                break;
            }
        }
        if(isUncommon) {
            maxLength = Math.max(maxLength, strs[i].length);
        }
    }
    return maxLength;
}
```
The algorithm first initializes a variable `maxLength` which will store the maximum length of the uncommon subsequence. Then it iterates through the input array of strings. For each string, it checks if it is an uncommon subsequence among the array elements. This check is done by iterating through the input array again, comparing the current string with all other strings in the array. If it's found that the current string is a subsequence of another string in the array, the current string cannot be the uncommon subsequence. If the current string is uncommon, its length is compared to the current value of `maxLength` and the maximum value is stored in `maxLength`. Finally, the `maxLength` will contain the length of the longest uncommon subsequence, or -1 if such a subsequence does not exist.


# Continuous Subarray Sum

- slug: continuous-subarray-sum
- difficulty: Medium

Given an integer array nums and an integer k, return `true` _if_ `nums` _has a **good subarray** or_ `false` _otherwise_.

A **good subarray** is a subarray where:

*   its length is **at least two**, and
*   the sum of the elements of the subarray is a multiple of `k`.

**Note** that:

*   A **subarray** is a contiguous part of the array.
*   An integer `x` is a multiple of `k` if there exists an integer `n` such that `x = n * k`. `0` is **always** a multiple of `k`.

**Example 1:**

**Input:** nums = \[23,2,4,6,7\], k = 6
**Output:** true
**Explanation:** \[2, 4\] is a continuous subarray of size 2 whose elements sum up to 6.

**Example 2:**

**Input:** nums = \[23,2,6,4,7\], k = 6
**Output:** true
**Explanation:** \[23, 2, 6, 4, 7\] is an continuous subarray of size 5 whose elements sum up to 42.
42 is a multiple of 6 because 42 = 7 \* 6 and 7 is an integer.

**Example 3:**

**Input:** nums = \[23,2,6,4,7\], k = 13
**Output:** false

**Constraints:**

*   `1 <= nums.length <= 105`
*   `0 <= nums[i] <= 109`
*   `0 <= sum(nums[i]) <= 231 - 1`
*   `1 <= k <= 231 - 1`

## A solution in Java

```java
import java.util.HashMap;

public boolean checkSubarraySum(int[] nums, int k) {
    int n = nums.length, sum = 0;
    HashMap<Integer, Integer> map = new HashMap<>();
    map.put(0, -1);
    for (int i = 0; i < n; i++) {
        sum += nums[i];
        if (k != 0) sum %= k;
        if (map.containsKey(sum)) {
            if (i - map.get(sum) > 1) return true;
        } else {
            map.put(sum, i);
        }
    }
    return false;
}
```
The algorithm uses a hashmap to store the running sum from the beginning of the array to the current index while iterating through the array. Each iteration, it updates the sum by adding the current number and calculates the modulus of the updated sum with k. If the resultant remainder is already in hashmap and the distance between the current index and the index in hashmap is greater than 1, then it returns true. If the modulus isn't in the hashmap, then it adds the sum and current index to the hashmap. After iterating through the entire array if no subarray with sum multiple of k is found, then it returns false.

## A solution in C++

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

bool checkSubarraySum(std::vector<int>& nums, int k) {
    int n = nums.size(), sum = 0;
    std::unordered_map<int, int> mp;
    mp[0] = -1;
    for (int i = 0; i < n; ++i) {
        sum += nums[i];
        if (k != 0) sum %= k;
        if (mp.count(sum)) {
            if (i - mp[sum] > 1) return true;
        } else {
            mp[sum] = i;
        }
    }
    return false;
}
```
The algorithm uses a hashmap to store the running sum from the beginning of the array to the current index while iterating through the array. Each iteration, it updates the sum by adding the current number and calculates the modulus of the updated sum with k. If the resultant remainder is already in hashmap and the distance between the current index and the index in hashmap is greater than 1, then it returns true. If the modulus isn't in the hashmap, then it adds the sum and current index to the hashmap. After iterating through the entire array if no subarray with sum multiple of k is found, then it returns false.

## A solution in Python

```python
def checkSubarraySum(nums, k):
    n, sum_ = len(nums), 0
    mp = {0: -1}
    for i, num in enumerate(nums):
        sum_ += num
        if k != 0:
            sum_ %= k
        if sum_ in mp:
            if i - mp[sum_] > 1:
                return True
        else:
            mp[sum_] = i
    return False
```
The algorithm uses a hashmap to store the running sum from the beginning of the array to the current index while iterating through the array. Each iteration, it updates the sum by adding the current number and calculates the modulus of the updated sum with k. If the resultant remainder is already in hashmap and the distance between the current index and the index in hashmap is greater than 1, then it returns true. If the modulus isn't in the hashmap, then it adds the sum and current index to the hashmap. After iterating through the entire array if no subarray with sum multiple of k is found, then it returns false.

## A solution in Javascript

```javascript
function checkSubarraySum(nums, k) {
    let n = nums.length, sum = 0, mp = new Map();
    mp.set(0, -1);
    for (let i = 0; i < n; i++) {
        sum += nums[i];
        if (k !== 0) sum %= k;
        if (mp.has(sum)) {
            if (i - mp.get(sum) > 1) return true;
        } else {
            mp.set(sum, i);
        }
    }
    return false;
}
```
The algorithm uses a hashmap to store the running sum from the beginning of the array to the current index while iterating through the array. Each iteration, it updates the sum by adding the current number and calculates the modulus of the updated sum with k. If the resultant remainder is already in hashmap and the distance between the current index and the index in hashmap is greater than 1, then it returns true. If the modulus isn't in the hashmap, then it adds the sum and current index to the hashmap. After iterating through the entire array if no subarray with sum multiple of k is found, then it returns false.