# Island Perimeter

- slug: island-perimeter
- difficulty: Easy

You are given `row x col` `grid` representing a map where `grid[i][j] = 1` represents land and `grid[i][j] = 0` represents water.

Grid cells are connected **horizontally/vertically** (not diagonally). The `grid` is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells).

The island doesn't have "lakes ", meaning the water inside isn't connected to the water around the island. One cell is a square with side length 1. The grid is rectangular, width and height don't exceed 100. Determine the perimeter of the island.

**Example 1:**

**Input:** grid = \[\[0,1,0,0\],\[1,1,1,0\],\[0,1,0,0\],\[1,1,0,0\]\]
**Output:** 16
**Explanation:** The perimeter is the 16 yellow stripes in the image above.

**Example 2:**

**Input:** grid = \[\[1\]\]
**Output:** 4

**Example 3:**

**Input:** grid = \[\[1,0\]\]
**Output:** 4

**Constraints:**

*   `row == grid.length`
*   `col == grid[i].length`
*   `1 <= row, col <= 100`
*   `grid[i][j]` is `0` or `1`.
*   There is exactly one island in `grid`.

## A solution in Java

```java
public int islandPerimeter(int[][] grid) {
    int perimeter = 0;
    for (int row = 0; row < grid.length; row++) {
        for (int col = 0; col < grid[row].length; col++) {
            if (grid[row][col] == 1) {
                perimeter += 4;
                if (row > 0 && grid[row - 1][col] == 1) perimeter -= 2;
                if (col > 0 && grid[row][col - 1] == 1) perimeter -= 2;
            }
        }
    }
    return perimeter;
}
```
The algorithm iterates through each cell in the grid. If a cell contains land, increment the perimeter count by 4 (each side of the square). If there is land in the adjacent cell to the left or above, decrement the perimeter count by 2 for each adjacent land cell as they share a common side. This way, we can calculate the total perimeter of the island without any extra data structures or recursion.

## A solution in C++

```cpp
int islandPerimeter(vector<vector<int>>& grid) {
    int perimeter = 0;
    for (int row = 0; row < grid.size(); row++) {
        for (int col = 0; col < grid[row].size(); col++) {
            if (grid[row][col] == 1) {
                perimeter += 4;
                if (row > 0 && grid[row - 1][col] == 1) perimeter -= 2;
                if (col > 0 && grid[row][col - 1] == 1) perimeter -= 2;
            }
        }
    }
    return perimeter;
}
```
The algorithm iterates through each cell in the grid. If a cell contains land, increment the perimeter count by 4 (each side of the square). If there is land in the adjacent cell to the left or above, decrement the perimeter count by 2 for each adjacent land cell as they share a common side. This way, we can calculate the total perimeter of the island without any extra data structures or recursion.

## A solution in Python

```python
def islandPerimeter(grid):
    perimeter = 0
    for row in range(len(grid)):
        for col in range(len(grid[row])):
            if grid[row][col] == 1:
                perimeter += 4
                if row > 0 and grid[row - 1][col] == 1:
                    perimeter -= 2
                if col > 0 and grid[row][col - 1] == 1:
                    perimeter -= 2
    return perimeter
```
The algorithm iterates through each cell in the grid. If a cell contains land, increment the perimeter count by 4 (each side of the square). If there is land in the adjacent cell to the left or above, decrement the perimeter count by 2 for each adjacent land cell as they share a common side. This way, we can calculate the total perimeter of the island without any extra data structures or recursion.

## A solution in Javascript

```javascript
function islandPerimeter(grid) {
    let perimeter = 0;
    for (let row = 0; row < grid.length; row++) {
        for (let col = 0; col < grid[row].length; col++) {
            if (grid[row][col] === 1) {
                perimeter += 4;
                if (row > 0 && grid[row - 1][col] === 1) perimeter -= 2;
                if (col > 0 && grid[row][col - 1] === 1) perimeter -= 2;
            }
        }
    }
    return perimeter;
}
```
The algorithm iterates through each cell in the grid. If a cell contains land, increment the perimeter count by 4 (each side of the square). If there is land in the adjacent cell to the left or above, decrement the perimeter count by 2 for each adjacent land cell as they share a common side. This way, we can calculate the total perimeter of the island without any extra data structures or recursion.


# Can I Win

- slug: can-i-win
- difficulty: Medium

In the "100 game " two players take turns adding, to a running total, any integer from `1` to `10`. The player who first causes the running total to **reach or exceed** 100 wins.

What if we change the game so that players **cannot** re-use integers?

For example, two players might take turns drawing from a common pool of numbers from 1 to 15 without replacement until they reach a total >= 100.

Given two integers `maxChoosableInteger` and `desiredTotal`, return `true` if the first player to move can force a win, otherwise, return `false`. Assume both players play **optimally**.

**Example 1:**

**Input:** maxChoosableInteger = 10, desiredTotal = 11
**Output:** false
**Explanation:**
No matter which integer the first player choose, the first player will lose.
The first player can choose an integer from 1 up to 10.
If the first player choose 1, the second player can only choose integers from 2 up to 10.
The second player will win by choosing 10 and get a total = 11, which is >= desiredTotal.
Same with other integers chosen by the first player, the second player will always win.

**Example 2:**

**Input:** maxChoosableInteger = 10, desiredTotal = 0
**Output:** true

**Example 3:**

**Input:** maxChoosableInteger = 10, desiredTotal = 1
**Output:** true

**Constraints:**

*   `1 <= maxChoosableInteger <= 20`
*   `0 <= desiredTotal <= 300`

## A solution in Java

```java
import java.util.HashMap;

public class Solution {
    public boolean canIWin(int maxChoosableInteger, int desiredTotal) {
        if (maxChoosableInteger >= desiredTotal) return true;
        if ((maxChoosableInteger * (maxChoosableInteger + 1)) / 2 < desiredTotal) return false;

        HashMap<Integer, Boolean> memo = new HashMap<>();
        int state = 0;
        return canWin(maxChoosableInteger, desiredTotal, state, memo);
    }

    private boolean canWin(int maxChoosableInteger, int desiredTotal, int state, HashMap<Integer, Boolean> memo) {
        if (desiredTotal <= 0) return false;
        if (memo.containsKey(state)) return memo.get(state);

        for (int i = 1; i <= maxChoosableInteger; i++) {
            int bitCheck = 1 << i;
            if ((state & bitCheck) == 0) {
                if (!canWin(maxChoosableInteger, desiredTotal - i, state | bitCheck, memo)) {
                    memo.put(state, true);
                    return true;
                }
            }
        }

        memo.put(state, false);
        return false;
    }
}
```
We use a state, represented by an integer where each bit indicates if a number has been taken or not, and store the states in a memoization table. With each function call, we try to take each number from 1 to maxChoosableInteger if it hasn't been taken before, and update the state accordingly. If no moves can be made which forces a win, return false. If the desired total is equal to or less than zero, then the player has lost, and we return false.

Both players play optimally, so we can recursively call the function for each possible number and check if it doesn't result in a win for the other player. If we find such a scenario, then the first player can force a win. At the end, we return the final result from the memoization table.

## A solution in C++

```cpp
#include <unordered_map>

bool canWin(int maxChoosableInteger, int desiredTotal, int state, std::unordered_map<int, bool>& memo) {
    if(desiredTotal <= 0) {
        return false;
    }
    if(memo.count(state) > 0) {
        return memo[state];
    }
    for(int i = 1; i <= maxChoosableInteger; i++) {
        int bitCheck = 1 << i;
        if((state & bitCheck) == 0) {
            if(!canWin(maxChoosableInteger, desiredTotal - i, state | bitCheck, memo)) {
                memo[state] = true;
                return true;
            }
        }
    }
    memo[state] = false;
    return false;
}

bool canIWin(int maxChoosableInteger, int desiredTotal) {
    if (maxChoosableInteger >= desiredTotal) return true;
    if ((maxChoosableInteger * (maxChoosableInteger + 1)) / 2 < desiredTotal) return false;

    std::unordered_map<int, bool> memo;
    int state = 0;
    return canWin(maxChoosableInteger, desiredTotal, state, memo);
}
```
We use a state, represented by an integer where each bit indicates if a number has been taken or not, and store the states in a memoization table. With each function call, we try to take each number from 1 to maxChoosableInteger if it hasn't been taken before, and update the state accordingly. If no moves can be made which forces a win, return false. If the desired total is equal to or less than zero, then the player has lost, and we return false.

Both players play optimally, so we can recursively call the function for each possible number and check if it doesn't result in a win for the other player. If we find such a scenario, then the first player can force a win. At the end, we return the final result from the memoization table.

## A solution in Python

```python
def canIWin(maxChoosableInteger, desiredTotal):
    if maxChoosableInteger >= desiredTotal: return True
    if (maxChoosableInteger * (maxChoosableInteger + 1)) // 2 < desiredTotal: return False

    memo = {}

    def canWin(state):
        if state in memo:
            return memo[state]
        for i in range(1, maxChoosableInteger + 1):
            bitCheck = 1 << i
            if (state & bitCheck) == 0:
                if not canWin(state | bitCheck):
                    memo[state] = True
                    return True

        memo[state] = False
        return False

    return canWin(0)
```
We use a state, represented by an integer where each bit indicates if a number has been taken or not, and store the states in a memoization table. With each function call, we try to take each number from 1 to maxChoosableInteger if it hasn't been taken before, and update the state accordingly. If no moves can be made which forces a win, return false. If the desired total is equal to or less than zero, then the player has lost, and we return false.

Both players play optimally, so we can recursively call the function for each possible number and check if it doesn't result in a win for the other player. If we find such a scenario, then the first player can force a win. At the end, we return the final result from the memoization table.

## A solution in Javascript

```javascript
var canIWin = function(maxChoosableInteger, desiredTotal) {
    if (maxChoosableInteger >= desiredTotal) return true;
    if (maxChoosableInteger * (maxChoosableInteger + 1) / 2 < desiredTotal) return false;

    const memo = new Map();

    function canWin(state) {
        if (memo.has(state)) return memo.get(state);

        for (let i = 1; i <= maxChoosableInteger; i++) {
            let bitCheck = 1 << i;
            if ((state & bitCheck) === 0) {
                if (!canWin(state | bitCheck)) {
                    memo.set(state, true);
                    return true;
                }
            }
        }

        memo.set(state, false);
        return false;
    }

    return canWin(0);
}
```
We use a state, represented by an integer where each bit indicates if a number has been taken or not, and store the states in a memoization table. With each function call, we try to take each number from 1 to maxChoosableInteger if it hasn't been taken before, and update the state accordingly. If no moves can be made which forces a win, return false. If the desired total is equal to or less than zero, then the player has lost, and we return false.

