# Check if There is a Valid Path in a Grid

- slug: check-if-there-is-a-valid-path-in-a-grid
- difficulty: Medium

You are given an `m x n` `grid`. Each cell of `grid` represents a street. The street of `grid[i][j]` can be:

*   `1` which means a street connecting the left cell and the right cell.
*   `2` which means a street connecting the upper cell and the lower cell.
*   `3` which means a street connecting the left cell and the lower cell.
*   `4` which means a street connecting the right cell and the lower cell.
*   `5` which means a street connecting the left cell and the upper cell.
*   `6` which means a street connecting the right cell and the upper cell.

You will initially start at the street of the upper-left cell `(0, 0)`. A valid path in the grid is a path that starts from the upper left cell `(0, 0)` and ends at the bottom-right cell `(m - 1, n - 1)`. **The path should only follow the streets**.

**Notice** that you are **not allowed** to change any street.

Return `true` _if there is a valid path in the grid or_ `false` _otherwise_.

**Example 1:**

**Input:** grid = \[\[2,4,3\],\[6,5,2\]\]
**Output:** true
**Explanation:** As shown you can start at cell (0, 0) and visit all the cells of the grid to reach (m - 1, n - 1).

**Example 2:**

**Input:** grid = \[\[1,2,1\],\[1,2,1\]\]
**Output:** false
**Explanation:** As shown you the street at cell (0, 0) is not connected with any street of any other cell and you will get stuck at cell (0, 0)

**Example 3:**

**Input:** grid = \[\[1,1,2\]\]
**Output:** false
**Explanation:** You will get stuck at cell (0, 1) and you cannot reach cell (0, 2).

**Constraints:**

*   `m == grid.length`
*   `n == grid[i].length`
*   `1 <= m, n <= 300`
*   `1 <= grid[i][j] <= 6`

## A solution in Java

```java
public boolean hasValidPath(int[][] grid) {
    int m = grid.length;
    int n = grid[0].length;

    int[][] directions = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
    int[][] allowed = {{}, {0, 2}, {1, 3}, {0, 1}, {0, 3}, {1, 2}, {1, 0}};

    boolean[][] visited = new boolean[m][n];

    class DFS {
        boolean search(int i, int j) {
            if (i == m - 1 && j == n - 1) return true;
            visited[i][j] = true;
            for (int dir : allowed[grid[i][j]]) {
                int x = i + directions[dir][0];
                int y = j + directions[dir][1];
                if (x >= 0 && y >= 0 && x < m && y < n && !visited[x][y] && Arrays.stream(allowed[grid[x][y]]).anyMatch(d -> d == (dir + 2) % 4)) {
                    if (search(x, y)) return true;
                }
            }
            return false;
        }
    }

    return new DFS().search(0, 0);
}
```
The problem can be solved using Depth First Search (DFS). The DFS function is defined and starts from the upper-left cell (0, 0) and explores one of its connected streets/cells based on the allowed connections between the streets. The 'allowed' variable is used to store these connections, such that the pairs of directions that are allowed to connect for each street are listed. For example, for street 1, the pairs 0 and 2 are allowed (left and right).

The 'directions' variable is used to define how to navigate the grid by moving up, down, left, or right using indices. In the DFS function, we loop through all of the directions (dir) that are allowed for the current cell's street (i, j) using the 'allowed' list described before. For each allowed direction, we calculate the new position on the grid (x, y) and then check if this new position is within the grid bounds, if it has not been visited before, and if the new cell's street at (x, y) has a connection back to the current cell (i, j) (using (dir + 2) % 4 checks for the direction that is opposite of the current direction).

If all conditions are true, we continue to explore the path by calling dfs(x, y), and if the DFS returns True, return True.

The function returns False when there is no valid path to the bottom-right cell (m - 1, n - 1).

The overall complexity of this algorithm is O(m * n), where m and n are the dimensions of the grid, as each cell can potentially be visited once.

## A solution in C++

```cpp
bool hasValidPath(vector<vector<int>>& grid) {
    int m = grid.size();
    int n = grid[0].size();

    vector<vector<int>> directions = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
    vector<vector<int>> allowed = {{}, {0, 2}, {1, 3}, {0, 1}, {0, 3}, {1, 2}, {1, 0}};

    vector<vector<bool>> visited(m, vector<bool>(n, false));

    function<bool(int, int)> dfs = [&](int i, int j) -> bool {
        if (i == m - 1 && j == n - 1) return true;
        visited[i][j] = true;
        for (int dir : allowed[grid[i][j]]) {
            int x = i + directions[dir][0];
            int y = j + directions[dir][1];
            if (x >= 0 && y >= 0 && x < m && y < n && !visited[x][y] && find(allowed[grid[x][y]].begin(), allowed[grid[x][y]].end(), (dir + 2) % 4) != allowed[grid[x][y]].end()) {
                if (dfs(x, y)) return true;
            }
        }
        return false;
    };

    return dfs(0, 0);
}
```
The problem can be solved using Depth First Search (DFS). The DFS function is defined and starts from the upper-left cell (0, 0) and explores one of its connected streets/cells based on the allowed connections between the streets. The 'allowed' variable is used to store these connections, such that the pairs of directions that are allowed to connect for each street are listed. For example, for street 1, the pairs 0 and 2 are allowed (left and right).

The 'directions' variable is used to define how to navigate the grid by moving up, down, left, or right using indices. In the DFS function, we loop through all of the directions (dir) that are allowed for the current cell's street (i, j) using the 'allowed' list described before. For each allowed direction, we calculate the new position on the grid (x, y) and then check if this new position is within the grid bounds, if it has not been visited before, and if the new cell's street at (x, y) has a connection back to the current cell (i, j) (using (dir + 2) % 4 checks for the direction that is opposite of the current direction).

If all conditions are true, we continue to explore the path by calling dfs(x, y), and if the DFS returns True, return True.

The function returns False when there is no valid path to the bottom-right cell (m - 1, n - 1).

The overall complexity of this algorithm is O(m * n), where m and n are the dimensions of the grid, as each cell can potentially be visited once.

## A solution in Python

```python
def hasValidPath(grid):
    m, n = len(grid), len(grid[0])

    directions = [(0, -1), (-1, 0), (0, 1), (1, 0)]
    allowed = [[], [0, 2], [1, 3], [0, 1], [0, 3], [1, 2], [1, 0]]

    visited = [[False] * n for _ in range(m)]

    def dfs(i, j):
        if i == m - 1 and j == n - 1:
            return True

        visited[i][j] = True
        for dir in allowed[grid[i][j]]:
            x, y = i + directions[dir][0], j + directions[dir][1]
            if 0 <= x < m and 0 <= y < n and not visited[x][y] and (dir + 2) % 4 in allowed[grid[x][y]]:
                if dfs(x, y):
                    return True
        return False

    return dfs(0, 0)
```
The problem can be solved using Depth First Search (DFS). The DFS function is defined and starts from the upper-left cell (0, 0) and explores one of its connected streets/cells based on the allowed connections between the streets. The 'allowed' variable is used to store these connections, such that the pairs of directions that are allowed to connect for each street are listed. For example, for street 1, the pairs 0 and 2 are allowed (left and right).

The 'directions' variable is used to define how to navigate the grid by moving up, down, left, or right using indices. In the DFS function, we loop through all of the directions (dir) that are allowed for the current cell's street (i, j) using the 'allowed' list described before. For each allowed direction, we calculate the new position on the grid (x, y) and then check if this new position is within the grid bounds, if it has not been visited before, and if the new cell's street at (x, y) has a connection back to the current cell (i, j) (using (dir + 2) % 4 checks for the direction that is opposite of the current direction).

If all conditions are true, we continue to explore the path by calling dfs(x, y), and if the DFS returns True, return True.

The function returns False when there is no valid path to the bottom-right cell (m - 1, n - 1).

The overall complexity of this algorithm is O(m * n), where m and n are the dimensions of the grid, as each cell can potentially be visited once.

## A solution in Javascript

```javascript
function hasValidPath(grid) {
    const m = grid.length;
    const n = grid[0].length;

    const directions = [[0, -1], [-1, 0], [0, 1], [1, 0]];
    const allowed = [[], [0, 2], [1, 3], [0, 1], [0, 3], [1, 2], [1, 0]];

    const visited = Array.from({ length: m }, () => Array(n).fill(false));

    const dfs = (i, j) => {
        if (i === m - 1 && j === n - 1) return true;
        visited[i][j] = true;
        for (const dir of allowed[grid[i][j]]) {
            const x = i + directions[dir][0];
            const y = j + directions[dir][1];
            if (x >= 0 && y >= 0 && x < m && y < n && !visited[x][y] && allowed[grid[x][y]].includes((dir + 2) % 4)) {
                if (dfs(x, y)) return true;
            }
        }
        return false;
    };

    return dfs(0, 0);
}
```
The problem can be solved using Depth First Search (DFS). The DFS function is defined and starts from the upper-left cell (0, 0) and explores one of its connected streets/cells based on the allowed connections between the streets. The 'allowed' variable is used to store these connections, such that the pairs of directions that are allowed to connect for each street are listed. For example, for street 1, the pairs 0 and 2 are allowed (left and right).

The 'directions' variable is used to define how to navigate the grid by moving up, down, left, or right using indices. In the DFS function, we loop through all of the directions (dir) that are allowed for the current cell's street (i, j) using the 'allowed' list described before. For each allowed direction, we calculate the new position on the grid (x, y) and then check if this new position is within the grid bounds, if it has not been visited before, and if the new cell's street at (x, y) has a connection back to the current cell (i, j) (using (dir + 2) % 4 checks for the direction that is opposite of the current direction).

If all conditions are true, we continue to explore the path by calling dfs(x, y), and if the DFS returns True, return True.

The function returns False when there is no valid path to the bottom-right cell (m - 1, n - 1).

The overall complexity of this algorithm is O(m * n), where m and n are the dimensions of the grid, as each cell can potentially be visited once.


# Find Lucky Integer in an Array

- slug: find-lucky-integer-in-an-array
- difficulty: Easy

Given an array of integers `arr`, a **lucky integer** is an integer that has a frequency in the array equal to its value.

Return _the largest **lucky integer** in the array_. If there is no **lucky integer** return `-1`.

**Example 1:**

**Input:** arr = \[2,2,3,4\]
**Output:** 2
**Explanation:** The only lucky number in the array is 2 because frequency\[2\] == 2.

**Example 2:**

**Input:** arr = \[1,2,2,3,3,3\]
**Output:** 3
**Explanation:** 1, 2 and 3 are all lucky numbers, return the largest of them.

**Example 3:**

**Input:** arr = \[2,2,2,3,3\]
**Output:** -1
**Explanation:** There are no lucky numbers in the array.

**Constraints:**