Both players play optimally, so we can recursively call the function for each possible number and check if it doesn't result in a win for the other player. If we find such a scenario, then the first player can force a win. At the end, we return the final result from the memoization table.


# Optimal Account Balancing

- slug: optimal-account-balancing
- difficulty: Hard

You are given an array of transactions `transactions` where `transactions[i] = [fromi, toi, amounti]` indicates that the person with `ID = fromi` gave `amounti $` to the person with `ID = toi`.

Return _the minimum number of transactions required to settle the debt_.

**Example 1:**

**Input:** transactions = \[\[0,1,10\],\[2,0,5\]\]
**Output:** 2
**Explanation:**
Person #0 gave person #1 $10.
Person #2 gave person #0 $5.
Two transactions are needed. One way to settle the debt is person #1 pays person #0 and #2 $5 each.

**Example 2:**

**Input:** transactions = \[\[0,1,10\],\[1,0,1\],\[1,2,5\],\[2,0,5\]\]
**Output:** 1
**Explanation:**
Person #0 gave person #1 $10.
Person #1 gave person #0 $1.
Person #1 gave person #2 $5.
Person #2 gave person #0 $5.
Therefore, person #1 only need to give person #0 $4, and all debt is settled.

**Constraints:**

*   `1 <= transactions.length <= 8`
*   `transactions[i].length == 3`
*   `0 <= fromi, toi < 12`
*   `fromi != toi`
*   `1 <= amounti <= 100`

## A solution in Java

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

public int minTransfers(int[][] transactions) {
    Map<Integer, Integer> balances = new HashMap<>();
    for (int[] transaction : transactions) {
        balances.put(transaction[0], balances.getOrDefault(transaction[0], 0) - transaction[2]);
        balances.put(transaction[1], balances.getOrDefault(transaction[1], 0) + transaction[2]);
    }

    List<Integer> debts = new ArrayList<>();
    for (int balance : balances.values()) {
        if (balance != 0) {
            debts.add(balance);
        }
    }
    return dfs(debts, 0);
}

private int dfs(List<Integer> debts, int start) {
    while (start < debts.size() && debts.get(start) == 0) {
        start++;
    }
    if (start == debts.size()) {
        return 0;
    }
    int result = Integer.MAX_VALUE;
    for (int i = start + 1; i < debts.size(); ++i) {
        if ((debts.get(start) > 0) != (debts.get(i) > 0)) {
            debts.set(i, debts.get(i) + debts.get(start));
            result = Math.min(result, 1 + dfs(debts, start + 1));
            debts.set(i, debts.get(i) - debts.get(start));
        }
    }
    return result;
}
```
The algorithm works by first iterating through the transactions and calculating the debt balance for each person. The debt balance maintains how much each person owes or is owed. Then, it stores the non-zero balance values in a separate list called `debts`.

Next, it performs a depth-first search (DFS) to minimize the transaction counts. The DFS function iterates over each pair of debts, and if one member owes money and the other is owed money, it simulates settling the debt by adjusting the balance and calling the DFS function recursively with the updated balance. After this step, it reverts the changes to the balance and compares the minimum transactions found.

The algorithm iterates over all possible subsets of debts and returns the minimum number of transactions required to settle the debts.

## A solution in C++

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

int minTransfers(std::vector<std::vector<int>>& transactions) {
    std::unordered_map<int, int> balances;
    for (const auto& transaction : transactions) {
        balances[transaction[0]] -= transaction[2];
        balances[transaction[1]] += transaction[2];
    }

    std_msgs::vector<int> debts;
    for (const auto& balance : balances) {
        if (balance.second != 0) {
            debts.push_back(balance.second);
        }
    }
    return dfs(debts, 0);
}

int dfs(std::vector<int>& debts, int start) {
    while (start < debts.size() && debts[start] == 0) {
        start++;
    }
    if (start == debts.size()) {
        return 0;
    }
    int result = INT_MAX;
    for (int i = start + 1; i < debts.size(); ++i) {
        if ((debts[start] > 0) != (debts[i] > 0)) {
            debts[i] += debts[start];
            result = std::min(result, 1 + dfs(debts, start + 1));
            debts[i] -= debts[start];
        }
    }
    return result;
}
```
The algorithm works by first iterating through the transactions and calculating the debt balance for each person. The debt balance maintains how much each person owes or is owed. Then, it stores the non-zero balance values in a separate list called `debts`.

Next, it performs a depth-first search (DFS) to minimize the transaction counts. The DFS function iterates over each pair of debts, and if one member owes money and the other is owed money, it simulates settling the debt by adjusting the balance and calling the DFS function recursively with the updated balance. After this step, it reverts the changes to the balance and compares the minimum transactions found.

The algorithm iterates over all possible subsets of debts and returns the minimum number of transactions required to settle the debts.

## A solution in Python

```python
from collections import defaultdict

def minTransfers(transactions):
    balances = defaultdict(int)
    for transaction in transactions:
        balances[transaction[0]] -= transaction[2]
        balances[transaction[1]] += transaction[2]

    debts = [balance for balance in balances.values() if balance != 0]
    return dfs(debts, 0)

def dfs(debts, start):
    while start < len(debts) and debts[start] == 0:
        start += 1
    if start == len(debts):
        return 0
    result = float('inf')
    for i in range(start + 1, len(debts)):
        if (debts[start] > 0) != (debts[i] > 0):
            debts[i] += debts[start]
            result = min(result, 1 + dfs(debts, start + 1))
            debts[i] -= debts[start]
    return result
```
The algorithm works by first iterating through the transactions and calculating the debt balance for each person. The debt balance maintains how much each person owes or is owed. Then, it stores the non-zero balance values in a separate list called `debts`.

Next, it performs a depth-first search (DFS) to minimize the transaction counts. The DFS function iterates over each pair of debts, and if one member owes money and the other is owed money, it simulates settling the debt by adjusting the balance and calling the DFS function recursively with the updated balance. After this step, it reverts the changes to the balance and compares the minimum transactions found.

The algorithm iterates over all possible subsets of debts and returns the minimum number of transactions required to settle the debts.

## A solution in Javascript

```javascript
function minTransfers(transactions) {
    const balances = new Map();
    for (const transaction of transactions) {
        balances.set(transaction[0], (balances.get(transaction[0]) || 0) - transaction[2]);
        balances.set(transaction[1], (balances.get(transaction[1]) || 0) + transaction[2]);
    }

    const debts = [];
    for (const balance of balances.values()) {
        if (balance !== 0) {
            debts.push(balance);
        }
    }
    return dfs(debts, 0);
}

function dfs(debts, start) {
    while (start < debts.length && debts[start] === 0) {
        start++;
    }
    if (start === debts.length) {
        return 0;
    }
    let result = Infinity;
    for (let i = start + 1; i < debts.length; ++i) {
        if ((debts[start] > 0) !== (debts[i] > 0)) {
            debts[i] += debts[start];
            result = Math.min(result, 1 + dfs(debts, start + 1));
            debts[i] -= debts[start];
        }
    }
    return result;
}
```
The algorithm works by first iterating through the transactions and calculating the debt balance for each person. The debt balance maintains how much each person owes or is owed. Then, it stores the non-zero balance values in a separate list called `debts`.

Next, it performs a depth-first search (DFS) to minimize the transaction counts. The DFS function iterates over each pair of debts, and if one member owes money and the other is owed money, it simulates settling the debt by adjusting the balance and calling the DFS function recursively with the updated balance. After this step, it reverts the changes to the balance and compares the minimum transactions found.

The algorithm iterates over all possible subsets of debts and returns the minimum number of transactions required to settle the debts.


# Count The Repetitions

- slug: count-the-repetitions
- difficulty: Hard

We define `str = [s, n]` as the string `str` which consists of the string `s` concatenated `n` times.

*   For example, `str == [ "abc ", 3] == "abcabcabc "`.

We define that string `s1` can be obtained from string `s2` if we can remove some characters from `s2` such that it becomes `s1`.

*   For example, `s1 = "abc "` can be obtained from `s2 = "ab**dbe**c "` based on our definition by removing the bolded underlined characters.

You are given two strings `s1` and `s2` and two integers `n1` and `n2`. You have the two strings `str1 = [s1, n1]` and `str2 = [s2, n2]`.

Return _the maximum integer_ `m` _such that_ `str = [str2, m]` _can be obtained from_ `str1`.

**Example 1:**

**Input:** s1 = "acb", n1 = 4, s2 = "ab", n2 = 2
**Output:** 2

**Example 2:**

**Input:** s1 = "acb", n1 = 1, s2 = "acb", n2 = 1
**Output:** 1

**Constraints:**

*   `1 <= s1.length, s2.length <= 100`
*   `s1` and `s2` consist of lowercase English letters.
*   `1 <= n1, n2 <= 106`

## A solution in Java

```java
public int getMaxRepetitions(String s1, int n1, String s2, int n2) {
    int count1 = 0, count2 = 0, i = 0, j = 0;
    while (count1 < n1) {
        if (s1.charAt(i) == s2.charAt(j)) {
            j++;
            if (j == s2.length()) {
                j = 0;
                count2++;
            }
        }
        i++;
        if (i == s1.length()) {
            i = 0;
            count1++;
        }
    }
    return count2 / n2;
}
```
1. Initialize counter variables for both strings (count1 and count2) as well as indices for both strings (i and j).
2. Iterate through str1 while count1 is less than n1.
3. Compare the characters at the current indices of s1 and s2. If they match, increment index j of s2.
4. If j reaches the length of s2, reset j to 0 and increment count2.
5. Increment index i of s1. If i reaches the length of s1, reset i to 0 and increment count1.
6. Return the integer division of count2 by n2 as the maximum integer m.

## A solution in C++

```cpp
int getMaxRepetitions(string s1, int n1, string s2, int n2) {
    int count1 = 0, count2 = 0, i = 0, j = 0;
    while (count1 < n1) {
        if (s1[i] == s2[j]) {
            j++;
            if (j == s2.size()) {
                j = 0;
                count2++;
            }
        }
        i++;
        if (i == s1.size()) {
            i = 0;
            count1++;
        }
    }
    return count2 / n2;
}
```
1. Initialize counter variables for both strings (count1 and count2) as well as indices for both strings (i and j).
2. Iterate through str1 while count1 is less than n1.
3. Compare the characters at the current indices of s1 and s2. If they match, increment index j of s2.
4. If j reaches the length of s2, reset j to 0 and increment count2.
5. Increment index i of s1. If i reaches the length of s1, reset i to 0 and increment count1.
6. Return the integer division of count2 by n2 as the maximum integer m.