*   `1 <= arr.length <= 500`
*   `1 <= arr[i] <= 500`

## A solution in Java

```java
public int findLucky(int[] arr) {
    Map<Integer, Integer> freq = new HashMap<>();
    for (int num : arr) {
        freq.put(num, freq.getOrDefault(num, 0) + 1);
    }
    int maxLucky = -1;
    for (Map.Entry<Integer, Integer> entry : freq.entrySet()) {
        if (entry.getKey().equals(entry.getValue())) {
            maxLucky = Math.max(maxLucky, entry.getKey());
        }
    }
    return maxLucky;
}
```
The algorithm iterates over the input array, computing the frequency of each number. It then iterates through the frequencies and checks if the number and its frequency match. If they do, it keeps track of the maximum such number. Finally, the algorithm returns the maximum lucky integer. If no lucky integer is found, the function returns -1.

## A solution in C++

```cpp
int findLucky(vector<int>& arr) {
    unordered_map<int, int> freq;
    for (int num : arr) {
        freq[num]++;
    }
    int maxLucky = -1;
    for (auto& pair : freq) {
        if (pair.first == pair.second) {
            maxLucky = max(maxLucky, pair.first);
        }
    }
    return maxLucky;
}
```
The algorithm iterates over the input array, computing the frequency of each number. It then iterates through the frequencies and checks if the number and its frequency match. If they do, it keeps track of the maximum such number. Finally, the algorithm returns the maximum lucky integer. If no lucky integer is found, the function returns -1.

## A solution in Python

```python
def find_lucky(arr):
    freq = {}
    for num in arr:
        freq[num] = freq.get(num, 0) + 1
    max_lucky = -1
    for num, count in freq.items():
        if num == count:
            max_lucky = max(max_lucky, num)
    return max_lucky
```
The algorithm iterates over the input array, computing the frequency of each number. It then iterates through the frequencies and checks if the number and its frequency match. If they do, it keeps track of the maximum such number. Finally, the algorithm returns the maximum lucky integer. If no lucky integer is found, the function returns -1.

## A solution in Javascript

```javascript
function findLucky(arr) {
    const freq = {};
    for (const num of arr) {
        if (!freq[num]) {
            freq[num] = 0;
        }
        freq[num]++;
    }
    let maxLucky = -1;
    for (const [num, count] of Object.entries(freq)) {
        if ( parseInt(num) === count) {
            maxLucky = Math.max(maxLucky, parseInt(num));
        }
    }
    return maxLucky;
}
```
The algorithm iterates over the input array, computing the frequency of each number. It then iterates through the frequencies and checks if the number and its frequency match. If they do, it keeps track of the maximum such number. Finally, the algorithm returns the maximum lucky integer. If no lucky integer is found, the function returns -1.


# Count Number of Teams

- slug: count-number-of-teams
- difficulty: Medium

There are `n` soldiers standing in a line. Each soldier is assigned a **unique** `rating` value.

You have to form a team of 3 soldiers amongst them under the following rules:

*   Choose 3 soldiers with index (`i`, `j`, `k`) with rating (`rating[i]`, `rating[j]`, `rating[k]`).
*   A team is valid if: (`rating[i] < rating[j] < rating[k]`) or (`rating[i] > rating[j] > rating[k]`) where (`0 <= i < j < k < n`).

Return the number of teams you can form given the conditions. (soldiers can be part of multiple teams).

**Example 1:**

**Input:** rating = \[2,5,3,4,1\]
**Output:** 3
**Explanation:** We can form three teams given the conditions. (2,3,4), (5,4,1), (5,3,1).

**Example 2:**

**Input:** rating = \[2,1,3\]
**Output:** 0
**Explanation:** We can't form any team given the conditions.

**Example 3:**

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

**Constraints:**

*   `n == rating.length`
*   `3 <= n <= 1000`
*   `1 <= rating[i] <= 105`
*   All the integers in `rating` are **unique**.

In one second, you can either: - Move vertically by one unit, - Move horizontally by one unit, or - Move diagonally sqrt(2) units (in other words, move one unit vertically then one unit horizontally in one second). You have to visit the points in the same order as they appear in the array. You are allowed to pass through points, but they do not count as visited unless you stop on them.

## A solution in Java

```java
public int minTimeToVisitAllPoints(int[][] points) {
    int time = 0;
    for(int i = 1; i < points.length; ++i) {
        int dx = Math.abs(points[i][0] - points[i-1][0]);
        int dy = Math.abs(points[i][1] - points[i-1][1]);
        time += Math.max(dx, dy);
    }
    return time;
}
```
The algorithm calculates the minimum time to visit all the points by iterating through the given points, and for each pair of consecutive points, finding the difference in their x and y coordinates (dx and dy). Since moving diagonally is the fastest way to cover a unit of distance vertically and horizontally, the time needed to move between two points is the maximum of dx and dy.

In each language, the code follows the same logic: iterate through the points, calculate the difference in x and y coordinates, and add the maximum of those differences to the total time. The primary differences are in syntax and the specific functions used to calculate the absolute value and maximum value.

## A solution in C++

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

int minTimeToVisitAllPoints(std::vector<std::vector<int>>& points) {
    int time = 0;
    for(int i = 1; i < points.size(); ++i) {
        int dx = abs(points[i][0] - points[i-1][0]);
        int dy = abs(points[i][1] - points[i-1][1]);
        time += std::max(dx, dy);
    }
    return time;
}
```
The algorithm calculates the minimum time to visit all the points by iterating through the given points, and for each pair of consecutive points, finding the difference in their x and y coordinates (dx and dy). Since moving diagonally is the fastest way to cover a unit of distance vertically and horizontally, the time needed to move between two points is the maximum of dx and dy.

In each language, the code follows the same logic: iterate through the points, calculate the difference in x and y coordinates, and add the maximum of those differences to the total time. The primary differences are in syntax and the specific functions used to calculate the absolute value and maximum value.

## A solution in Python

```python
def minTimeToVisitAllPoints(points: List[List[int]]) -> int:
    time = 0
    for i in range(1, len(points)):
        dx = abs(points[i][0] - points[i-1][0])
        dy = abs(points[i][1] - points[i-1][1])
        time += max(dx, dy)
    return time
```
The algorithm calculates the minimum time to visit all the points by iterating through the given points, and for each pair of consecutive points, finding the difference in their x and y coordinates (dx and dy). Since moving diagonally is the fastest way to cover a unit of distance vertically and horizontally, the time needed to move between two points is the maximum of dx and dy.

In each language, the code follows the same logic: iterate through the points, calculate the difference in x and y coordinates, and add the maximum of those differences to the total time. The primary differences are in syntax and the specific functions used to calculate the absolute value and maximum value.

## A solution in Javascript

```javascript
function minTimeToVisitAllPoints(points) {
    let time = 0;
    for(let i = 1; i < points.length; ++i) {
        let dx = Math.abs(points[i][0] - points[i-1][0]);
        let dy = Math.abs(points[i][1] - points[i-1][1]);
        time += Math.max(dx, dy);
    }
    return time;
}
```
The algorithm calculates the minimum time to visit all the points by iterating through the given points, and for each pair of consecutive points, finding the difference in their x and y coordinates (dx and dy). Since moving diagonally is the fastest way to cover a unit of distance vertically and horizontally, the time needed to move between two points is the maximum of dx and dy.

In each language, the code follows the same logic: iterate through the points, calculate the difference in x and y coordinates, and add the maximum of those differences to the total time. The primary differences are in syntax and the specific functions used to calculate the absolute value and maximum value.


# Design Underground System

- slug: design-underground-system
- difficulty: Medium

An underground railway system is keeping track of customer travel times between different stations. They are using this data to calculate the average time it takes to travel from one station to another.

Implement the `UndergroundSystem` class:

*   `void checkIn(int id, string stationName, int t)`
    *   A customer with a card ID equal to `id`, checks in at the station `stationName` at time `t`.
    *   A customer can only be checked into one place at a time.
*   `void checkOut(int id, string stationName, int t)`
    *   A customer with a card ID equal to `id`, checks out from the station `stationName` at time `t`.
*   `double getAverageTime(string startStation, string endStation)`
    *   Returns the average time it takes to travel from `startStation` to `endStation`.
    *   The average time is computed from all the previous traveling times from `startStation` to `endStation` that happened **directly**, meaning a check in at `startStation` followed by a check out from `endStation`.
    *   The time it takes to travel from `startStation` to `endStation` **may be different** from the time it takes to travel from `endStation` to `startStation`.
    *   There will be at least one customer that has traveled from `startStation` to `endStation` before `getAverageTime` is called.

You may assume all calls to the `checkIn` and `checkOut` methods are consistent. If a customer checks in at time `t1` then checks out at time `t2`, then `t1 < t2`. All events happen in chronological order.

**Example 1:**

**Input**
\[ "UndergroundSystem ", "checkIn ", "checkIn ", "checkIn ", "checkOut ", "checkOut ", "checkOut ", "getAverageTime ", "getAverageTime ", "checkIn ", "getAverageTime ", "checkOut ", "getAverageTime "\]
\[\[\],\[45, "Leyton ",3\],\[32, "Paradise ",8\],\[27, "Leyton ",10\],\[45, "Waterloo ",15\],\[27, "Waterloo ",20\],\[32, "Cambridge ",22\],\[ "Paradise ", "Cambridge "\],\[ "Leyton ", "Waterloo "\],\[10, "Leyton ",24\],\[ "Leyton ", "Waterloo "\],\[10, "Waterloo ",38\],\[ "Leyton ", "Waterloo "\]\]

**Output**
\[null,null,null,null,null,null,null,14.00000,11.00000,null,11.00000,null,12.00000\]

**Explanation**
UndergroundSystem undergroundSystem = new UndergroundSystem();
undergroundSystem.checkIn(45,  "Leyton ", 3);
undergroundSystem.checkIn(32,  "Paradise ", 8);
undergroundSystem.checkIn(27,  "Leyton ", 10);
undergroundSystem.checkOut(45,  "Waterloo ", 15);  // Customer 45  "Leyton " ->  "Waterloo " in 15-3 = 12
undergroundSystem.checkOut(27,  "Waterloo ", 20);  // Customer 27  "Leyton " ->  "Waterloo " in 20-10 = 10
undergroundSystem.checkOut(32,  "Cambridge ", 22); // Customer 32  "Paradise " ->  "Cambridge " in 22-8 = 14
undergroundSystem.getAverageTime( "Paradise ",  "Cambridge "); // return 14.00000. One trip  "Paradise " ->  "Cambridge ", (14) / 1 = 14
undergroundSystem.getAverageTime( "Leyton ",  "Waterloo ");    // return 11.00000. Two trips  "Leyton " ->  "Waterloo ", (10 + 12) / 2 = 11
undergroundSystem.checkIn(10,  "Leyton ", 24);
undergroundSystem.getAverageTime( "Leyton ",  "Waterloo ");    // return 11.00000
undergroundSystem.checkOut(10,  "Waterloo ", 38);  // Customer 10  "Leyton " ->  "Waterloo " in 38-24 = 14
undergroundSystem.getAverageTime( "Leyton ",  "Waterloo ");    // return 12.00000. Three trips  "Leyton " ->  "Waterloo ", (10 + 12 + 14) / 3 = 12

**Example 2:**

**Input**
\[ "UndergroundSystem ", "checkIn ", "checkOut ", "getAverageTime ", "checkIn ", "checkOut ", "getAverageTime ", "checkIn ", "checkOut ", "getAverageTime "\]
\[\[\],\[10, "Leyton ",3\],\[10, "Paradise ",8\],\[ "Leyton ", "Paradise "\],\[5, "Leyton ",10\],\[5, "Paradise ",16\],\[ "Leyton ", "Paradise "\],\[2, "Leyton ",21\],\[2, "Paradise ",30\],\[ "Leyton ", "Paradise "\]\]

**Output**
\[null,null,null,5.00000,null,null,5.50000,null,null,6.66667\]

**Explanation**
UndergroundSystem undergroundSystem = new UndergroundSystem();
undergroundSystem.checkIn(10,  "Leyton ", 3);
undergroundSystem.checkOut(10,  "Paradise ", 8); // Customer 10  "Leyton " ->  "Paradise " in 8-3 = 5
undergroundSystem.getAverageTime( "Leyton ",  "Paradise "); // return 5.00000, (5) / 1 = 5
undergroundSystem.checkIn(5,  "Leyton ", 10);
undergroundSystem.checkOut(5,  "Paradise ", 16); // Customer 5  "Leyton " ->  "Paradise " in 16-10 = 6
undergroundSystem.getAverageTime( "Leyton ",  "Paradise "); // return 5.50000, (5 + 6) / 2 = 5.5
undergroundSystem.checkIn(2,  "Leyton ", 21);
undergroundSystem.checkOut(2,  "Paradise ", 30); // Customer 2  "Leyton " ->  "Paradise " in 30-21 = 9
undergroundSystem.getAverageTime( "Leyton ",  "Paradise "); // return 6.66667, (5 + 6 + 9) / 3 = 6.66667

**Constraints:**

*   `1 <= id, t <= 106`
*   `1 <= stationName.length, startStation.length, endStation.length <= 10`
*   All strings consist of uppercase and lowercase English letters and digits.
*   There will be at most `2 * 104` calls **in total** to `checkIn`, `checkOut`, and `getAverageTime`.
*   Answers within `10-5` of the actual value will be accepted.

## A solution in Java

```java
import java.util.*;

class UndergroundSystem {
    private Map<Integer, Pair<String, Integer>> checkInInfo;
    private Map<String, Pair<Integer, Integer>> journeyData;

    public UndergroundSystem() {
        checkInInfo = new HashMap<>();
        journeyData = new HashMap<>();
    }

    public void checkIn(int id, String stationName, int t) {
        checkInInfo.put(id, new Pair<>(stationName, t));
    }

    public void checkOut(int id, String stationName, int t) {
        Pair<String, Integer> startInfo = checkInInfo.get(id);
        String route = startInfo.getKey() + "_" + stationName;
        int duration = t - startInfo.getValue();
        Pair<Integer, Integer> data = journeyData.getOrDefault(route, new Pair<>(0, 0));
        journeyData.put(route, new Pair<>(data.getKey() + duration, data.getValue() + 1));
    }

    public double getAverageTime(String startStation, String endStation) {
        String route = startStation + "_" + endStation;
        Pair<Integer, Integer> data = journeyData.get(route);
        return (double) data.getKey() / data.getValue();
    }
}
```
We use two hashmaps, one for keeping track of checkIn information and one for keeping track of journey data. When a user checks in, we store their check-in information (station and time) in the checkInInfo hashmap. When a user checks out, we retrieve their stored check-in information, calculate the duration of the journey, and store or update the journey data in the journeyData hashmap. To obtain the average time for a journey between two stations, we retrieve the aggregated journey data from the journeyData hashmap and calculate the average.

## A solution in C++

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

class UndergroundSystem {
public:
    unordered_map<int, pair<string, int>> checkin_info;
    unordered_map<string, pair<int, int>> journey_data;

    void checkIn(int id, string stationName, int t) {
        checkin_info[id] = {stationName, t};
    }

    void checkOut(int id, string stationName, int t) {
        auto& start_info = checkin_info[id];
        string route = start_info.first + "_" + stationName;
        int duration = t - start_info.second;
        journey_data[route].first += duration;
        journey_data[route].second ++;
    }

    double getAverageTime(string startStation, string endStation) {
        string route = startStation + "_" + endStation;
        auto& data = journey_data[route];
        return (double)data.first / data.second;
    }
};
```
We use two hashmaps, one for keeping track of checkIn information and one for keeping track of journey data. When a user checks in, we store their check-in information (station and time) in the checkInInfo hashmap. When a user checks out, we retrieve their stored check-in information, calculate the duration of the journey, and store or update the journey data in the journeyData hashmap. To obtain the average time for a journey between two stations, we retrieve the aggregated journey data from the journeyData hashmap and calculate the average.

## A solution in Python

```python
class UndergroundSystem:

    def __init__(self):
        self.check_in_info = dict()
        self.journey_data = dict()

    def check_in(self, id: int, station_name: str, t: int) -> None:
        self.check_in_info[id] = (station_name, t)

    def check_out(self, id: int, station_name: str, t: int) -> None:
        start_station, start_time = self.check_in_info[id]
        route = (start_station, station_name)
        duration = t - start_time
        if route not in self.journey_data:
            self.journey_data[route] = (0, 0)
        prev_duration, count = self.journey_data[route]
        self.journey_data[route] = (prev_duration + duration, count + 1)

    def get_average_time(self, start_station: str, end_station: str) -> float:
        route = (start_station, end_station)
        duration, count = self.journey_data[route]
        return duration / count
```
We use two hashmaps, one for keeping track of checkIn information and one for keeping track of journey data. When a user checks in, we store their check-in information (station and time) in the checkInInfo hashmap. When a user checks out, we retrieve their stored check-in information, calculate the duration of the journey, and store or update the journey data in the journeyData hashmap. To obtain the average time for a journey between two stations, we retrieve the aggregated journey data from the journeyData hashmap and calculate the average.

## A solution in Javascript

```javascript
class UndergroundSystem {
    constructor() {
        this.checkInInfo = {};
        this.journeyData = {};
    }

    checkIn(id, stationName, t) {
        this.checkInInfo[id] = [stationName, t];
    }

    checkOut(id, stationName, t) {
        const [startStation, startTime] = this.checkInInfo[id];
        const route = startStation + "_" + stationName;
        const duration = t - startTime;
        if (!this.journeyData.hasOwnProperty(route)) {
            this.journeyData[route] = [0, 0];
        }
        this.journeyData[route][0] += duration;
        this.journeyData[route][1] += 1;
    }

    getAverageTime(startStation, endStation) {
        const route = startStation + "_" + endStation;
        const [duration, count] = this.journeyData[route];
        return duration / count;
    }
}
```
We use two hashmaps, one for keeping track of checkIn information and one for keeping track of journey data. When a user checks in, we store their check-in information (station and time) in the checkInInfo hashmap. When a user checks out, we retrieve their stored check-in information, calculate the duration of the journey, and store or update the journey data in the journeyData hashmap. To obtain the average time for a journey between two stations, we retrieve the aggregated journey data from the journeyData hashmap and calculate the average.


# Find All Good Strings

- slug: find-all-good-strings
- difficulty: Hard

Given the strings `s1` and `s2` of size `n` and the string `evil`, return _the number of **good** strings_.

A **good** string has size `n`, it is alphabetically greater than or equal to `s1`, it is alphabetically smaller than or equal to `s2`, and it does not contain the string `evil` as a substring. Since the answer can be a huge number, return this **modulo** `109 + 7`.

**Example 1:**

**Input:** n = 2, s1 =  "aa ", s2 =  "da ", evil =  "b "
**Output:** 51
**Explanation:** There are 25 good strings starting with 'a':  "aa ", "ac ", "ad ",..., "az ". Then there are 25 good strings starting with 'c':  "ca ", "cc ", "cd ",..., "cz " and finally there is one good string starting with 'd':  "da ".

**Example 2:**

**Input:** n = 8, s1 =  "leetcode ", s2 =  "leetgoes ", evil =  "leet "
**Output:** 0
**Explanation:** All strings greater than or equal to s1 and smaller than or equal to s2 start with the prefix  "leet ", therefore, there is not any good string.

**Example 3:**

**Input:** n = 2, s1 =  "gx ", s2 =  "gz ", evil =  "x "
**Output:** 2

**Constraints:**

*   `s1.length == n`
*   `s2.length == n`
*   `s1 <= s2`
*   `1 <= n <= 500`
*   `1 <= evil.length <= 50`
*   All strings consist of lowercase English letters.

## A solution in Java

```java
import java.util.*;

public List<List<String>> suggestedProducts(String[] products, String searchWord) {
    Arrays.sort(products);

    List<List<String>> result = new ArrayList<>();
    String currentPrefix = "";

    for (char letter : searchWord.toCharArray()) {
        currentPrefix += letter;

        int index = Arrays.binarySearch(products, currentPrefix);
        if (index < 0) {
            index = -index - 1;
        }

        List<String> suggestions = new ArrayList<>();
        for (int i = 0; i < 3 && index < products.length && products[index].startsWith(currentPrefix); i++) {
            suggestions.add(products[index]);
            index++;
        }

        result.add(suggestions);
    }

    return result;
}
```
The algorithm for solving this problem consists of the following steps:
1. Sort the `products` lexicographically.
2. Initialize an empty result list and an empty `currentPrefix` string.
3. Iterate through each letter of `searchWord`, appending the letter to `currentPrefix`.
4. Use a binary search to find the starting position of the suggested products with the common prefix `currentPrefix`.
5. Initialize an empty suggestions list.
6. Iterate from the starting position and add at most 3 product names to the suggestions list that have the common prefix with `currentPrefix`. Stop adding product names either when there are no more products with the common prefix or 3 suggestions are added.
7. Add the suggestions list to the result list.
8. Return the result list after iterating through all the characters of `searchWord`.

## A solution in C++

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