## A solution in Python

```python
def getMaxRepetitions(s1: str, n1: int, s2: str, n2: int) -> int:
    count1, count2, i, j = 0, 0, 0, 0
    while count1 < n1:
        if s1[i] == s2[j]:
            j += 1
            if j == len(s2):
                j = 0
                count2 += 1
        i += 1
        if i == len(s1):
            i = 0
            count1 += 1
    return count2 // n2
```
1. Initialize counter variables for both strings (count1 and count2) as well as indices for both strings (i and j).
2. Iterate through str1 while count1 is less than n1.
3. Compare the characters at the current indices of s1 and s2. If they match, increment index j of s2.
4. If j reaches the length of s2, reset j to 0 and increment count2.
5. Increment index i of s1. If i reaches the length of s1, reset i to 0 and increment count1.
6. Return the integer division of count2 by n2 as the maximum integer m.

## A solution in Javascript

```javascript
function getMaxRepetitions(s1, n1, s2, n2) {
    let count1 = 0, count2 = 0, i = 0, j = 0;
    while (count1 < n1) {
        if (s1.charAt(i) === s2.charAt(j)) {
            j++;
            if (j === s2.length) {
                j = 0;
                count2++;
            }
        }
        i++;
        if (i === s1.length) {
            i = 0;
            count1++;
        }
    }
    return Math.floor(count2 / n2);
}
```
1. Initialize counter variables for both strings (count1 and count2) as well as indices for both strings (i and j).
2. Iterate through str1 while count1 is less than n1.
3. Compare the characters at the current indices of s1 and s2. If they match, increment index j of s2.
4. If j reaches the length of s2, reset j to 0 and increment count2.
5. Increment index i of s1. If i reaches the length of s1, reset i to 0 and increment count1.
6. Return the integer division of count2 by n2 as the maximum integer m.


# Unique Substrings in Wraparound String

- slug: unique-substrings-in-wraparound-string
- difficulty: Medium

We define the string `base` to be the infinite wraparound string of `"abcdefghijklmnopqrstuvwxyz "`, so `base` will look like this:

*   `"...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd.... "`.

Given a string `s`, return _the number of **unique non-empty substrings** of_ `s` _are present in_ `base`.

**Example 1:**

**Input:** s =  "a "
**Output:** 1
**Explanation:** Only the substring  "a " of s is in base.

**Example 2:**

**Input:** s =  "cac "
**Output:** 2
**Explanation:** There are two substrings ( "a ",  "c ") of s in base.

**Example 3:**

**Input:** s =  "zab "
**Output:** 6
**Explanation:** There are six substrings ( "z ",  "a ",  "b ",  "za ",  "ab ", and  "zab ") of s in base.

**Constraints:**

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

## A solution in Java

```java
public int findSubstringInWraproundString(String p) {
    int[] cnt = new int[26];
    int length = 0;

    for (int i = 0; i < p.length(); i++) {
        if (i > 0 && (p.charAt(i) == p.charAt(i - 1) + 1 || p.charAt(i - 1) - p.charAt(i) == 25)) {
            length++;
        } else {
            length = 1;
        }
        cnt[p.charAt(i) - 'a'] = Math.max(cnt[p.charAt(i) - 'a'], length);
    }

    int sum = 0;
    for (int v : cnt) {
        sum += v;
    }
    return sum;
}
```
1. Initialize an array cnt of size 26 to keep the count of the maximum length of contiguous characters ending with a given character.
2. Initialize a variable length to keep track of the current count of contiguous characters.
3. Iterate through the given string p.
   - If the current character is the next character of the previous one or wraps around from 'z' to 'a', increment length by 1.
   - Otherwise, reset length to 1.
   - Update cnt for the current character with the maximum of its current value and length.
4. Return the sum of all the counts in cnt.

## A solution in C++

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

int findSubstringInWraproundString(const std::string& p) {
    std::vector<int> cnt(26, 0);
    int length = 0;

    for (int i = 0; i < p.size(); i++) {
        if (i > 0 && (p[i] == p[i - 1] + 1 || p[i - 1] - p[i] == 25)) {
            length++;
        } else {
            length = 1;
        }
        cnt[p[i] - 'a'] = std::max(cnt[p[i] - 'a'], length);
    }

    return std::accumulate(cnt.begin(), cnt.end(), 0);
}
```
1. Initialize an array cnt of size 26 to keep the count of the maximum length of contiguous characters ending with a given character.
2. Initialize a variable length to keep track of the current count of contiguous characters.
3. Iterate through the given string p.
   - If the current character is the next character of the previous one or wraps around from 'z' to 'a', increment length by 1.
   - Otherwise, reset length to 1.
   - Update cnt for the current character with the maximum of its current value and length.
4. Return the sum of all the counts in cnt.

## A solution in Python

```python
def findSubstringInWraproundString(p: str) -> int:
    cnt = [0] * 26
    length = 0

    for i in range(len(p)):
        if i > 0 and (p[i] == chr(ord(p[i - 1]) + 1) or ord(p[i - 1]) - ord(p[i]) == 25):
            length += 1
        else:
            length = 1
        cnt[ord(p[i]) - ord('a')] = max(cnt[ord(p[i]) - ord('a')], length)

    return sum(cnt)
```
1. Initialize an array cnt of size 26 to keep the count of the maximum length of contiguous characters ending with a given character.
2. Initialize a variable length to keep track of the current count of contiguous characters.
3. Iterate through the given string p.
   - If the current character is the next character of the previous one or wraps around from 'z' to 'a', increment length by 1.
   - Otherwise, reset length to 1.
   - Update cnt for the current character with the maximum of its current value and length.
4. Return the sum of all the counts in cnt.

## A solution in Javascript

```javascript
function findSubstringInWraproundString(p) {
    const cnt = new Array(26).fill(0);
    let length = 0;

    for (let i = 0; i < p.length; i++) {
        if (i > 0 && (p.charCodeAt(i) === p.charCodeAt(i - 1) + 1 || p.charCodeAt(i - 1) - p.charCodeAt(i) === 25)) {
            length++;
        } else {
            length = 1;
        }
        cnt[p.charCodeAt(i) - 'a'.charCodeAt(0)] = Math.max(cnt[p.charCodeAt(i) - 'a'.charCodeAt(0)], length);
    }

    return cnt.reduce((a, b) => a + b, 0);
}
```
1. Initialize an array cnt of size 26 to keep the count of the maximum length of contiguous characters ending with a given character.
2. Initialize a variable length to keep track of the current count of contiguous characters.
3. Iterate through the given string p.
   - If the current character is the next character of the previous one or wraps around from 'z' to 'a', increment length by 1.
   - Otherwise, reset length to 1.
   - Update cnt for the current character with the maximum of its current value and length.
4. Return the sum of all the counts in cnt.


# Validate IP Address

- slug: validate-ip-address
- difficulty: Medium

Given a string `queryIP`, return `"IPv4 "` if IP is a valid IPv4 address, `"IPv6 "` if IP is a valid IPv6 address or `"Neither "` if IP is not a correct IP of any type.

**A valid IPv4** address is an IP in the form `"x1.x2.x3.x4 "` where `0 <= xi <= 255` and `xi` **cannot contain** leading zeros. For example, `"192.168.1.1 "` and `"192.168.1.0 "` are valid IPv4 addresses while `"192.168.01.1 "`, `"192.168.1.00 "`, and `"192.168@1.1 "` are invalid IPv4 addresses.

**A valid IPv6** address is an IP in the form `"x1:x2:x3:x4:x5:x6:x7:x8 "` where:

*   `1 <= xi.length <= 4`
*   `xi` is a **hexadecimal string** which may contain digits, lowercase English letter (`'a'` to `'f'`) and upper-case English letters (`'A'` to `'F'`).
*   Leading zeros are allowed in `xi`.

For example, "`2001:0db8:85a3:0000:0000:8a2e:0370:7334 "` and "`2001:db8:85a3:0:0:8A2E:0370:7334 "` are valid IPv6 addresses, while "`2001:0db8:85a3::8A2E:037j:7334 "` and "`02001:0db8:85a3:0000:0000:8a2e:0370:7334 "` are invalid IPv6 addresses.

**Example 1:**

**Input:** queryIP =  "172.16.254.1 "
**Output:**  "IPv4 "
**Explanation:** This is a valid IPv4 address, return  "IPv4 ".

**Example 2:**

**Input:** queryIP =  "2001:0db8:85a3:0:0:8A2E:0370:7334 "
**Output:**  "IPv6 "
**Explanation:** This is a valid IPv6 address, return  "IPv6 ".

**Example 3:**

**Input:** queryIP =  "256.256.256.256 "
**Output:**  "Neither "
**Explanation:** This is neither a IPv4 address nor a IPv6 address.

**Constraints:**

*   `queryIP` consists only of English letters, digits and the characters `'.'` and `':'`.

## A solution in Java

```java
public String validateIP(String queryIP) {
    String[] ipv4Parts = queryIP.split("\\.", -1);
    String[] ipv6Parts = queryIP.split(":", -1);

    if (ipv4Parts.length == 4) {
        if (isValidIPv4(ipv4Parts)) return "IPv4";
    } else if (ipv6Parts.length == 8) {
        if (isValidIPv6(ipv6Parts)) return "IPv6";
    }

    return "Neither";
}

private boolean isValidIPv4(String[] parts) {
    for (String part : parts) {
        if (part.length() == 0 || part.length() > 3 || (part.length() > 1 && part.charAt(0) == '0')) return false;

        int num = 0;
        for (char ch : part.toCharArray()) {
            if (!Character.isDigit(ch)) return false;
            num = num * 10 + (ch - '0');
        }

        if (num < 0 || num > 255) return false;
    }

    return true;
}

private boolean isValidIPv6(String[] parts) {
    for (String part : parts) {
        if (part.length() == 0 || part.length() > 4) return false;

        for (char ch : part.toCharArray()) {
            if (!Character.isDigit(ch) && !(ch >= 'a' && ch <= 'f') && !(ch >= 'A' && ch <= 'F')) return false;
        }
    }

    return true;
}
```
The algorithm checks if the given `queryIP` is an IPv4 or IPv6, then proceeds as follows:

1. For IPv4, we split the input by dots '.' and validate if there are exactly 4 parts. Each part should be a string with length between 1 and 3, and should not have leading zeros. We then check if each character of the part is a digit and if the integer value of the part is between 0 and 255 inclusive.

2. For IPv6, we split the input by colons ':' and validate if there are exactly 8 parts. Each part should be a string with length between 1 and 4. We then check if each character of the part is a hexadecimal digit (0-9, a-f or A-F).