std::vector<std::vector<std::string>> suggestedProducts(std::vector<std::string>& products, std::string searchWord) {
    std::sort(products.begin(), products.end());

    std::vector<std::vector<std::string>> result;
    std::string currentPrefix;

    for (char letter : searchWord) {
        currentPrefix += letter;

        auto it = std::lower_bound(products.begin(), products.end(), currentPrefix);
        std::vector<std::string> suggestions;

        for (int i = 0; i < 3 && it != products.end() && it->substr(0, currentPrefix.size()) == currentPrefix; ++i) {
            suggestions.push_back(*it);
            ++it;
        }

        result.push_back(suggestions);
    }

    return result;
}
```
The algorithm for solving this problem consists of the following steps:
1. Sort the `products` lexicographically.
2. Initialize an empty result list and an empty `currentPrefix` string.
3. Iterate through each letter of `searchWord`, appending the letter to `currentPrefix`.
4. Use a binary search to find the starting position of the suggested products with the common prefix `currentPrefix`.
5. Initialize an empty suggestions list.
6. Iterate from the starting position and add at most 3 product names to the suggestions list that have the common prefix with `currentPrefix`. Stop adding product names either when there are no more products with the common prefix or 3 suggestions are added.
7. Add the suggestions list to the result list.
8. Return the result list after iterating through all the characters of `searchWord`.

## A solution in Python

```python
from bisect import bisect_left

def suggestedProducts(products, searchWord):
    products.sort()
    result = []
    current_prefix = ""

    for letter in searchWord:
        current_prefix += letter
        index = bisect_left(products, current_prefix)
        suggestions = []

        for i in range(3):
            if index < len(products) and products[index].startswith(current_prefix):
                suggestions.append(products[index])
                index += 1
            else:
                break

        result.append(suggestions)

    return result
```
The algorithm for solving this problem consists of the following steps:
1. Sort the `products` lexicographically.
2. Initialize an empty result list and an empty `currentPrefix` string.
3. Iterate through each letter of `searchWord`, appending the letter to `currentPrefix`.
4. Use a binary search to find the starting position of the suggested products with the common prefix `currentPrefix`.
5. Initialize an empty suggestions list.
6. Iterate from the starting position and add at most 3 product names to the suggestions list that have the common prefix with `currentPrefix`. Stop adding product names either when there are no more products with the common prefix or 3 suggestions are added.
7. Add the suggestions list to the result list.
8. Return the result list after iterating through all the characters of `searchWord`.

## A solution in Javascript

```javascript
function suggestedProducts(products, searchWord) {
    products.sort();

    let result = [];
    let currentPrefix = "";

    for (let letter of searchWord) {
        currentPrefix += letter;

        let index = products.findIndex(product => product.startsWith(currentPrefix));

        let suggestions = [];
        for (let i = 0; i < 3 && index < products.length && products[index].startsWith(currentPrefix); i++) {
            suggestions.push(products[index]);
            index++;
        }

        result.push(suggestions);
    }

    return result;
}
```
The algorithm for solving this problem consists of the following steps:
1. Sort the `products` lexicographically.
2. Initialize an empty result list and an empty `currentPrefix` string.
3. Iterate through each letter of `searchWord`, appending the letter to `currentPrefix`.
4. Use a binary search to find the starting position of the suggested products with the common prefix `currentPrefix`.
5. Initialize an empty suggestions list.
6. Iterate from the starting position and add at most 3 product names to the suggestions list that have the common prefix with `currentPrefix`. Stop adding product names either when there are no more products with the common prefix or 3 suggestions are added.
7. Add the suggestions list to the result list.
8. Return the result list after iterating through all the characters of `searchWord`.


# Count Largest Group

- slug: count-largest-group
- difficulty: Easy

You are given an integer `n`.

Each number from `1` to `n` is grouped according to the sum of its digits.

Return _the number of groups that have the largest size_.

**Example 1:**

**Input:** n = 13
**Output:** 4
**Explanation:** There are 9 groups in total, they are grouped according sum of its digits of numbers from 1 to 13:
\[1,10\], \[2,11\], \[3,12\], \[4,13\], \[5\], \[6\], \[7\], \[8\], \[9\].
There are 4 groups with largest size.

**Example 2:**

**Input:** n = 2
**Output:** 2
**Explanation:** There are 2 groups \[1\], \[2\] of size 1.

**Constraints:**

*   `1 <= n <= 104`

## A solution in Java

```java
public int countLargestGroup(int n) {
    int[] groups = new int[37];
    int largest_group_size = 0;
    int count_largest_groups = 0;

    for (int i = 1; i <= n; i++) {
        int sum = 0, num = i;
        while (num > 0) {
            sum += num % 10;
            num /= 10;
        }
        groups[sum]++;
        if (groups[sum] > largest_group_size) {
            largest_group_size = groups[sum];
            count_largest_groups = 1;
        } else if (groups[sum] == largest_group_size) {
            count_largest_groups++;
        }
    }
    return count_largest_groups;
}
```
The algorithm iterates through every number from 1 to n. For each number, calculate the sum of its digits. Increment the count for the group corresponding to that sum of digits. Update the largest group size if the current group becomes larger than the previous largest group. If the current group size is equal to the largest group size, increment the count of largest groups.

The algorithm has a time complexity of O(n), as it processes each number from 1 to n once.

## A solution in C++

```cpp
int countLargestGroup(int n) {
    std::vector<int> groups(37, 0);
    int largest_group_size = 0;
    int count_largest_groups = 0;

    for (int i = 1; i <= n; i++) {
        int sum = 0, num = i;
        while (num) {
            sum += num % 10;
            num /= 10;
        }
        groups[sum]++;
        if (groups[sum] > largest_group_size) {
            largest_group_size = groups[sum];
            count_largest_groups = 1;
        } else if (groups[sum] == largest_group_size) {
            count_largest_groups++;
        }
    }
    return count_largest_groups;
}
```
The algorithm iterates through every number from 1 to n. For each number, calculate the sum of its digits. Increment the count for the group corresponding to that sum of digits. Update the largest group size if the current group becomes larger than the previous largest group. If the current group size is equal to the largest group size, increment the count of largest groups.

The algorithm has a time complexity of O(n), as it processes each number from 1 to n once.

## A solution in Python

```python
def countLargestGroup(n: int) -> int:
    groups = [0] * 37
    largest_group_size = 0
    count_largest_groups = 0

    for i in range(1, n + 1):
        sum_of_digits = sum(map(int, str(i)))
        groups[sum_of_digits] += 1
        if groups[sum_of_digits] > largest_group_size:
            largest_group_size = groups[sum_of_digits]
            count_largest_groups = 1
        elif groups[sum_of_digits] == largest_group_size:
            count_largest_groups += 1

    return count_largest_groups
```
The algorithm iterates through every number from 1 to n. For each number, calculate the sum of its digits. Increment the count for the group corresponding to that sum of digits. Update the largest group size if the current group becomes larger than the previous largest group. If the current group size is equal to the largest group size, increment the count of largest groups.

The algorithm has a time complexity of O(n), as it processes each number from 1 to n once.

## A solution in Javascript

```javascript
function countLargestGroup(n) {
    const groups = new Array(37).fill(0);
    let largest_group_size = 0;
    let count_largest_groups = 0;

    for (let i = 1; i <= n; i++) {
        const sum = i.toString().split('').reduce((a, b) => a + parseInt(b), 0);
        groups[sum]++;
        if (groups[sum] > largest_group_size) {
            largest_group_size = groups[sum];
            count_largest_groups = 1;
        } else if (groups[sum] === largest_group_size) {
            count_largest_groups++;
        }
    }
    return count_largest_groups;
};
```
The algorithm iterates through every number from 1 to n. For each number, calculate the sum of its digits. Increment the count for the group corresponding to that sum of digits. Update the largest group size if the current group becomes larger than the previous largest group. If the current group size is equal to the largest group size, increment the count of largest groups.

The algorithm has a time complexity of O(n), as it processes each number from 1 to n once.


# Construct K Palindrome Strings

- slug: construct-k-palindrome-strings
- difficulty: Medium

Given a string `s` and an integer `k`, return `true` _if you can use all the characters in_ `s` _to construct_ `k` _palindrome strings or_ `false` _otherwise_.

**Example 1:**

**Input:** s =  "annabelle ", k = 2
**Output:** true
**Explanation:** You can construct two palindromes using all characters in s.
Some possible constructions  "anna " +  "elble ",  "anbna " +  "elle ",  "anellena " +  "b "

**Example 2:**

**Input:** s =  "leetcode ", k = 3
**Output:** false
**Explanation:** It is impossible to construct 3 palindromes using all the characters of s.

**Example 3:**

**Input:** s =  "true ", k = 4
**Output:** true
**Explanation:** The only possible solution is to put each character in a separate string.

**Constraints:**

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

## A solution in Java

```java
import java.util.*;

public String tictactoe(int[][] moves) {
    int[][] grid = new int[3][3];
    int player = 1;
    for (int[] move : moves) {
        grid[move[0]][move[1]] = player;
        if ((grid[0][move[1]] == player && grid[1][move[1]] == player && grid[2][move[1]] == player) ||
            (grid[move[0]][0] == player && grid[move[0]][1] == player && grid[move[0]][2] == player) ||
            (move[0] == move[1] && grid[0][0] == player && grid[1][1] == player && grid[2][2] == player) ||
            (move[0] + move[1] == 2 && grid[0][2] == player && grid[1][1] == player && grid[2][0] == player)) {
            return player == 1 ? "A" : "B";
        }
        player = 3 - player;
    }
    return moves.length == 9 ? "Draw" : "Pending";
}
```
1. Initialize an empty `grid` and set the first player to be `1` (representing A) to track players.
2. Iterate through each move in `moves`.
3. In each iteration, apply the corresponding player's move on the grid.
4. Check if the current move created 3 in a row, 3 in a column, or 3 on either diagonal. If so, the current player wins and return "A" or "B" corresponding to the player.
5. If no winner is found after processing all moves, return "Draw" if there are 9 moves, else return "Pending".

## A solution in C++

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

std::string tictactoe(std::vector<std::vector<int>>& moves) {
    int grid[3][3] = {0};
    int player = 1;
    for (const auto& move : moves) {
        grid[move[0]][move[1]] = player;
        if ((grid[0][move[1]] == player && grid[1][move[1]] == player && grid[2][move[1]] == player) ||
            (grid[move[0]][0] == player && grid[move[0]][1] == player && grid[move[0]][2] == player) ||
            (move[0] == move[1] && grid[0][0] == player && grid[1][1] == player && grid[2][2] == player) ||
            (move[0] + move[1] == 2 && grid[0][2] == player && grid[1][1] == player && grid[2][0] == player)) {
            return player == 1 ? "A" : "B";
        }
        player = 3 - player;
    }
    return moves.size() == 9 ? "Draw" : "Pending";
}
```
1. Initialize an empty `grid` and set the first player to be `1` (representing A) to track players.
2. Iterate through each move in `moves`.
3. In each iteration, apply the corresponding player's move on the grid.
4. Check if the current move created 3 in a row, 3 in a column, or 3 on either diagonal. If so, the current player wins and return "A" or "B" corresponding to the player.
5. If no winner is found after processing all moves, return "Draw" if there are 9 moves, else return "Pending".