If the given `queryIP` passes either of the above validations, it is considered a valid IPv4 or IPv6 address. Otherwise, it is considered "Neither".

## A solution in C++

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

bool isValidIPv4(const std::string& part);
bool isValidIPv6(const std::string& part);

std::string validateIP(const std::string& queryIP) {
    std::stringstream ss(queryIP);
    std::string part;
    int partsCount = 0;

    if (queryIP.find(':') == std::string::npos) {
        while (getline(ss, part, '.')) {
            if (!isValidIPv4(part)) return "Neither";
            partsCount++;
        }
        if (partsCount == 4) return "IPv4";
    } else {
        while (getline(ss, part, ':')) {
            if (!isValidIPv6(part)) return "Neither";
            partsCount++;
        }
        if (partsCount == 8) return "IPv6";
    }

    return "Neither";
}

bool isValidIPv4(const std::string& part) {
    if (part.empty() || part.size() > 3) return false;
    if (part.size() > 1 && part[0] == '0') return false;

    int num = 0;
    for (char ch : part) {
        if (!isdigit(ch)) return false;
        num = num * 10 + (ch - '0');
    }

    return num >= 0 && num <= 255;
}

bool isValidIPv6(const std::string& part) {
    if (part.empty() || part.size() > 4) return false;

    for (char ch : part) {
        if (!isxdigit(ch)) return false;
    }

    return true;
}
```
The algorithm checks if the given `queryIP` is an IPv4 or IPv6, then proceeds as follows:

1. For IPv4, we split the input by dots '.' and validate if there are exactly 4 parts. Each part should be a string with length between 1 and 3, and should not have leading zeros. We then check if each character of the part is a digit and if the integer value of the part is between 0 and 255 inclusive.

2. For IPv6, we split the input by colons ':' and validate if there are exactly 8 parts. Each part should be a string with length between 1 and 4. We then check if each character of the part is a hexadecimal digit (0-9, a-f or A-F).

If the given `queryIP` passes either of the above validations, it is considered a valid IPv4 or IPv6 address. Otherwise, it is considered "Neither".

## A solution in Python

```python
def validateIP(queryIP):
    ipv4_parts = queryIP.split('.')
    ipv6_parts = queryIP.split(':')

    if len(ipv4_parts) == 4:
        if is_valid_ipv4(ipv4_parts):
            return "IPv4"
    elif len(ipv6_parts) == 8:
        if is_valid_ipv6(ipv6_parts):
            return "IPv6"

    return "Neither"

def is_valid_ipv4(parts):
    for part in parts:
        if not part or len(part) > 3 or (len(part) > 1 and part[0] == '0'):
            return False

        if not part.isdigit() or int(part) < 0 or int(part) > 255:
            return False

    return True

def is_valid_ipv6(parts):
    for part in parts:
        if not part or len(part) > 4:
            return False

        for ch in part:
            if not ch.isdigit() and not (ch.lower() >= 'a' and ch.lower() <= 'f'):
                return False

    return True
```
The algorithm checks if the given `queryIP` is an IPv4 or IPv6, then proceeds as follows:

1. For IPv4, we split the input by dots '.' and validate if there are exactly 4 parts. Each part should be a string with length between 1 and 3, and should not have leading zeros. We then check if each character of the part is a digit and if the integer value of the part is between 0 and 255 inclusive.

2. For IPv6, we split the input by colons ':' and validate if there are exactly 8 parts. Each part should be a string with length between 1 and 4. We then check if each character of the part is a hexadecimal digit (0-9, a-f or A-F).

If the given `queryIP` passes either of the above validations, it is considered a valid IPv4 or IPv6 address. Otherwise, it is considered "Neither".

## A solution in Javascript

```javascript
function validateIP(queryIP) {
    const ipv4_parts = queryIP.split('.');
    const ipv6_parts = queryIP.split(':');

    if (ipv4_parts.length == 4) {
        if (isValidIPv4(ipv4_parts)) return "IPv4";
    } else if (ipv6_parts.length == 8) {
        if (isValidIPv6(ipv6_parts)) return "IPv6";
    }

    return "Neither";
}

function isValidIPv4(parts) {
    for (let part of parts) {
        if (!part || part.length > 3 || (part.length > 1 && part[0] == '0')) return false;

        let num = 0;
        for (let ch of part) {
            if (!/[0-9]/.test(ch)) return false;
            num = num * 10 + parseInt(ch);
        }

        if (num < 0 || num > 255) return false;
    }

    return true;
}

function isValidIPv6(parts) {
    for (let part of parts) {
        if (!part || part.length > 4) return false;

        for (let ch of part) {
            if (!/[0-9a-fA-F]/.test(ch)) return false;
        }
    }

    return true;
}
```
The algorithm checks if the given `queryIP` is an IPv4 or IPv6, then proceeds as follows:

1. For IPv4, we split the input by dots '.' and validate if there are exactly 4 parts. Each part should be a string with length between 1 and 3, and should not have leading zeros. We then check if each character of the part is a digit and if the integer value of the part is between 0 and 255 inclusive.

2. For IPv6, we split the input by colons ':' and validate if there are exactly 8 parts. Each part should be a string with length between 1 and 4. We then check if each character of the part is a hexadecimal digit (0-9, a-f or A-F).

If the given `queryIP` passes either of the above validations, it is considered a valid IPv4 or IPv6 address. Otherwise, it is considered "Neither".


# Convex Polygon

- slug: convex-polygon
- difficulty: Medium

You are given an array of points on the **X-Y** plane `points` where `points[i] = [xi, yi]`. The points form a polygon when joined sequentially.

Return `true` if this polygon is [convex](http://en.wikipedia.org/wiki/Convex_polygon) and `false` otherwise.

You may assume the polygon formed by given points is always a [simple polygon](http://en.wikipedia.org/wiki/Simple_polygon). In other words, we ensure that exactly two edges intersect at each vertex and that edges otherwise don't intersect each other.

**Example 1:**

**Input:** points = \[\[0,0\],\[0,5\],\[5,5\],\[5,0\]\]
**Output:** true

**Example 2:**

**Input:** points = \[\[0,0\],\[0,10\],\[10,10\],\[10,0\],\[5,5\]\]
**Output:** false

**Constraints:**

*   `3 <= points.length <= 104`
*   `points[i].length == 2`
*   `-104 <= xi, yi <= 104`
*   All the given points are **unique**.

## A solution in Java

```java
public boolean isConvex(int[][] points) {
    int n = points.length;
    int pre = 0, cur = 0;

    for (int i = 0; i < n; ++i) {
        int x1 = points[(i + 1) % n][0] - points[i][0];
        int y1 = points[(i + 1) % n][1] - points[i][1];
        int x2 = points[(i + 2) % n][0] - points[(i + 1) % n][0];
        int y2 = points[(i + 2) % n][1] - points[(i + 1) % n][1];
        cur = x1 * y2 - x2 * y1;

        if (cur == 0)
            continue;
        if (cur * pre < 0)
            return false;
        pre = cur;
    }

    return true;
}
```
We can determine if a polygon is convex by checking the z-component of the cross product between any two consecutive edges in the polygon. If the sign of this cross product remains the same for all the edges, the polygon is convex; otherwise, it is not.

First, initialize `n` as the number of points, and `pre` and `cur` as integers to hold the cross product value. Then, loop through the points with an index `i` from 0 to `n`. Inside the loop:
- Calculate `x1` and `y1` as the difference between the coordinates of the next point and the current point.
- Calculate `x2` and `y2` as the difference between the coordinates of the point after the next and the next point.
- Calculate the cross product value `cur` as `x1 * y2 - x2 * y1`.
- If `cur` is 0, continue to the next iteration.
- If the product of `cur` and `pre` is negative, return `false`, as the polygon is not convex.
- Set `pre` to `cur`.

After the loop, return `true`, as the polygon is convex.

## A solution in C++

```cpp
bool isConvex(vector<vector<int>>& points) {
    int n = points.size();
    int pre = 0, cur = 0;

    for (int i = 0; i < n; ++i) {
        int x1 = points[(i + 1) % n][0] - points[i][0];
        int y1 = points[(i + 1) % n][1] - points[i][1];
        int x2 = points[(i + 2) % n][0] - points[(i + 1) % n][0];
        int y2 = points[(i + 2) % n][1] - points[(i + 1) % n][1];
        cur = x1 * y2 - x2 * y1;

        if (cur == 0)
            continue;
        if (cur * pre < 0)
            return false;
        pre = cur;
    }

    return true;
}
```
We can determine if a polygon is convex by checking the z-component of the cross product between any two consecutive edges in the polygon. If the sign of this cross product remains the same for all the edges, the polygon is convex; otherwise, it is not.

First, initialize `n` as the number of points, and `pre` and `cur` as integers to hold the cross product value. Then, loop through the points with an index `i` from 0 to `n`. Inside the loop:
- Calculate `x1` and `y1` as the difference between the coordinates of the next point and the current point.
- Calculate `x2` and `y2` as the difference between the coordinates of the point after the next and the next point.
- Calculate the cross product value `cur` as `x1 * y2 - x2 * y1`.
- If `cur` is 0, continue to the next iteration.
- If the product of `cur` and `pre` is negative, return `false`, as the polygon is not convex.
- Set `pre` to `cur`.

After the loop, return `true`, as the polygon is convex.

## A solution in Python

```python
def isConvex(points):
    n = len(points)
    pre = cur = 0

    for i in range(n):
        x1 = points[(i + 1) % n][0] - points[i][0]
        y1 = points[(i + 1) % n][1] - points[i][1]
        x2 = points[(i + 2) % n][0] - points[(i + 1) % n][0]
        y2 = points[(i + 2) % n][1] - points[(i + 1) % n][1]
        cur = x1 * y2 - x2 * y1

        if cur == 0:
            continue
        if cur * pre < 0:
            return False
        pre = cur

    return True