## A solution in Python

```python
def tictactoe(moves):
    grid = [[0] * 3 for _ in range(3)]
    player = 1
    for move in moves:
        r, c = move
        grid[r][c] = player
        if (all(grid[i][c] == player for i in range(3)) or
            all(grid[r][i] == player for i in range(3)) or
            (r == c and all(grid[i][i] == player for i in range(3))) or
            (r + c == 2 and all(grid[i][2 - i] == player for i in range(3)))):
            return 'A' if player == 1 else 'B'
        player = 3 - player

    return 'Draw' if len(moves) == 9 else 'Pending'
```
1. Initialize an empty `grid` and set the first player to be `1` (representing A) to track players.
2. Iterate through each move in `moves`.
3. In each iteration, apply the corresponding player's move on the grid.
4. Check if the current move created 3 in a row, 3 in a column, or 3 on either diagonal. If so, the current player wins and return "A" or "B" corresponding to the player.
5. If no winner is found after processing all moves, return "Draw" if there are 9 moves, else return "Pending".

## A solution in Javascript

```javascript
function tictactoe(moves) {
    const grid = Array.from({ length: 3 }, () => new Array(3).fill(0));
    let player = 1;
    for (const move of moves) {
        const [row, col] = move;
        grid[row][col] = player;
        if ((Array(3).fill().every((_, i) => grid[i][col] === player)) ||
            (Array(3).fill().every((_, i) => grid[row][i] === player)) ||
            (row === col && Array(3).fill().every((_, i) => grid[i][i] === player)) ||
            (row + col === 2 && Array(3).fill().every((_, i) => grid[i][2 - i] === player))) {
            return player === 1 ? "A" : "B";
        }
        player = 3 - player;
    }
    return moves.length === 9 ? "Draw" : "Pending";
}
```
1. Initialize an empty `grid` and set the first player to be `1` (representing A) to track players.
2. Iterate through each move in `moves`.
3. In each iteration, apply the corresponding player's move on the grid.
4. Check if the current move created 3 in a row, 3 in a column, or 3 on either diagonal. If so, the current player wins and return "A" or "B" corresponding to the player.
5. If no winner is found after processing all moves, return "Draw" if there are 9 moves, else return "Pending".


# Circle and Rectangle Overlapping

- slug: circle-and-rectangle-overlapping
- difficulty: Medium

You are given a circle represented as `(radius, xCenter, yCenter)` and an axis-aligned rectangle represented as `(x1, y1, x2, y2)`, where `(x1, y1)` are the coordinates of the bottom-left corner, and `(x2, y2)` are the coordinates of the top-right corner of the rectangle.

Return `true` _if the circle and rectangle are overlapped otherwise return_ `false`. In other words, check if there is **any** point `(xi, yi)` that belongs to the circle and the rectangle at the same time.

**Example 1:**

**Input:** radius = 1, xCenter = 0, yCenter = 0, x1 = 1, y1 = -1, x2 = 3, y2 = 1
**Output:** true
**Explanation:** Circle and rectangle share the point (1,0).

**Example 2:**

**Input:** radius = 1, xCenter = 1, yCenter = 1, x1 = 1, y1 = -3, x2 = 2, y2 = -1
**Output:** false

**Example 3:**

**Input:** radius = 1, xCenter = 0, yCenter = 0, x1 = -1, y1 = 0, x2 = 0, y2 = 1
**Output:** true

**Constraints:**

*   `1 <= radius <= 2000`
*   `-104 <= xCenter, yCenter <= 104`
*   `-104 <= x1 < x2 <= 104`
*   `-104 <= y1 < y2 <= 104`

## A solution in Java

```java
boolean checkOverlap(int radius, int xCenter, int yCenter, int x1, int y1, int x2, int y2) {
    int xClosest = Math.max(x1, Math.min(xCenter, x2));
    int yClosest = Math.max(y1, Math.min(yCenter, y2));
    return (xCenter - xClosest) * (xCenter - xClosest) + (yCenter - yClosest) * (yCenter - yClosest) <= radius * radius;
}
```
The algorithm finds the closest point from the center of the circle to the rectangle. First, it determines the x-coordinate and y-coordinate of this point `xClosest` and `yClosest`, by finding the minimum and maximum values of x and y coordinates between the center of the circle and the bounds of the rectangle, respectively.

Then, check if the distance squared between the circle's center `(xCenter, yCenter)` and the closest point `(xClosest, yClosest)` is less than or equal to the square of the radius of the circle. If it is, then the circle and the rectangle are overlapping, otherwise they are not.

## A solution in C++

```cpp
bool checkOverlap(int radius, int xCenter, int yCenter, int x1, int y1, int x2, int y2) {
    int xClosest = std::max(x1, std::min(xCenter, x2));
    int yClosest = std::max(y1, std::min(yCenter, y2));
    return (xCenter - xClosest) * (xCenter - xClosest) + (yCenter - yClosest) * (yCenter - yClosest) <= radius * radius;
}
```
The algorithm finds the closest point from the center of the circle to the rectangle. First, it determines the x-coordinate and y-coordinate of this point `xClosest` and `yClosest`, by finding the minimum and maximum values of x and y coordinates between the center of the circle and the bounds of the rectangle, respectively.

Then, check if the distance squared between the circle's center `(xCenter, yCenter)` and the closest point `(xClosest, yClosest)` is less than or equal to the square of the radius of the circle. If it is, then the circle and the rectangle are overlapping, otherwise they are not.

## A solution in Python

```python
def checkOverlap(radius, xCenter, yCenter, x1, y1, x2, y2):
    xClosest = max(x1, min(xCenter, x2))
    yClosest = max(y1, min(yCenter, y2))
    return (xCenter - xClosest) ** 2 + (yCenter - yClosest) ** 2 <= radius ** 2
```
The algorithm finds the closest point from the center of the circle to the rectangle. First, it determines the x-coordinate and y-coordinate of this point `xClosest` and `yClosest`, by finding the minimum and maximum values of x and y coordinates between the center of the circle and the bounds of the rectangle, respectively.

Then, check if the distance squared between the circle's center `(xCenter, yCenter)` and the closest point `(xClosest, yClosest)` is less than or equal to the square of the radius of the circle. If it is, then the circle and the rectangle are overlapping, otherwise they are not.

## A solution in Javascript

```javascript
function checkOverlap(radius, xCenter, yCenter, x1, y1, x2, y2) {
    const xClosest = Math.max(x1, Math.min(xCenter, x2));
    const yClosest = Math.max(y1, Math.min(yCenter, y2));
    return (xCenter - xClosest) * (xCenter - xClosest) + (yCenter - yClosest) * (yCenter - yClosest) <= radius * radius;
}
```
The algorithm finds the closest point from the center of the circle to the rectangle. First, it determines the x-coordinate and y-coordinate of this point `xClosest` and `yClosest`, by finding the minimum and maximum values of x and y coordinates between the center of the circle and the bounds of the rectangle, respectively.

Then, check if the distance squared between the circle's center `(xCenter, yCenter)` and the closest point `(xClosest, yClosest)` is less than or equal to the square of the radius of the circle. If it is, then the circle and the rectangle are overlapping, otherwise they are not.


# Reducing Dishes

- slug: reducing-dishes
- difficulty: Hard

A chef has collected data on the `satisfaction` level of his `n` dishes. Chef can cook any dish in 1 unit of time.

**Like-time coefficient** of a dish is defined as the time taken to cook that dish including previous dishes multiplied by its satisfaction level i.e. `time[i] * satisfaction[i]`.

Return _the maximum sum of **like-time coefficient** that the chef can obtain after dishes preparation_.

Dishes can be prepared in **any** order and the chef can discard some dishes to get this maximum value.

**Example 1:**

**Input:** satisfaction = \[-1,-8,0,5,-9\]
**Output:** 14
**Explanation:** After Removing the second and last dish, the maximum total **like-time coefficient** will be equal to (-1\*1 + 0\*2 + 5\*3 = 14).
Each dish is prepared in one unit of time.

**Example 2:**

**Input:** satisfaction = \[4,3,2\]
**Output:** 20
**Explanation:** Dishes can be prepared in any order, (2\*1 + 3\*2 + 4\*3 = 20)

**Example 3:**

**Input:** satisfaction = \[-1,-4,-5\]
**Output:** 0
**Explanation:** People do not like the dishes. No dish is prepared.

**Constraints:**

*   `n == satisfaction.length`
*   `1 <= n <= 500`
*   `-1000 <= satisfaction[i] <= 1000`

## A solution in Java

```java
public int countSquares(int[][] matrix) {
    int m = matrix.length, n = matrix[0].length, ans = 0;
    int[][] dp = new int[m][n];
    for(int i = 0; i < m; i++) {
        for(int j = 0; j < n; j++) {
            if(i == 0 || j == 0) dp[i][j] = matrix[i][j];
            else if(matrix[i][j] == 1) dp[i][j] = Math.min(dp[i-1][j-1], Math.min(dp[i-1][j], dp[i][j-1])) + 1;
            ans += dp[i][j];
        }
    }
    return ans;
}
```
The algorithm uses a dynamic programming approach. For each cell of the input matrix, we create a `dp` matrix that will store the size of the square that ends at the current cell `[i, j]`. If the current cell contains 1, we need to check the values of the neighbors, i.e., cells `[i-1, j-1]`, `[i-1, j]`, and `[i, j-1]`. To form a square of size `k`, all three neighboring cells must have squares of size `k-1`. Thus, we set the current cell in `dp` to the minimum of the neighboring cells plus one (`dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1`).

For each cell, we then add its value in the `dp` matrix to the result (`ans += dp[i][j]`). Finally, we return the total number of squares found.

## A solution in C++

```cpp
int countSquares(vector<vector<int>>& matrix) {
    int m = matrix.size(), n = matrix[0].size(), ans = 0;
    vector<vector<int>> dp(m, vector<int>(n, 0));
    for(int i = 0; i < m; i++) {
        for(int j = 0; j < n; j++) {
            if(i == 0 || j == 0) dp[i][j] = matrix[i][j];
            else if(matrix[i][j]) dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i][j-1])) + 1;
            ans += dp[i][j];
        }
    }
    return ans;
}
```
The algorithm uses a dynamic programming approach. For each cell of the input matrix, we create a `dp` matrix that will store the size of the square that ends at the current cell `[i, j]`. If the current cell contains 1, we need to check the values of the neighbors, i.e., cells `[i-1, j-1]`, `[i-1, j]`, and `[i, j-1]`. To form a square of size `k`, all three neighboring cells must have squares of size `k-1`. Thus, we set the current cell in `dp` to the minimum of the neighboring cells plus one (`dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1`).