```
We can determine if a polygon is convex by checking the z-component of the cross product between any two consecutive edges in the polygon. If the sign of this cross product remains the same for all the edges, the polygon is convex; otherwise, it is not.

First, initialize `n` as the number of points, and `pre` and `cur` as integers to hold the cross product value. Then, loop through the points with an index `i` from 0 to `n`. Inside the loop:
- Calculate `x1` and `y1` as the difference between the coordinates of the next point and the current point.
- Calculate `x2` and `y2` as the difference between the coordinates of the point after the next and the next point.
- Calculate the cross product value `cur` as `x1 * y2 - x2 * y1`.
- If `cur` is 0, continue to the next iteration.
- If the product of `cur` and `pre` is negative, return `false`, as the polygon is not convex.
- Set `pre` to `cur`.

After the loop, return `true`, as the polygon is convex.

## A solution in Javascript

```javascript
function isConvex(points) {
    const n = points.length;
    let pre = 0, cur = 0;

    for (let i = 0; i < n; ++i) {
        const x1 = points[(i + 1) % n][0] - points[i][0];
        const y1 = points[(i + 1) % n][1] - points[i][1];
        const x2 = points[(i + 2) % n][0] - points[(i + 1) % n][0];
        const y2 = points[(i + 2) % n][1] - points[(i + 1) % n][1];
        cur = x1 * y2 - x2 * y1;

        if (cur === 0)
            continue;
        if (cur * pre < 0)
            return false;
        pre = cur;
    }

    return true;
}
```
We can determine if a polygon is convex by checking the z-component of the cross product between any two consecutive edges in the polygon. If the sign of this cross product remains the same for all the edges, the polygon is convex; otherwise, it is not.

First, initialize `n` as the number of points, and `pre` and `cur` as integers to hold the cross product value. Then, loop through the points with an index `i` from 0 to `n`. Inside the loop:
- Calculate `x1` and `y1` as the difference between the coordinates of the next point and the current point.
- Calculate `x2` and `y2` as the difference between the coordinates of the point after the next and the next point.
- Calculate the cross product value `cur` as `x1 * y2 - x2 * y1`.
- If `cur` is 0, continue to the next iteration.
- If the product of `cur` and `pre` is negative, return `false`, as the polygon is not convex.
- Set `pre` to `cur`.

After the loop, return `true`, as the polygon is convex.


# Implement Rand10() Using Rand7()

- slug: implement-rand10-using-rand7
- difficulty: Medium

Given the **API** `rand7()` that generates a uniform random integer in the range `[1, 7]`, write a function `rand10()` that generates a uniform random integer in the range `[1, 10]`. You can only call the API `rand7()`, and you shouldn't call any other API. Please **do not** use a language's built-in random API.

Each test case will have one **internal** argument `n`, the number of times that your implemented function `rand10()` will be called while testing. Note that this is **not an argument** passed to `rand10()`.

**Example 1:**

**Input:** n = 1
**Output:** \[2\]

**Example 2:**

**Input:** n = 2
**Output:** \[2,8\]

**Example 3:**

**Input:** n = 3
**Output:** \[3,8,10\]

**Constraints:**

*   `1 <= n <= 105`

**Follow up:**

*   What is the [expected value](https://en.wikipedia.org/wiki/Expected_value) for the number of calls to `rand7()` function?
*   Could you minimize the number of calls to `rand7()`?

## A solution in Java

```java
public int rand7() ; // Provided API

public int rand10() {
    int result;
    do {
        result = (rand7() - 1) * 7 + rand7();
    } while (result > 40);
    return result % 10 + 1;
}
```
Here's how the algorithm works:

1. Call `rand7()` two times and treat the two values as (row, column) indices in a 7x7 grid (so each value is 1 to 7). This gives us 49 possible values, forming a uniform distribution.

2. We actually convert the two values `a` and `b` (from 1 to 7) into a single value, `result = (a - 1) * 7 + b`. This will give us a value between 1 and 49 (inclusive).

3. If the `result` is greater than 40, we reject this value (and try again) since this is larger than what we can map to the range 1 to 10. We will use the value `result` to represent the range [1, 10] by taking the modulus of 10 and adding 1 (i.e. `result % 10 + 1`).

4. This way, we ensure a uniformly random value between 1 to 10. Since some values are rejected, the expected number of calls to rand7() is 2.4 (the probability of a value being accepted is 40/49, so expected calls are 2/(40/49)).

5. The number of calls to rand7() is optimized in this approach, minimizing it to 2 calls on average.

## A solution in C++

```cpp
int rand7(); // Provided API

int rand10() {
    int result;
    do {
        result = (rand7() - 1) * 7 + rand7();
    } while (result > 40);
    return result % 10 + 1;
}
```
Here's how the algorithm works:

1. Call `rand7()` two times and treat the two values as (row, column) indices in a 7x7 grid (so each value is 1 to 7). This gives us 49 possible values, forming a uniform distribution.

2. We actually convert the two values `a` and `b` (from 1 to 7) into a single value, `result = (a - 1) * 7 + b`. This will give us a value between 1 and 49 (inclusive).

3. If the `result` is greater than 40, we reject this value (and try again) since this is larger than what we can map to the range 1 to 10. We will use the value `result` to represent the range [1, 10] by taking the modulus of 10 and adding 1 (i.e. `result % 10 + 1`).

4. This way, we ensure a uniformly random value between 1 to 10. Since some values are rejected, the expected number of calls to rand7() is 2.4 (the probability of a value being accepted is 40/49, so expected calls are 2/(40/49)).

5. The number of calls to rand7() is optimized in this approach, minimizing it to 2 calls on average.

## A solution in Python

```python
def rand7():
    pass  # Provided API

def rand10():
    result = None
    while True:
        result = (rand7() - 1) * 7 + rand7()
        if result <= 40:
            break
    return result % 10 + 1
```
Here's how the algorithm works:

1. Call `rand7()` two times and treat the two values as (row, column) indices in a 7x7 grid (so each value is 1 to 7). This gives us 49 possible values, forming a uniform distribution.

2. We actually convert the two values `a` and `b` (from 1 to 7) into a single value, `result = (a - 1) * 7 + b`. This will give us a value between 1 and 49 (inclusive).

3. If the `result` is greater than 40, we reject this value (and try again) since this is larger than what we can map to the range 1 to 10. We will use the value `result` to represent the range [1, 10] by taking the modulus of 10 and adding 1 (i.e. `result % 10 + 1`).

4. This way, we ensure a uniformly random value between 1 to 10. Since some values are rejected, the expected number of calls to rand7() is 2.4 (the probability of a value being accepted is 40/49, so expected calls are 2/(40/49)).

5. The number of calls to rand7() is optimized in this approach, minimizing it to 2 calls on average.

## A solution in Javascript

```javascript
function rand7() ; // Provided API

function rand10() {
    let result;
    do {
        result = (rand7() - 1) * 7 + rand7();
    } while (result > 40);
    return result % 10 + 1;
}
```
Here's how the algorithm works:

1. Call `rand7()` two times and treat the two values as (row, column) indices in a 7x7 grid (so each value is 1 to 7). This gives us 49 possible values, forming a uniform distribution.

2. We actually convert the two values `a` and `b` (from 1 to 7) into a single value, `result = (a - 1) * 7 + b`. This will give us a value between 1 and 49 (inclusive).

3. If the `result` is greater than 40, we reject this value (and try again) since this is larger than what we can map to the range 1 to 10. We will use the value `result` to represent the range [1, 10] by taking the modulus of 10 and adding 1 (i.e. `result % 10 + 1`).

4. This way, we ensure a uniformly random value between 1 to 10. Since some values are rejected, the expected number of calls to rand7() is 2.4 (the probability of a value being accepted is 40/49, so expected calls are 2/(40/49)).

5. The number of calls to rand7() is optimized in this approach, minimizing it to 2 calls on average.


# Encode String with Shortest Length

- slug: encode-string-with-shortest-length
- difficulty: Hard

Given a string `s`, encode the string such that its encoded length is the shortest.

The encoding rule is: `k[encoded_string]`, where the `encoded_string` inside the square brackets is being repeated exactly `k` times. `k` should be a positive integer.

If an encoding process does not make the string shorter, then do not encode it. If there are several solutions, return **any of them**.

**Example 1:**

**Input:** s =  "aaa "
**Output:**  "aaa "
**Explanation:** There is no way to encode it such that it is shorter than the input string, so we do not encode it.

**Example 2:**

**Input:** s =  "aaaaa "
**Output:**  "5\[a\] "
**Explanation:**  "5\[a\] " is shorter than  "aaaaa " by 1 character.

**Example 3:**

**Input:** s =  "aaaaaaaaaa "
**Output:**  "10\[a\] "
**Explanation:**  "a9\[a\] " or  "9\[a\]a " are also valid solutions, both of them have the same length = 5, which is the same as  "10\[a\] ".

**Constraints:**

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

## A solution in Java

```java
String encode(String s) {
    int n = s.length();
    for (int i = n / 2; i > 0; i--) {
        if (n % i == 0) {
            int reps = n / i;
            String sub = s.substring(0, i);
            StringBuilder composed = new StringBuilder();
            for (int j = 0; j < reps; j++) {
                composed.append(sub);
            }
            if (s.equals(composed.toString())) {
                return reps + "[" + sub + "]";
            }
        }
    }
    return s;
}
```
The algorithm works by iteratively checking substrings of the input string `s` from the largest possible ones (half of the input string's length) to the smallest (single characters). To find the shortest possible encoding, the algorithm calculates the number of repetitions of the current substring and checks if the input string can be entirely composed of that substring. If a suitable substring is found, it returns the encoded string in the format _k[encoded_string]_, where _k_ is the number of repetitions, otherwise it returns the original input string.

## A solution in C++

```cpp
std::string encode(std::string s) {
    int n = s.length();
    for (int i = n / 2; i > 0; i--) {
        if (n % i == 0) {
            int reps = n / i;
            std::string sub = s.substr(0, i);
            std::string composed = "";
            for (int j = 0; j < reps; j++) {
                composed += sub;
            }
            if (s == composed) {
                return std::to_string(reps) + "[" + sub + "]";
            }
        }
    }
    return s;
}
```
The algorithm works by iteratively checking substrings of the input string `s` from the largest possible ones (half of the input string's length) to the smallest (single characters). To find the shortest possible encoding, the algorithm calculates the number of repetitions of the current substring and checks if the input string can be entirely composed of that substring. If a suitable substring is found, it returns the encoded string in the format _k[encoded_string]_, where _k_ is the number of repetitions, otherwise it returns the original input string.

## A solution in Python

```python
def encode(s: str) -> str:
    n = len(s)
    for i in range(n // 2, 0, -1):
        if n % i == 0:
            reps = n // i
            sub = s[:i]
            composed = sub * reps
            if s == composed:
                return f"{reps}[{sub}]"
    return s
```
The algorithm works by iteratively checking substrings of the input string `s` from the largest possible ones (half of the input string's length) to the smallest (single characters). To find the shortest possible encoding, the algorithm calculates the number of repetitions of the current substring and checks if the input string can be entirely composed of that substring. If a suitable substring is found, it returns the encoded string in the format _k[encoded_string]_, where _k_ is the number of repetitions, otherwise it returns the original input string.

## A solution in Javascript

```javascript
function encode(s) {
    const n = s.length;
    for (let i = Math.floor(n / 2); i > 0; i--) {
        if (n % i === 0) {
            const reps = n / i;
            const sub = s.slice(0, i);
            let composed = "";
            for (let j = 0; j < reps; j++) {
                composed += sub;
            }
            if (s === composed) {
                return `${reps}[${sub}]`;
            }
        }
    }
    return s;
}
```
The algorithm works by iteratively checking substrings of the input string `s` from the largest possible ones (half of the input string's length) to the smallest (single characters). To find the shortest possible encoding, the algorithm calculates the number of repetitions of the current substring and checks if the input string can be entirely composed of that substring. If a suitable substring is found, it returns the encoded string in the format _k[encoded_string]_, where _k_ is the number of repetitions, otherwise it returns the original input string.


# Concatenated Words

- slug: concatenated-words
- difficulty: Hard

Given an array of strings `words` (**without duplicates**), return _all the **concatenated words** in the given list of_ `words`.

A **concatenated word** is defined as a string that is comprised entirely of at least two shorter words (not necesssarily distinct) in the given array.

**Example 1:**

**Input:** words = \[ "cat ", "cats ", "catsdogcats ", "dog ", "dogcatsdog ", "hippopotamuses ", "rat ", "ratcatdogcat "\]
**Output:** \[ "catsdogcats ", "dogcatsdog ", "ratcatdogcat "\]
**Explanation:**  "catsdogcats " can be concatenated by  "cats ",  "dog " and  "cats ";
 "dogcatsdog " can be concatenated by  "dog ",  "cats " and  "dog ";
 "ratcatdogcat " can be concatenated by  "rat ",  "cat ",  "dog " and  "cat ".

**Example 2:**

**Input:** words = \[ "cat ", "dog ", "catdog "\]
**Output:** \[ "catdog "\]

**Constraints:**

*   `1 <= words.length <= 104`
*   `1 <= words[i].length <= 30`
*   `words[i]` consists of only lowercase English letters.
*   All the strings of `words` are **unique**.
*   `1 <= sum(words[i].length) <= 105`

## A solution in Java

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

public class Solution {
    public boolean isConcatenated(String word, Set<String> wordDict) {
        int n = word.length();
        boolean[] dp = new boolean[n + 1];
        dp[0] = true;

        for (int i = 1; i <= n; ++i) {
            for (int j = 0; j < i; ++j) {
                if (dp[j] && wordDict.contains(word.substring(j, i))) {
                    dp[i] = true;
                    break;
                }
            }
        }
        return dp[n];
    }

    public List<String> findAllConcatenatedWords(String[] words) {
        Set<String> wordDict = new HashSet<>();
        for (String word : words) {
            wordDict.add(word);
        }

        List<String> result = new ArrayList<>();
        for (String word : words) {
            if (isConcatenated(word, wordDict)) {
                result.add(word);
            }
        }

        return result;
    }
}
```
The algorithm uses dynamic programming to determine if a given word is a concatenated word. The function `isConcatenated` checks if a word can be formed by concatenating two or more words from the input array. It iterates through the characters of the word and uses a boolean array `dp` to keep track of whether or not the substring from the start of the word up to a certain index can be formed by concatenating the words from the input array.

Then, the main function `findAllConcatenatedWords` iterates through each word in the array, and if the word is a concatenated word, adds it to the result list/array.

The four implementations in C++, Java, Python, and JavaScript use the same algorithm described above but are adapted to their respective language syntax and standard libraries.

## A solution in C++

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

bool isConcatenated(const string& word, unordered_set<string>& wordDict) {
    int n = word.size();
    vector<bool> dp(n + 1, false);
    dp[0] = true;

    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j < i; ++j) {
            if (dp[j] && wordDict.count(word.substr(j, i - j))) {
                dp[i] = true;
                break;
            }
        }
    }
    return dp[n];
}