For each cell, we then add its value in the `dp` matrix to the result (`ans += dp[i][j]`). Finally, we return the total number of squares found.

## A solution in Python

```python
def countSquares(matrix: List[List[int]]) -> int:
    m, n, ans = len(matrix), len(matrix[0]), 0
    dp = [[0] * n for _ in range(m)]
    for i in range(m):
        for j in range(n):
            if i == 0 or j == 0:
                dp[i][j] = matrix[i][j]
            elif matrix[i][j]:
                dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1
            ans += dp[i][j]
    return ans
```
The algorithm uses a dynamic programming approach. For each cell of the input matrix, we create a `dp` matrix that will store the size of the square that ends at the current cell `[i, j]`. If the current cell contains 1, we need to check the values of the neighbors, i.e., cells `[i-1, j-1]`, `[i-1, j]`, and `[i, j-1]`. To form a square of size `k`, all three neighboring cells must have squares of size `k-1`. Thus, we set the current cell in `dp` to the minimum of the neighboring cells plus one (`dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1`).

For each cell, we then add its value in the `dp` matrix to the result (`ans += dp[i][j]`). Finally, we return the total number of squares found.

## A solution in Javascript

```javascript
function countSquares(matrix) {
    const m = matrix.length, n = matrix[0].length;
    let ans = 0, dp = Array.from({length: m}, () => Array(n));
    for(let i = 0; i < m; i++) {
        for(let j = 0; j < n; j++) {
            if(i === 0 || j === 0) dp[i][j] = matrix[i][j];
            else if(matrix[i][j]) dp[i][j] = Math.min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1;
            ans += dp[i][j];
        }
    }
    return ans;
}
```
The algorithm uses a dynamic programming approach. For each cell of the input matrix, we create a `dp` matrix that will store the size of the square that ends at the current cell `[i, j]`. If the current cell contains 1, we need to check the values of the neighbors, i.e., cells `[i-1, j-1]`, `[i-1, j]`, and `[i, j-1]`. To form a square of size `k`, all three neighboring cells must have squares of size `k-1`. Thus, we set the current cell in `dp` to the minimum of the neighboring cells plus one (`dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1`).

For each cell, we then add its value in the `dp` matrix to the result (`ans += dp[i][j]`). Finally, we return the total number of squares found.


# Minimum Subsequence in Non-Increasing Order

- slug: minimum-subsequence-in-non-increasing-order
- difficulty: Easy

Given the array `nums`, obtain a subsequence of the array whose sum of elements is **strictly greater** than the sum of the non included elements in such subsequence.

If there are multiple solutions, return the subsequence with **minimum size** and if there still exist multiple solutions, return the subsequence with the **maximum total sum** of all its elements. A subsequence of an array can be obtained by erasing some (possibly zero) elements from the array.

Note that the solution with the given constraints is guaranteed to be **unique**. Also return the answer sorted in **non-increasing** order.

**Example 1:**

**Input:** nums = \[4,3,10,9,8\]
**Output:** \[10,9\]
**Explanation:** The subsequences \[10,9\] and \[10,8\] are minimal such that the sum of their elements is strictly greater than the sum of elements not included. However, the subsequence \[10,9\] has the maximum total sum of its elements.

**Example 2:**

**Input:** nums = \[4,4,7,6,7\]
**Output:** \[7,7,6\]
**Explanation:** The subsequence \[7,7\] has the sum of its elements equal to 14 which is not strictly greater than the sum of elements not included (14 = 4 + 4 + 6). Therefore, the subsequence \[7,6,7\] is the minimal satisfying the conditions. Note the subsequence has to be returned in non-decreasing order.

**Constraints:**

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

## A solution in Java

```java
public int minChangesToDivideString(String s, int k) {
    int n = s.length();
    if (n % k != 0) return -1;
    int chunkCount = n / k;
    int res = 0;
    for (int i = 0; i < k; ++i) {
        int[] counts = new int[26];
        for (int j = i; j < n; j += k) {
            ++counts[s.charAt(j) - 'a'];
        }
        int maxCount = Arrays.stream(counts).max().getAsInt();
        res += chunkCount - maxCount;
    }
    return res;
}
```
The algorithm works as follows:

1. Check if the length of the string s is divisible by k. If not, return -1 as it's impossible to divide the string.
2. Calculate the number of chunks the string will be divided into. This value will be (length of string / k).
3. Initialize a variable `res` to 0. This will store the total count of characters needed to be changed.
4. Loop through 0 to k as `i`:
   a. Create a count array `counts` with 26 elements for each character in the lowercase English alphabet.
   b. Loop through the characters of the string starting from `i` and incrementing by `k`.
   c. Increment the count associated with each lowercase character in the `counts` array.
   d. Find the maximum count in the `counts` array.
   e. Add the difference of chunkCount and maxCount to the `res` variable.
5. Return the `res` variable, which contains the minimal number of characters that need to be changed.

## A solution in C++

```cpp
int min_changes_to_divide_string(const std::string& s, int k) {
    int n = s.length();
    if (n % k != 0) return -1;
    int chunk_count = n / k;
    int res = 0;
    for (int i = 0; i < k; ++i) {
        int counts[26] = {0};
        for (int j = i; j < n; j += k) {
            ++counts[s[j] - 'a'];
        }
        int max_count = *std::max_element(counts, counts + 26);
        res += chunk_count - max_count;
    }
    return res;
}
```
The algorithm works as follows:

1. Check if the length of the string s is divisible by k. If not, return -1 as it's impossible to divide the string.
2. Calculate the number of chunks the string will be divided into. This value will be (length of string / k).
3. Initialize a variable `res` to 0. This will store the total count of characters needed to be changed.
4. Loop through 0 to k as `i`:
   a. Create a count array `counts` with 26 elements for each character in the lowercase English alphabet.
   b. Loop through the characters of the string starting from `i` and incrementing by `k`.
   c. Increment the count associated with each lowercase character in the `counts` array.
   d. Find the maximum count in the `counts` array.
   e. Add the difference of chunkCount and maxCount to the `res` variable.
5. Return the `res` variable, which contains the minimal number of characters that need to be changed.

## A solution in Python

```python
def min_changes_to_divide_string(s, k):
    n = len(s)
    if n % k != 0:
        return -1
    chunk_count = n // k
    res = 0
    for i in range(k):
        counts = [0] * 26
        for j in range(i, n, k):
            counts[ord(s[j]) - ord('a')] += 1
        max_count = max(counts)
        res += chunk_count - max_count
    return res
```
The algorithm works as follows:

1. Check if the length of the string s is divisible by k. If not, return -1 as it's impossible to divide the string.
2. Calculate the number of chunks the string will be divided into. This value will be (length of string / k).
3. Initialize a variable `res` to 0. This will store the total count of characters needed to be changed.
4. Loop through 0 to k as `i`:
   a. Create a count array `counts` with 26 elements for each character in the lowercase English alphabet.
   b. Loop through the characters of the string starting from `i` and incrementing by `k`.
   c. Increment the count associated with each lowercase character in the `counts` array.
   d. Find the maximum count in the `counts` array.
   e. Add the difference of chunkCount and maxCount to the `res` variable.
5. Return the `res` variable, which contains the minimal number of characters that need to be changed.

## A solution in Javascript

```javascript
function minChangesToDivideString(s, k) {
    let n = s.length;
    if (n % k !== 0) {
        return -1;
    }
    let chunkCount = n / k;
    let res = 0;
    for (let i = 0; i < k; ++i) {
        let counts = new Array(26).fill(0);
        for (let j = i; j < n; j += k) {
            ++counts[s.charCodeAt(j) - 'a'.charCodeAt(0)];
        }
        let maxCount = Math.max(...counts);
        res += chunkCount - maxCount;
    }
    return res;
}
```
The algorithm works as follows:

1. Check if the length of the string s is divisible by k. If not, return -1 as it's impossible to divide the string.
2. Calculate the number of chunks the string will be divided into. This value will be (length of string / k).
3. Initialize a variable `res` to 0. This will store the total count of characters needed to be changed.
4. Loop through 0 to k as `i`:
   a. Create a count array `counts` with 26 elements for each character in the lowercase English alphabet.
   b. Loop through the characters of the string starting from `i` and incrementing by `k`.
   c. Increment the count associated with each lowercase character in the `counts` array.
   d. Find the maximum count in the `counts` array.
   e. Add the difference of chunkCount and maxCount to the `res` variable.
5. Return the `res` variable, which contains the minimal number of characters that need to be changed.


# Number of Steps to Reduce a Number in Binary Representation to One

- slug: number-of-steps-to-reduce-a-number-in-binary-representation-to-one
- difficulty: Medium

Given the binary representation of an integer as a string `s`, return _the number of steps to reduce it to_ `1` _under the following rules_:

*   If the current number is even, you have to divide it by `2`.

*   If the current number is odd, you have to add `1` to it.

It is guaranteed that you can always reach one for all test cases.

**Example 1:**

**Input:** s =  "1101 "
**Output:** 6
**Explanation:**  "1101 " corressponds to number 13 in their decimal representation.
Step 1) 13 is odd, add 1 and obtain 14.
Step 2) 14 is even, divide by 2 and obtain 7.
Step 3) 7 is odd, add 1 and obtain 8.
Step 4) 8 is even, divide by 2 and obtain 4.
Step 5) 4 is even, divide by 2 and obtain 2.
Step 6) 2 is even, divide by 2 and obtain 1.

**Example 2:**

**Input:** s =  "10 "
**Output:** 1
**Explanation:**  "10 " corressponds to number 2 in their decimal representation.
Step 1) 2 is even, divide by 2 and obtain 1.

**Example 3:**

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

**Constraints:**

*   `1 <= s.length <= 500`
*   `s` consists of characters '0' or '1'
*   `s[0] == '1'`

## A solution in Java

```java
public int numSteps(String s) {
    int steps = 0, carry = 0;
    for (int i = s.length() - 1; i > 0; --i) {
        int bit = s.charAt(i) - '0';
        if (bit == 1 && carry == 1) {
            carry = 1;
            steps += 2;
        } else if (bit == 1 || carry == 1) {
            carry ^= 1;
            steps += 2;
        } else {
            steps++;
        }
    }

    return steps + carry;
}
```
We can start from the least significant bit (LSB) of the binary string `s` and work backwards. Initialize `steps` and `carry` counters to 0. We then iterate through the string from right to left, skipping the first character (which is always '1').

For each character, we check whether the bit is 1, carry is 1, or both are 0:
- If the bit is 1 and carry is 1, we will set the carry to 1 and increment steps by 2 (one step for adding 1 and another step for dividing by 2).
- If the bit is 1 or the carry is 1, we will XOR the carry with 1 (i.e., flip the carry) and increment steps by 2.
- If both are 0, we increment steps by 1, as we only need to divide by 2.

After iterating through the entire string, we add the carry to the steps counter and return the steps. This process ensures we account for any remaining carry, as illustrated in the given examples.

## A solution in C++

```cpp
int num_steps(const std::string& s) {
    int steps = 0, carry = 0;
    for (int i = s.length() - 1; i > 0; --i) {
        int bit = s[i] - '0';
        if (bit && carry) {
            carry = 1;
            steps += 2;
        } else if (bit || carry) {
            carry ^= 1;
            steps += 2;
        } else {
            steps++;
        }
    }

    return steps + carry;
}
```
We can start from the least significant bit (LSB) of the binary string `s` and work backwards. Initialize `steps` and `carry` counters to 0. We then iterate through the string from right to left, skipping the first character (which is always '1').

For each character, we check whether the bit is 1, carry is 1, or both are 0:
- If the bit is 1 and carry is 1, we will set the carry to 1 and increment steps by 2 (one step for adding 1 and another step for dividing by 2).
- If the bit is 1 or the carry is 1, we will XOR the carry with 1 (i.e., flip the carry) and increment steps by 2.
- If both are 0, we increment steps by 1, as we only need to divide by 2.

After iterating through the entire string, we add the carry to the steps counter and return the steps. This process ensures we account for any remaining carry, as illustrated in the given examples.

## A solution in Python

```python
def num_steps(s: str) -> int:
    steps = 0
    carry = 0

    for c in reversed(s[1:]):
        bit = int(c)
        if bit and carry:
            carry = 1
            steps += 2
        elif bit or carry:
            carry ^= 1
            steps += 2
        else:
            steps += 1

    return steps + carry
```
We can start from the least significant bit (LSB) of the binary string `s` and work backwards. Initialize `steps` and `carry` counters to 0. We then iterate through the string from right to left, skipping the first character (which is always '1').

For each character, we check whether the bit is 1, carry is 1, or both are 0:
- If the bit is 1 and carry is 1, we will set the carry to 1 and increment steps by 2 (one step for adding 1 and another step for dividing by 2).
- If the bit is 1 or the carry is 1, we will XOR the carry with 1 (i.e., flip the carry) and increment steps by 2.
- If both are 0, we increment steps by 1, as we only need to divide by 2.

After iterating through the entire string, we add the carry to the steps counter and return the steps. This process ensures we account for any remaining carry, as illustrated in the given examples.

## A solution in Javascript

```javascript
function numSteps(s) {
    let steps = 0, carry = 0;
    for (let i = s.length - 1; i > 0; --i) {
        const bit = parseInt(s[i]);
        if (bit && carry) {
            carry = 1;
            steps += 2;
        } else if (bit || carry) {
            carry ^= 1;
            steps += 2;
        } else {
            steps++;
        }
    }

    return steps + carry;
}
```
We can start from the least significant bit (LSB) of the binary string `s` and work backwards. Initialize `steps` and `carry` counters to 0. We then iterate through the string from right to left, skipping the first character (which is always '1').

For each character, we check whether the bit is 1, carry is 1, or both are 0:
- If the bit is 1 and carry is 1, we will set the carry to 1 and increment steps by 2 (one step for adding 1 and another step for dividing by 2).
- If the bit is 1 or the carry is 1, we will XOR the carry with 1 (i.e., flip the carry) and increment steps by 2.
- If both are 0, we increment steps by 1, as we only need to divide by 2.

After iterating through the entire string, we add the carry to the steps counter and return the steps. This process ensures we account for any remaining carry, as illustrated in the given examples.


# Longest Happy String

- slug: longest-happy-string
- difficulty: Medium

A string `s` is called **happy** if it satisfies the following conditions:

*   `s` only contains the letters `'a'`, `'b'`, and `'c'`.
*   `s` does not contain any of `"aaa "`, `"bbb "`, or `"ccc "` as a substring.
*   `s` contains **at most** `a` occurrences of the letter `'a'`.
*   `s` contains **at most** `b` occurrences of the letter `'b'`.
*   `s` contains **at most** `c` occurrences of the letter `'c'`.

Given three integers `a`, `b`, and `c`, return _the **longest possible happy** string_. If there are multiple longest happy strings, return _any of them_. If there is no such string, return _the empty string_ `" "`.

A **substring** is a contiguous sequence of characters within a string.

**Example 1:**

**Input:** a = 1, b = 1, c = 7
**Output:**  "ccaccbcc "
**Explanation:**  "ccbccacc " would also be a correct answer.

**Example 2:**

**Input:** a = 7, b = 1, c = 0
**Output:**  "aabaa "
**Explanation:** It is the only correct answer in this case.

**Constraints:**

*   `0 <= a, b, c <= 100`
*   `a + b + c > 0`

## A solution in Java

```java
import java.util.*;

class Solution {
    public String longestDiverseString(int a, int b, int c) {
        StringBuilder result = new StringBuilder();
        PriorityQueue<int[]> pq = new PriorityQueue<>((a1, a2) -> a2[0] - a1[0]);
        if (a != 0) pq.offer(new int[]{a, 'a'});
        if (b != 0) pq.offer(new int[]{b, 'b'});
        if (c != 0) pq.offer(new int[]{c, 'c'});

        while (!pq.isEmpty()) {
            int[] first = pq.poll();
            if (result.length() != 0 && result.charAt(result.length()-1) == first[1]) {
                if (pq.isEmpty()) break;
                int[] second = pq.poll();
                result.append((char)second[1]);
                second[0]--;
                if (second[0] != 0) pq.offer(second);
                pq.offer(first);
            } else {
                result.append((char)first[1]);
                first[0]--;
                if (first[0] != 0) pq.offer(first);
            }
        }
        return result.toString();
    }
}
```
Create a priority queue that stores the frequency and the character, in descending order of frequency. Iterate through the queue, adding characters to the result string. If the current character is the same as the last character in the result, and there is another character available in the queue, add the next available character to the result instead. Then, decrement the frequency count and push the used characters back into the priority queue if they still have positive frequency. If there are no suitable characters left in the priority queue, stop processing and return the result string. The final result will be a happy string that meets the given requirements.

## A solution in C++

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

string longestDiverseString(int a, int b, int c) {
    string result = "";
    using T = pair<int, char>;
    priority_queue<T> pq;
    if (a) pq.push({a, 'a'});
    if (b) pq.push({b, 'b'});
    if (c) pq.push({c, 'c'});

    while (!pq.empty()) {
        T first = pq.top(); pq.pop();
        if (!result.empty() && result.back() == first.second) {
            if (pq.empty()) break;
            T second = pq.top(); pq.pop();
            result += second.second;
            second.first--;
            if (second.first) pq.push(second);
            pq.push(first);
        } else {
            result += first.second;
            first.first--;
            if (first.first) pq.push(first);
        }
    }
    return result;
}
```
Create a priority queue that stores the frequency and the character, in descending order of frequency. Iterate through the queue, adding characters to the result string. If the current character is the same as the last character in the result, and there is another character available in the queue, add the next available character to the result instead. Then, decrement the frequency count and push the used characters back into the priority queue if they still have positive frequency. If there are no suitable characters left in the priority queue, stop processing and return the result string. The final result will be a happy string that meets the given requirements.

## A solution in Python

```python
import heapq

def longest_diverse_string(a: int, b: int, c: int) -> str:
    result = ""
    pq = [(-a, 'a'), (-b, 'b'), (-c, 'c')]
    heapq.heapify(pq)

    while pq:
        first = heapq.heappop(pq)
        if not result or result[-1] != first[1]:
            result += first[1]
            first = (first[0] + 1, first[1])
            if first[0] < 0:
                heapq.heappush(pq, first)
        elif pq:
            second = heapq.heappop(pq)
            result += second[1]
            second = (second[0] + 1, second[1])
            if second[0] < 0:
                heapq.heappush(pq, second)
            if first[0] < 0:
                heapq.heappush(pq, first)
        else:
            break

    return result