vector<string> findAllConcatenatedWords(vector<string>& words) {
    unordered_set<string> wordDict(words.begin(), words.end());
    vector<string> result;

    for (const string& word : words) {
        if (isConcatenated(word, wordDict)) {
            result.push_back(word);
        }
    }

    return result;
}
```
The algorithm uses dynamic programming to determine if a given word is a concatenated word. The function `isConcatenated` checks if a word can be formed by concatenating two or more words from the input array. It iterates through the characters of the word and uses a boolean array `dp` to keep track of whether or not the substring from the start of the word up to a certain index can be formed by concatenating the words from the input array.

Then, the main function `findAllConcatenatedWords` iterates through each word in the array, and if the word is a concatenated word, adds it to the result list/array.

The four implementations in C++, Java, Python, and JavaScript use the same algorithm described above but are adapted to their respective language syntax and standard libraries.

## A solution in Python

```python
def is_concatenated(word, word_dict):
    n = len(word)
    dp = [False] * (n + 1)
    dp[0] = True

    for i in range(1, n + 1):
        for j in range(i):
            if dp[j] and word[j:i] in word_dict:
                dp[i] = True
                break

    return dp[n]

def find_all_concatenated_words(words):
    word_dict = set(words)
    result = []

    for word in words:
        if is_concatenated(word, word_dict):
            result.append(word)

    return result
```
The algorithm uses dynamic programming to determine if a given word is a concatenated word. The function `isConcatenated` checks if a word can be formed by concatenating two or more words from the input array. It iterates through the characters of the word and uses a boolean array `dp` to keep track of whether or not the substring from the start of the word up to a certain index can be formed by concatenating the words from the input array.

Then, the main function `findAllConcatenatedWords` iterates through each word in the array, and if the word is a concatenated word, adds it to the result list/array.

The four implementations in C++, Java, Python, and JavaScript use the same algorithm described above but are adapted to their respective language syntax and standard libraries.

## A solution in Javascript

```javascript
function isConcatenated(word, wordDict) {
    const n = word.length;
    const dp = Array(n + 1).fill(false);
    dp[0] = true;

    for (let i = 1; i <= n; ++i) {
        for (let j = 0; j < i; ++j) {
            if (dp[j] && wordDict.has(word.substring(j, i))) {
                dp[i] = true;
                break;
            }
        }
    }
    return dp[n];
}

function findAllConcatenatedWords(words) {
    const wordDict = new Set(words);
    const result = [];

    for (const word of words) {
        if (isConcatenated(word, wordDict)) {
            result.push(word);
        }
    }

    return result;
}
```
The algorithm uses dynamic programming to determine if a given word is a concatenated word. The function `isConcatenated` checks if a word can be formed by concatenating two or more words from the input array. It iterates through the characters of the word and uses a boolean array `dp` to keep track of whether or not the substring from the start of the word up to a certain index can be formed by concatenating the words from the input array.

Then, the main function `findAllConcatenatedWords` iterates through each word in the array, and if the word is a concatenated word, adds it to the result list/array.

The four implementations in C++, Java, Python, and JavaScript use the same algorithm described above but are adapted to their respective language syntax and standard libraries.


# Matchsticks to Square

- slug: matchsticks-to-square
- difficulty: Medium

You are given an integer array `matchsticks` where `matchsticks[i]` is the length of the `ith` matchstick. You want to use **all the matchsticks** to make one square. You **should not break** any stick, but you can link them up, and each matchstick must be used **exactly one time**.

Return `true` if you can make this square and `false` otherwise.

**Example 1:**

**Input:** matchsticks = \[1,1,2,2,2\]
**Output:** true
**Explanation:** You can form a square with length 2, one side of the square came two sticks with length 1.

**Example 2:**

**Input:** matchsticks = \[3,3,3,3,4\]
**Output:** false
**Explanation:** You cannot find a way to form a square with all the matchsticks.

**Constraints:**

*   `1 <= matchsticks.length <= 15`
*   `1 <= matchsticks[i] <= 108`

## A solution in Java

```java
import java.util.Arrays;

public class Solution {
    public boolean makesquare(int[] matchsticks) {
        if (matchsticks == null || matchsticks.length < 4) return false;
        int sum = 0;
        for (int matchstick : matchsticks) sum += matchstick;
        if (sum % 4 != 0) return false;
        int target = sum / 4;
        Arrays.sort(matchsticks);
        reverse(matchsticks);
        int[] sums = new int[4];
        return dfs(matchsticks, sums, target, 0);
    }

    private void reverse(int[] nums) {
        int left = 0, right = nums.length - 1;
        while (left < right) {
            int temp = nums[left];
            nums[left] = nums[right];
            nums[right] = temp;
            left++;
            right--;
        }
    }

    private boolean dfs(int[] matchsticks, int[] sums, int target, int index) {
        if (index == matchsticks.length) {
            return sums[0] == target && sums[1] == target && sums[2] == target;
        }
        for (int i = 0; i < 4; i++) {
            if (sums[i] + matchsticks[index] <= target) {
                sums[i] += matchsticks[index];
                if (dfs(matchsticks, sums, target, index + 1)) return true;
                sums[i] -= matchsticks[index];
            }
        }
        return false;
    }
}
```
1. First, we check if there are enough matchsticks and if the total length of matchsticks can be divided by 4 to form a square. If not, return false.
2. Sort the matchsticks in descending order to traverse them from the largest to the smallest. This helps to prune branches in the depth-first search.
3. Utilize a recursive depth-first search function to try placing matchsticks i (0 <= i < 4) to form each side. If we reach the sum of all the matchsticks in a square, return true.
4. Make sure each matchstick is used exactly once and check if the assigned sums satisfy the required target.
5. If we reach the end and could not make a square, return false.

## A solution in C++

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

bool makesquare(std::vector<int>& matchsticks) {
    if (matchsticks.size() < 4) return false;
    int sum = std::accumulate(matchsticks.begin(), matchsticks.end(), 0);
    if (sum % 4) return false;
    int target = sum / 4;
    std::sort(matchsticks.rbegin(), matchsticks.rend());
    std::vector<int> sums(4, 0);
    return dfs(matchsticks, sums, target, 0);
}

bool dfs(std::vector<int>& matchsticks, std::vector<int>& sums, int target, int index) {
    if (index == matchsticks.size()) {
        return sums[0] == target && sums[1] == target && sums[2] == target;
    }
    for (int i = 0; i < 4; ++i) {
        if (sums[i] + matchsticks[index] <= target) {
            sums[i] += matchsticks[index];
            if (dfs(matchsticks, sums, target, index + 1)) return true;
            sums[i] -= matchsticks[index];
        }
    }
    return false;
}
```
1. First, we check if there are enough matchsticks and if the total length of matchsticks can be divided by 4 to form a square. If not, return false.
2. Sort the matchsticks in descending order to traverse them from the largest to the smallest. This helps to prune branches in the depth-first search.
3. Utilize a recursive depth-first search function to try placing matchsticks i (0 <= i < 4) to form each side. If we reach the sum of all the matchsticks in a square, return true.
4. Make sure each matchstick is used exactly once and check if the assigned sums satisfy the required target.
5. If we reach the end and could not make a square, return false.