```
Create a priority queue that stores the frequency and the character, in descending order of frequency. Iterate through the queue, adding characters to the result string. If the current character is the same as the last character in the result, and there is another character available in the queue, add the next available character to the result instead. Then, decrement the frequency count and push the used characters back into the priority queue if they still have positive frequency. If there are no suitable characters left in the priority queue, stop processing and return the result string. The final result will be a happy string that meets the given requirements.

## A solution in Javascript

```javascript
var longestDiverseString = function(a, b, c) {
    let result = "";
    let pq = new PriorityQueue(([cnt1, _], [cnt2, __]) => cnt1 > cnt2);
    if (a !== 0) pq.enqueue([a, 'a']);
    if (b !== 0) pq.enqueue([b, 'b']);
    if (c !== 0) pq.enqueue([c, 'c']);

    while (!pq.isEmpty()) {
        let [firstCnt, firstChar] = pq.dequeue();
        if (result.length === 0 || result[result.length - 1] !== firstChar) {
            result += firstChar;
            firstCnt--;
            if (firstCnt !== 0) pq.enqueue([firstCnt, firstChar]);
        } else if (!pq.isEmpty()) {
            let [secondCnt, secondChar] = pq.dequeue();
            result += secondChar;
            secondCnt--;
            if (secondCnt !== 0) pq.enqueue([secondCnt, secondChar]);
            pq.enqueue([firstCnt, firstChar]);
        } else {
            break;
        }
    }
    return result;
};
```
Create a priority queue that stores the frequency and the character, in descending order of frequency. Iterate through the queue, adding characters to the result string. If the current character is the same as the last character in the result, and there is another character available in the queue, add the next available character to the result instead. Then, decrement the frequency count and push the used characters back into the priority queue if they still have positive frequency. If there are no suitable characters left in the priority queue, stop processing and return the result string. The final result will be a happy string that meets the given requirements.


# Stone Game III

- slug: stone-game-iii
- difficulty: Hard

Alice and Bob continue their games with piles of stones. There are several stones **arranged in a row**, and each stone has an associated value which is an integer given in the array `stoneValue`.

Alice and Bob take turns, with Alice starting first. On each player's turn, that player can take `1`, `2`, or `3` stones from the **first** remaining stones in the row.

The score of each player is the sum of the values of the stones taken. The score of each player is `0` initially.

The objective of the game is to end with the highest score, and the winner is the player with the highest score and there could be a tie. The game continues until all the stones have been taken.

Assume Alice and Bob **play optimally**.

Return `"Alice "` _if Alice will win,_ `"Bob "` _if Bob will win, or_ `"Tie "` _if they will end the game with the same score_.

**Example 1:**

**Input:** values = \[1,2,3,7\]
**Output:**  "Bob "
**Explanation:** Alice will always lose. Her best move will be to take three piles and the score become 6. Now the score of Bob is 7 and Bob wins.

**Example 2:**

**Input:** values = \[1,2,3,-9\]
**Output:**  "Alice "
**Explanation:** Alice must choose all the three piles at the first move to win and leave Bob with negative score.
If Alice chooses one pile her score will be 1 and the next move Bob's score becomes 5. In the next move, Alice will take the pile with value = -9 and lose.
If Alice chooses two piles her score will be 3 and the next move Bob's score becomes 3. In the next move, Alice will take the pile with value = -9 and also lose.
Remember that both play optimally so here Alice will choose the scenario that makes her win.

**Example 3:**

**Input:** values = \[1,2,3,6\]
**Output:**  "Tie "
**Explanation:** Alice cannot win this game. She can end the game in a draw if she decided to choose all the first three piles, otherwise she will lose.

**Constraints:**

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

## A solution in Java

```java
public String stoneGameIII(int[] stoneValue) {
    int n = stoneValue.length;
    int[] dp = new int[n + 1];
    dp[n] = 0;

    for (int i = n - 1; i >= 0; --i) {
        dp[i] = Integer.MIN_VALUE;
        int curr = 0;
        for (int j = 0; j < 3 && i + j < n; ++j) {
            curr += stoneValue[i + j];
            dp[i] = Math.max(dp[i], curr - dp[i + j + 1]);
        }
    }

    return dp[0] == 0 ? "Tie " : dp[0] > 0 ? "Alice " : "Bob ";
}
```
We can solve this problem using dynamic programming. Create a `dp` array of size `n+1` where `n` is the length of the stoneValue array, and initialize it with the minimum possible integer value (in Python, use `-inf`). The last element of the `dp` array should be initialized to 0.
The idea is to find the maximum score difference each player can achieve, starting from index i, for 0 ≤ i < n.

For each index i, we calculate the current score (sum of values at most 3 consecutive stones starting from i) and update the `dp[i]` to max(`dp[i]`, current - `dp[i+j+1]`).

At the end, `dp[0]` represents the maximum score difference between Alice and Bob. If `dp[0] > 0`, Alice wins, if `dp[0] < 0`, Bob wins, and if `dp[0] == 0`, it's a tie.

## A solution in C++

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

string stoneGameIII(vector<int>& stoneValue) {
    int n = stoneValue.size();
    vector<int> dp(n + 1, INT_MIN);
    dp[n] = 0;

    for (int i = n - 1; i >= 0; --i) {
        int curr = 0;
        for (int j = 0; j < 3 && i + j < n; ++j) {
            curr += stoneValue[i + j];
            dp[i] = max(dp[i], curr - dp[i + j + 1]);
        }
    }

    return dp[0] == 0 ? "Tie " : dp[0] > 0 ? "Alice " : "Bob ";
}
```
We can solve this problem using dynamic programming. Create a `dp` array of size `n+1` where `n` is the length of the stoneValue array, and initialize it with the minimum possible integer value (in Python, use `-inf`). The last element of the `dp` array should be initialized to 0.
The idea is to find the maximum score difference each player can achieve, starting from index i, for 0 ≤ i < n.

For each index i, we calculate the current score (sum of values at most 3 consecutive stones starting from i) and update the `dp[i]` to max(`dp[i]`, current - `dp[i+j+1]`).

At the end, `dp[0]` represents the maximum score difference between Alice and Bob. If `dp[0] > 0`, Alice wins, if `dp[0] < 0`, Bob wins, and if `dp[0] == 0`, it's a tie.

## A solution in Python

```python
def stoneGameIII(stoneValue):
    n = len(stoneValue)
    dp = [float("-inf")] * (n + 1)
    dp[n] = 0

    for i in range(n - 1, -1, -1):
        curr = 0
        for j in range(3):
            if i + j < n:
                curr += stoneValue[i + j]
                dp[i] = max(dp[i], curr - dp[i + j + 1])

    return "Tie " if dp[0] == 0 else "Alice " if dp[0] > 0 else "Bob "
```
We can solve this problem using dynamic programming. Create a `dp` array of size `n+1` where `n` is the length of the stoneValue array, and initialize it with the minimum possible integer value (in Python, use `-inf`). The last element of the `dp` array should be initialized to 0.
The idea is to find the maximum score difference each player can achieve, starting from index i, for 0 ≤ i < n.

For each index i, we calculate the current score (sum of values at most 3 consecutive stones starting from i) and update the `dp[i]` to max(`dp[i]`, current - `dp[i+j+1]`).

At the end, `dp[0]` represents the maximum score difference between Alice and Bob. If `dp[0] > 0`, Alice wins, if `dp[0] < 0`, Bob wins, and if `dp[0] == 0`, it's a tie.

## A solution in Javascript

```javascript
var stoneGameIII = function(stoneValue) {
    let n = stoneValue.length;
    let dp = new Array(n + 1).fill(Number.MIN_SAFE_INTEGER);
    dp[n] = 0;

    for (let i = n - 1; i >= 0; --i) {
        let curr = 0;
        for (let j = 0; j < 3 && i + j < n; ++j) {
            curr += stoneValue[i + j];
            dp[i] = Math.max(dp[i], curr - dp[i + j + 1]);
        }
    }

    return dp[0] === 0 ? "Tie " : dp[0] > 0 ? "Alice " : "Bob ";
};
```
We can solve this problem using dynamic programming. Create a `dp` array of size `n+1` where `n` is the length of the stoneValue array, and initialize it with the minimum possible integer value (in Python, use `-inf`). The last element of the `dp` array should be initialized to 0.
The idea is to find the maximum score difference each player can achieve, starting from index i, for 0 ≤ i < n.

For each index i, we calculate the current score (sum of values at most 3 consecutive stones starting from i) and update the `dp[i]` to max(`dp[i]`, current - `dp[i+j+1]`).

At the end, `dp[0]` represents the maximum score difference between Alice and Bob. If `dp[0] > 0`, Alice wins, if `dp[0] < 0`, Bob wins, and if `dp[0] == 0`, it's a tie.


# String Matching in an Array

- slug: string-matching-in-an-array
- difficulty: Easy

Given an array of string `words`, return _all strings in_ `words` _that is a **substring** of another word_. You can return the answer in **any order**.

A **substring** is a contiguous sequence of characters within a string

**Example 1:**

**Input:** words = \[ "mass ", "as ", "hero ", "superhero "\]
**Output:** \[ "as ", "hero "\]
**Explanation:**  "as " is substring of  "mass " and  "hero " is substring of  "superhero ".
\[ "hero ", "as "\] is also a valid answer.

**Example 2:**

**Input:** words = \[ "leetcode ", "et ", "code "\]
**Output:** \[ "et ", "code "\]
**Explanation:**  "et ",  "code " are substring of  "leetcode ".

**Example 3:**

**Input:** words = \[ "blue ", "green ", "bu "\]
**Output:** \[\]
**Explanation:** No string of words is substring of another string.

**Constraints:**

*   `1 <= words.length <= 100`
*   `1 <= words[i].length <= 30`
*   `words[i]` contains only lowercase English letters.
*   All the strings of `words` are **unique**.

## A solution in Java

```java
import java.lang.Math;

public int smallestDivisor(int[] nums, int threshold) {
    int left = 1, right = 1000000;
    while (left < right) {
        int mid = (left + right) / 2;
        int sum = 0;
        for (int n : nums) {
            sum += Math.ceil(1.0 * n / mid);
        }
        if (sum > threshold) {
            left = mid + 1;
        } else {
            right = mid;
        }
    }
    return left;
}
```
We will use a binary search to find the smallest divisor. Define the search range initially from 1 to 1,000,000 (10^6). Calculate the middle value 'mid' between the given search range (left and right), and then get the sum of division results using that middle value in the array. If the sum of the division results is greater than the given threshold, that means the divisor must be larger, so we update the left boundary to be equal to 'mid' + 1. If the sum is less than or equal to the threshold, it means the divisor can be smaller or the value itself, so we update the right boundary to be equal to 'mid'. We repeat this process until the left and right boundaries are equal, and the final answer will be the left boundary.

## A solution in C++

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

int smallestDivisor(std::vector<int>& nums, int threshold) {
    int left = 1, right = 1e6;
    while (left < right) {
        int mid = (left + right) / 2;
        int sum = 0;
        for (int n : nums) {
            sum += std::ceil(1.0 * n / mid);
        }
        if (sum > threshold) {
            left = mid + 1;
        } else {
            right = mid;
        }
    }
    return left;
}
```
We will use a binary search to find the smallest divisor. Define the search range initially from 1 to 1,000,000 (10^6). Calculate the middle value 'mid' between the given search range (left and right), and then get the sum of division results using that middle value in the array. If the sum of the division results is greater than the given threshold, that means the divisor must be larger, so we update the left boundary to be equal to 'mid' + 1. If the sum is less than or equal to the threshold, it means the divisor can be smaller or the value itself, so we update the right boundary to be equal to 'mid'. We repeat this process until the left and right boundaries are equal, and the final answer will be the left boundary.

## A solution in Python

```python
import math

def smallest_divisor(nums, threshold):
    left, right = 1, 10**6
    while left < right:
        mid = (left + right) // 2
        total = sum(math.ceil(n / mid) for n in nums)
        if total > threshold:
            left = mid + 1
        else:
            right = mid
    return left
```
We will use a binary search to find the smallest divisor. Define the search range initially from 1 to 1,000,000 (10^6). Calculate the middle value 'mid' between the given search range (left and right), and then get the sum of division results using that middle value in the array. If the sum of the division results is greater than the given threshold, that means the divisor must be larger, so we update the left boundary to be equal to 'mid' + 1. If the sum is less than or equal to the threshold, it means the divisor can be smaller or the value itself, so we update the right boundary to be equal to 'mid'. We repeat this process until the left and right boundaries are equal, and the final answer will be the left boundary.

## A solution in Javascript

```javascript
function smallestDivisor(nums, threshold) {
    let left = 1, right = 10**6;
    while (left < right) {
        let mid = Math.floor((left + right) / 2);
        let sum = nums.reduce((acc, n) => acc + Math.ceil(n / mid), 0);
        if (sum > threshold) {
            left = mid + 1;
        } else {
            right = mid;
        }
    }
    return left;
}
```
We will use a binary search to find the smallest divisor. Define the search range initially from 1 to 1,000,000 (10^6). Calculate the middle value 'mid' between the given search range (left and right), and then get the sum of division results using that middle value in the array. If the sum of the division results is greater than the given threshold, that means the divisor must be larger, so we update the left boundary to be equal to 'mid' + 1. If the sum is less than or equal to the threshold, it means the divisor can be smaller or the value itself, so we update the right boundary to be equal to 'mid'. We repeat this process until the left and right boundaries are equal, and the final answer will be the left boundary.