## A solution in Python

```python
from itertools import chain

def makesquare(matchsticks):
    if len(matchsticks) < 4:
        return False
    total = sum(matchsticks)
    if total % 4:
        return False
    target = total // 4
    matchsticks.sort(reverse=True)
    sums = [0]*4
    return dfs(matchsticks, sums, target, 0)

def dfs(matchsticks, sums, target, index):
    if index == len(matchsticks):
        return sums[0] == target and sums[1] == target and sums[2] == target
    for i in range(4):
        if sums[i] + matchsticks[index] <= target:
            sums[i] += matchsticks[index]
            if dfs(matchsticks, sums, target, index + 1):
                return True
            sums[i] -= matchsticks[index]
    return False
```
1. First, we check if there are enough matchsticks and if the total length of matchsticks can be divided by 4 to form a square. If not, return false.
2. Sort the matchsticks in descending order to traverse them from the largest to the smallest. This helps to prune branches in the depth-first search.
3. Utilize a recursive depth-first search function to try placing matchsticks i (0 <= i < 4) to form each side. If we reach the sum of all the matchsticks in a square, return true.
4. Make sure each matchstick is used exactly once and check if the assigned sums satisfy the required target.
5. If we reach the end and could not make a square, return false.

## A solution in Javascript

```javascript
function makesquare(matchsticks) {
    if (matchsticks.length < 4) return false;
    const total = matchsticks.reduce((a, b) => a + b, 0);
    if (total % 4 !== 0) return false;
    const target = total / 4;
    matchsticks.sort((a, b) => b - a);
    const sums = [0, 0, 0, 0];
    return dfs(matchsticks, sums, target, 0);
}

function dfs(matchsticks, sums, target, index) {
    if (index === matchsticks.length) {
        return sums[0] === target && sums[1] === target && sums[2] === target;
    }
    for (let i = 0; i < 4; i++) {
        if (sums[i] + matchsticks[index] <= target) {
            sums[i] += matchsticks[index];
            if (dfs(matchsticks, sums, target, index + 1)) return true;
            sums[i] -= matchsticks[index];
        }
    }
    return false;
}
```
1. First, we check if there are enough matchsticks and if the total length of matchsticks can be divided by 4 to form a square. If not, return false.
2. Sort the matchsticks in descending order to traverse them from the largest to the smallest. This helps to prune branches in the depth-first search.
3. Utilize a recursive depth-first search function to try placing matchsticks i (0 <= i < 4) to form each side. If we reach the sum of all the matchsticks in a square, return true.
4. Make sure each matchstick is used exactly once and check if the assigned sums satisfy the required target.
5. If we reach the end and could not make a square, return false.


# Ones and Zeroes

- slug: ones-and-zeroes
- difficulty: Medium

You are given an array of binary strings `strs` and two integers `m` and `n`.

Return _the size of the largest subset of `strs` such that there are **at most**_ `m` `0`_'s and_ `n` `1`_'s in the subset_.

A set `x` is a **subset** of a set `y` if all elements of `x` are also elements of `y`.

**Example 1:**

**Input:** strs = \[ "10 ", "0001 ", "111001 ", "1 ", "0 "\], m = 5, n = 3
**Output:** 4
**Explanation:** The largest subset with at most 5 0's and 3 1's is { "10 ",  "0001 ",  "1 ",  "0 "}, so the answer is 4.
Other valid but smaller subsets include { "0001 ",  "1 "} and { "10 ",  "1 ",  "0 "}.
{ "111001 "} is an invalid subset because it contains 4 1's, greater than the maximum of 3.

**Example 2:**

**Input:** strs = \[ "10 ", "0 ", "1 "\], m = 1, n = 1
**Output:** 2
**Explanation:** The largest subset is { "0 ",  "1 "}, so the answer is 2.

**Constraints:**

*   `1 <= strs.length <= 600`
*   `1 <= strs[i].length <= 100`
*   `strs[i]` consists only of digits `'0'` and `'1'`.
*   `1 <= m, n <= 100`

## A solution in Java

```java
import java.util.Arrays;

public int findMaxForm(String[] strs, int m, int n) {
    int[][] dp = new int[m + 1][n + 1];

    for (String str: strs) {
        int ones = (int) str.chars().filter(ch -> ch == '1').count();
        int zeros = str.length() - ones;

        for (int i = m; i >= zeros; --i) {
            for (int j = n; j >= ones; --j) {
                dp[i][j] = Math.max(dp[i][j], dp[i - zeros][j - ones] + 1);
            }
        }
    }
    return dp[m][n];
}
```
1. Initialize a 2-dimensional DP table dp, where dp[i][j] represents the maximum size of a subset with i 0's and j 1's.
2. Loop through each string in strs.
3. Count the number of 0's (zeros) and 1's (ones) in each string.
4. Iterate backward through the DP table, updating dp[i][j] to the maximum of its current value and dp[i - zeros][j - ones] + 1. This is because a string with zeros 0's and ones 1's will be included in the subset if i 0's and j 1's are available.
5. After processing all the strings, return dp[m][n], which represents the size of the largest subset with at most m 0's and n 1's.

## A solution in C++

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

int findMaxForm(std::vector<std::string>& strs, int m, int n) {
    std::vector<std::vector<int>> dp(m + 1, std::vector<int>(n + 1));

    for (const std::string& str: strs) {
        int ones = std::count(str.begin(), str.end(), '1');
        int zeros = str.length() - ones;

        for (int i = m; i >= zeros; --i) {
            for (int j = n; j >= ones; --j) {
                dp[i][j] = std::max(dp[i][j], dp[i - zeros][j - ones] + 1);
            }
        }
    }
    return dp[m][n];
}
```
1. Initialize a 2-dimensional DP table dp, where dp[i][j] represents the maximum size of a subset with i 0's and j 1's.
2. Loop through each string in strs.
3. Count the number of 0's (zeros) and 1's (ones) in each string.
4. Iterate backward through the DP table, updating dp[i][j] to the maximum of its current value and dp[i - zeros][j - ones] + 1. This is because a string with zeros 0's and ones 1's will be included in the subset if i 0's and j 1's are available.
5. After processing all the strings, return dp[m][n], which represents the size of the largest subset with at most m 0's and n 1's.

## A solution in Python

```python
def findMaxForm(strs, m, n):
    dp = [[0] * (n + 1) for _ in range(m + 1)]

    for s in strs:
        ones = s.count('1')
        zeros = len(s) - ones

        for i in range(m, zeros - 1, -1):
            for j in range(n, ones - 1, -1):
                dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1)

    return dp[m][n]
```
1. Initialize a 2-dimensional DP table dp, where dp[i][j] represents the maximum size of a subset with i 0's and j 1's.
2. Loop through each string in strs.
3. Count the number of 0's (zeros) and 1's (ones) in each string.
4. Iterate backward through the DP table, updating dp[i][j] to the maximum of its current value and dp[i - zeros][j - ones] + 1. This is because a string with zeros 0's and ones 1's will be included in the subset if i 0's and j 1's are available.
5. After processing all the strings, return dp[m][n], which represents the size of the largest subset with at most m 0's and n 1's.

## A solution in Javascript

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

    for (const str of strs) {
        const ones = str.split('').filter(ch => ch === '1').length;
        const zeros = str.length - ones;

        for (let i = m; i >= zeros; --i) {
            for (let j = n; j >= ones; --j) {
                dp[i][j] = Math.max(dp[i][j], dp[i - zeros][j - ones] + 1);
            }
        }
    }
    return dp[m][n];
}
```
1. Initialize a 2-dimensional DP table dp, where dp[i][j] represents the maximum size of a subset with i 0's and j 1's.
2. Loop through each string in strs.
3. Count the number of 0's (zeros) and 1's (ones) in each string.
4. Iterate backward through the DP table, updating dp[i][j] to the maximum of its current value and dp[i - zeros][j - ones] + 1. This is because a string with zeros 0's and ones 1's will be included in the subset if i 0's and j 1's are available.
5. After processing all the strings, return dp[m][n], which represents the size of the largest subset with at most m 0's and n 1's.


# Heaters

- slug: heaters
- difficulty: Medium

Winter is coming! During the contest, your first job is to design a standard heater with a fixed warm radius to warm all the houses.

Every house can be warmed, as long as the house is within the heater's warm radius range.

Given the positions of `houses` and `heaters` on a horizontal line, return _the minimum radius standard of heaters so that those heaters could cover all houses._

**Notice** that all the `heaters` follow your radius standard, and the warm radius will the same.

**Example 1:**

**Input:** houses = \[1,2,3\], heaters = \[2\]
**Output:** 1
**Explanation:** The only heater was placed in the position 2, and if we use the radius 1 standard, then all the houses can be warmed.

**Example 2:**

**Input:** houses = \[1,2,3,4\], heaters = \[1,4\]
**Output:** 1
**Explanation:** The two heater was placed in the position 1 and 4. We need to use radius 1 standard, then all the houses can be warmed.

**Example 3:**

**Input:** houses = \[1,5\], heaters = \[2\]
**Output:** 3

**Constraints:**

*   `1 <= houses.length, heaters.length <= 3 * 104`
*   `1 <= houses[i], heaters[i] <= 109`

## A solution in Java

```java
public int findRadius(int[] houses, int[] heaters) {
    Arrays.sort(houses);
    Arrays.sort(heaters);
    int result = 0;
    int i = 0;

    for (int house : houses) {
        while (i < heaters.length - 1 &&
               Math.abs(heaters[i + 1] - house) <= Math.abs(heaters[i] - house)) {
            i++;
        }
        result = Math.max(result, Math.abs(heaters[i] - house));
    }
    return result;
}
```
1. Sort both the arrays `houses` and `heaters`.
2. Initialize two variables `result` and `i` to store the minimum required radius and the current heater index, respectively.
3. Iterate through the `houses` array.
   1. Using a nested while loop:
   2. Increment `i` until the current heater is closer to the current house than the next heater.
   3. Update `result` with the maximum distance between a house and a heater we have seen so far.
4. After iterating through all houses, `result` contains the minimum radius for the heaters to cover all houses.

## A solution in C++

```cpp
int findRadius(vector<int>& houses, vector<int>& heaters) {
    sort(houses.begin(), houses.end());
    sort(heaters.begin(), heaters.end());

    int result = 0;
    int i = 0;

    for (int house : houses) {
        while (i < heaters.size() - 1 &&
               abs(heaters[i + 1] - house) <= abs(heaters[i] - house)) {
            i++;
        }
        result = max(result, abs(heaters[i] - house));
    }
    return result;
}
```
1. Sort both the arrays `houses` and `heaters`.
2. Initialize two variables `result` and `i` to store the minimum required radius and the current heater index, respectively.
3. Iterate through the `houses` array.
   1. Using a nested while loop:
   2. Increment `i` until the current heater is closer to the current house than the next heater.
   3. Update `result` with the maximum distance between a house and a heater we have seen so far.
4. After iterating through all houses, `result` contains the minimum radius for the heaters to cover all houses.

## A solution in Python

```python
def findRadius(houses, heaters):
    houses.sort()
    heaters.sort()
    result, i = 0, 0

    for house in houses:
        while i < len(heaters) - 1 and abs(heaters[i + 1] - house) <= abs(heaters[i] - house):
            i += 1
        result = max(result, abs(heaters[i] - house))

    return result
```
1. Sort both the arrays `houses` and `heaters`.
2. Initialize two variables `result` and `i` to store the minimum required radius and the current heater index, respectively.
3. Iterate through the `houses` array.
   1. Using a nested while loop:
   2. Increment `i` until the current heater is closer to the current house than the next heater.
   3. Update `result` with the maximum distance between a house and a heater we have seen so far.
4. After iterating through all houses, `result` contains the minimum radius for the heaters to cover all houses.

## A solution in Javascript

```javascript
function findRadius(houses, heaters) {
    houses.sort((a, b) => a - b);
    heaters.sort((a, b) => a - b);
    let result = 0;
    let i = 0;

    for (const house of houses) {
        while (i < heaters.length - 1 &&
               Math.abs(heaters[i + 1] - house) <= Math.abs(heaters[i] - house)) {
            i++;
        }
        result = Math.max(result, Math.abs(heaters[i] - house));
    }
    return result;
}
```
1. Sort both the arrays `houses` and `heaters`.
2. Initialize two variables `result` and `i` to store the minimum required radius and the current heater index, respectively.
3. Iterate through the `houses` array.
   1. Using a nested while loop:
   2. Increment `i` until the current heater is closer to the current house than the next heater.
   3. Update `result` with the maximum distance between a house and a heater we have seen so far.
4. After iterating through all houses, `result` contains the minimum radius for the heaters to cover all houses.


# Number Complement

- slug: number-complement
- difficulty: Easy

The **complement** of an integer is the integer you get when you flip all the `0`'s to `1`'s and all the `1`'s to `0`'s in its binary representation.

*   For example, The integer `5` is `"101 "` in binary and its **complement** is `"010 "` which is the integer `2`.

Given an integer `num`, return _its complement_.

**Example 1:**

**Input:** num = 5
**Output:** 2
**Explanation:** The binary representation of 5 is 101 (no leading zero bits), and its complement is 010. So you need to output 2.

**Example 2:**

**Input:** num = 1
**Output:** 0
**Explanation:** The binary representation of 1 is 1 (no leading zero bits), and its complement is 0. So you need to output 0.

**Constraints:**

*   `1 <= num < 231`

**Note:** This question is the same as 1009: [https://leetcode.com/problems/complement-of-base-10-integer/](https://leetcode.com/problems/complement-of-base-10-integer/)

## A solution in Java

```java
public int findComplement(int num) {
    int bitLength = 0;
    int mask = num;
    while (mask > 0) {
        mask >>= 1;
        bitLength++;
    }
    int allOnes = (1 << bitLength) - 1;

    return num ^ allOnes;
}
```
First, we calculate the number of bits in the binary representation of the input integer `num`. We do this by consecutively right-shifting the number (bitwise operation) and counting the iterations until the number becomes 0. This gives us the length of the binary representation.

Once we have the length, we create a bitmask of the same length with all bits set to 1 (for example, if the length is 3, the bitmask would be 111 in binary). To get the complement of the input integer, we then XOR (`^` operator) the number with this all-1 mask. The XOR operation returns 1 when the input bits are different and 0 when they are the same, so if we have a 0 in the input, we will get 1 and vice versa. This way, we get the complement of the original number.

Finally, we return the resulting number, which is the complement of the input integer `num`.

## A solution in C++

```cpp
int findComplement(int num) {
    int bitLength = 0;
    int mask = num;
    while (mask > 0) {
        mask >>= 1;
        bitLength++;
    }
    int allOnes = (1 << bitLength) - 1;

    return num ^ allOnes;
}
```
First, we calculate the number of bits in the binary representation of the input integer `num`. We do this by consecutively right-shifting the number (bitwise operation) and counting the iterations until the number becomes 0. This gives us the length of the binary representation.

Once we have the length, we create a bitmask of the same length with all bits set to 1 (for example, if the length is 3, the bitmask would be 111 in binary). To get the complement of the input integer, we then XOR (`^` operator) the number with this all-1 mask. The XOR operation returns 1 when the input bits are different and 0 when they are the same, so if we have a 0 in the input, we will get 1 and vice versa. This way, we get the complement of the original number.

Finally, we return the resulting number, which is the complement of the input integer `num`.

## A solution in Python

```python
def find_complement(num: int) -> int:
    bit_length = 0
    mask = num
    while mask > 0:
        mask >>= 1
        bit_length += 1
    all_ones = (1 << bit_length) - 1

    return num ^ all_ones
```
First, we calculate the number of bits in the binary representation of the input integer `num`. We do this by consecutively right-shifting the number (bitwise operation) and counting the iterations until the number becomes 0. This gives us the length of the binary representation.

Once we have the length, we create a bitmask of the same length with all bits set to 1 (for example, if the length is 3, the bitmask would be 111 in binary). To get the complement of the input integer, we then XOR (`^` operator) the number with this all-1 mask. The XOR operation returns 1 when the input bits are different and 0 when they are the same, so if we have a 0 in the input, we will get 1 and vice versa. This way, we get the complement of the original number.

Finally, we return the resulting number, which is the complement of the input integer `num`.

## A solution in Javascript

```javascript
function findComplement(num) {
    let bitLength = 0;
    let mask = num;
    while (mask > 0) {
        mask >>= 1;
        bitLength++;
    }
    const allOnes = (1 << bitLength) - 1;

    return num ^ allOnes;
}
```
First, we calculate the number of bits in the binary representation of the input integer `num`. We do this by consecutively right-shifting the number (bitwise operation) and counting the iterations until the number becomes 0. This gives us the length of the binary representation.

Once we have the length, we create a bitmask of the same length with all bits set to 1 (for example, if the length is 3, the bitmask would be 111 in binary). To get the complement of the input integer, we then XOR (`^` operator) the number with this all-1 mask. The XOR operation returns 1 when the input bits are different and 0 when they are the same, so if we have a 0 in the input, we will get 1 and vice versa. This way, we get the complement of the original number.

Finally, we return the resulting number, which is the complement of the input integer `num`.


# Total Hamming Distance

- slug: total-hamming-distance
- difficulty: Medium

The [Hamming distance](https://en.wikipedia.org/wiki/Hamming_distance) between two integers is the number of positions at which the corresponding bits are different.

Given an integer array `nums`, return _the sum of **Hamming distances** between all the pairs of the integers in_ `nums`.

**Example 1:**

**Input:** nums = \[4,14,2\]
**Output:** 6
**Explanation:** In binary representation, the 4 is 0100, 14 is 1110, and 2 is 0010 (just
showing the four bits relevant in this case).
The answer will be:
HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2) = 2 + 2 + 2 = 6.

**Example 2:**

**Input:** nums = \[4,14,4\]
**Output:** 4

**Constraints:**

*   `1 <= nums.length <= 104`
*   `0 <= nums[i] <= 109`
*   The answer for the given input will fit in a **32-bit** integer.

## A solution in Java

```java
public int totalHammingDistance(int[] nums) {
    int totalDistance = 0, n = nums.length;

    for (int i = 0; i < 32; ++i) {
        int bitCount = 0;
        for (int num : nums) {
            bitCount += (num >> i) & 1;
        }
        totalDistance += bitCount * (n - bitCount);
    }

    return totalDistance;
}
```
The algorithm iterates through the 32-bit positions of the integers. For each bit position, it counts the number of integers in the array that have a 1 at that position. Then, it calculates the Hamming distance for that bit position by multiplying the number of 1s by the number of 0s at that position. Finally, it sums up the Hamming distances for all the bit positions to find the total Hamming distance between all the pairs of integers in the array. This way, the algorithm has a linear runtime complexity with respect to the size of the input array.

## A solution in C++

```cpp
int totalHammingDistance(vector<int>& nums) {
    int total_distance = 0, n = nums.size();

    for (int i = 0; i < 32; ++i) {
        int bit_count = 0;
        for (int num : nums) {
            bit_count += (num >> i) & 1;
        }
        total_distance += bit_count * (n - bit_count);
    }

    return total_distance;
}
```
The algorithm iterates through the 32-bit positions of the integers. For each bit position, it counts the number of integers in the array that have a 1 at that position. Then, it calculates the Hamming distance for that bit position by multiplying the number of 1s by the number of 0s at that position. Finally, it sums up the Hamming distances for all the bit positions to find the total Hamming distance between all the pairs of integers in the array. This way, the algorithm has a linear runtime complexity with respect to the size of the input array.

## A solution in Python

```python
def total_hamming_distance(nums):
    total_distance = 0
    n = len(nums)

    for i in range(32):
        bit_count = sum(((num >> i) & 1) for num in nums)
        total_distance += bit_count * (n - bit_count)

    return total_distance
```
The algorithm iterates through the 32-bit positions of the integers. For each bit position, it counts the number of integers in the array that have a 1 at that position. Then, it calculates the Hamming distance for that bit position by multiplying the number of 1s by the number of 0s at that position. Finally, it sums up the Hamming distances for all the bit positions to find the total Hamming distance between all the pairs of integers in the array. This way, the algorithm has a linear runtime complexity with respect to the size of the input array.

## A solution in Javascript

```javascript
function totalHammingDistance(nums) {
    let totalDistance = 0, n = nums.length;

    for (let i = 0; i < 32; ++i) {
        let bitCount = 0;
        for (let num of nums) {
            bitCount += (num >> i) & 1;
        }
        totalDistance += bitCount * (n - bitCount);
    }

    return totalDistance;
}
```
The algorithm iterates through the 32-bit positions of the integers. For each bit position, it counts the number of integers in the array that have a 1 at that position. Then, it calculates the Hamming distance for that bit position by multiplying the number of 1s by the number of 0s at that position. Finally, it sums up the Hamming distances for all the bit positions to find the total Hamming distance between all the pairs of integers in the array. This way, the algorithm has a linear runtime complexity with respect to the size of the input array.