# String Without AAA or BBB

- slug: string-without-aaa-or-bbb
- difficulty: Medium

Given two integers `a` and `b`, return **any** string `s` such that:

*   `s` has length `a + b` and contains exactly `a` `'a'` letters, and exactly `b` `'b'` letters,
*   The substring `'aaa'` does not occur in `s`, and
*   The substring `'bbb'` does not occur in `s`.

**Example 1:**

**Input:** a = 1, b = 2
**Output:**  "abb "
**Explanation:**  "abb ",  "bab " and  "bba " are all correct answers.

**Example 2:**

**Input:** a = 4, b = 1
**Output:**  "aabaa "

**Constraints:**

*   `0 <= a, b <= 100`
*   It is guaranteed such an `s` exists for the given `a` and `b`.

## A solution in Java

```java
import java.util.*;

class Solution {
    public int removeStones(int[][] stones) {
        int n = stones.length;
        Map<Integer, Integer> row_groups = new HashMap<>();
        Map<Integer, Integer> col_groups = new HashMap<>();
        int group_count = 0;

        int[][] groups = new int[n * 2][n];
        int[] group_sizes = new int[n * 2];

        for (int i = 0; i < n; i++) {
            int x = stones[i][0], y = stones[i][1];
            int groupId_x = row_groups.computeIfAbsent(x, (key) -> group_count++);
            int groupId_y = col_groups.computeIfAbsent(y + 10001, (key) -> group_count++); // Offset by max row index

            groups[groupId_x][group_sizes[groupId_x]++] = groupId_y;
            groups[groupId_y][group_sizes[groupId_y]++] = groupId_x;
        }

        boolean[] visited = new boolean[group_count];

        int max_stones = 0;
        for (int groupId = 0; groupId < group_count; groupId++) {
            if (!visited[groupId]) {
                Stack<Integer> stack = new Stack<>();
                stack.push(groupId);
                visited[groupId] = true;
                int size = 0;

                while (!stack.isEmpty()) {
                    int curr = stack.pop();
                    size++;
                    for (int i = 0; i < group_sizes[curr]; i++) {
                        int neighbor = groups[curr][i];
                        if (!visited[neighbor]) {
                            stack.push(neighbor);
                            visited[neighbor] = true;
                        }
                    }
                }

                max_stones += size - 1;
            }
        }

        return max_stones;
    }
}
```
Each stone marked by a coordinate (x, y) on the plane is represented by two groups, one for the row and one for the column. We use the group counts as groupId in the group maps. First, we iterate through the stones and update the row and col groups.

Next, we create a graph represented by "groups". Each groupId has a list of connected groupIds. We connect the row's groupId to the column's groupId.

After constructing the graph, we perform a depth-first search (DFS) and track the connected groupId sizes. The number of stones that can be removed is the sum of connected components' sizes minus 1. This is because only (size - 1) edges connect the connected components; therefore, we can remove only (size - 1) stones without breaking the connections.

We apply the DFS in every defined language and return the max_stones which is the maximum number of stones that can be removed.

## A solution in C++

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

int removeStones(std::vector<std::vector<int>>& stones) {
    std::unordered_map<int, int> row_groups, col_groups;
    int group_count = 0;

    std::function<int(int, bool)> getGroupId = [&](int idx, bool isRow) -> int {
        auto& groups = isRow ? row_groups : col_groups;
        if (!groups.count(idx)) {
            groups[idx] = group_count++;
        }
        return groups[idx];
    };

    std::vector<std::vector<int>> groups(group_count);
    for (auto& [x, y] : stones) {
        int group_x = getGroupId(x, true);
        int group_y = getGroupId(10001 + y, false); // Offset by max row index
        groups[group_x].push_back(group_y);
        groups[group_y].push_back(group_x);
    }

    int max_stones = 0;
    std::vector<bool> visited(group_count);

    auto dfs = [&](int groupId, auto& dfs_ref) -> int {
        if (visited[groupId]) return 0;
        visited[groupId] = true;
        int size = 1;
        for (int neighbor : groups[groupId]) {
            size += dfs_ref(neighbor, dfs_ref);
        }
        return size;
    };

    for (int groupId = 0; groupId < group_count; groupId++) {
        max_stones += dfs(groupId, dfs) - 1;
    }

    return max_stones;
}
```
Each stone marked by a coordinate (x, y) on the plane is represented by two groups, one for the row and one for the column. We use the group counts as groupId in the group maps. First, we iterate through the stones and update the row and col groups.

Next, we create a graph represented by "groups". Each groupId has a list of connected groupIds. We connect the row's groupId to the column's groupId.

After constructing the graph, we perform a depth-first search (DFS) and track the connected groupId sizes. The number of stones that can be removed is the sum of connected components' sizes minus 1. This is because only (size - 1) edges connect the connected components; therefore, we can remove only (size - 1) stones without breaking the connections.

We apply the DFS in every defined language and return the max_stones which is the maximum number of stones that can be removed.

## A solution in Python

```python
from collections import defaultdict

def removeStones(stones):
    row_groups = defaultdict(int)
    col_groups = defaultdict(int)
    group_count = 0

    groups = defaultdict(list)

    for x, y in stones:
        if x not in row_groups:
            row_groups[x] = group_count
            group_count += 1
        if y + 10001 not in col_groups: # Offset by max row index
            col_groups[y + 10001] = group_count
            group_count += 1

        group_x, group_y = row_groups[x], col_groups[y + 10001]
        groups[group_x].append(group_y)
        groups[group_y].append(group_x)

    visited = [False] * group_count

    def dfs(groupId):
        if visited[groupId]:
            return 0
        visited[groupId] = True
        size = 1
        for neighbor in groups[groupId]:
            size += dfs(neighbor)
        return size

    max_stones = 0
    for groupId in range(group_count):
        max_stones += dfs(groupId) - 1

    return max_stones
```
Each stone marked by a coordinate (x, y) on the plane is represented by two groups, one for the row and one for the column. We use the group counts as groupId in the group maps. First, we iterate through the stones and update the row and col groups.

Next, we create a graph represented by "groups". Each groupId has a list of connected groupIds. We connect the row's groupId to the column's groupId.

After constructing the graph, we perform a depth-first search (DFS) and track the connected groupId sizes. The number of stones that can be removed is the sum of connected components' sizes minus 1. This is because only (size - 1) edges connect the connected components; therefore, we can remove only (size - 1) stones without breaking the connections.

We apply the DFS in every defined language and return the max_stones which is the maximum number of stones that can be removed.

## A solution in Javascript

```javascript
function removeStones(stones) {
    let row_groups = new Map(),
        col_groups = new Map(),
        groups = new Map(),
        group_count = 0;

    for (const [x, y] of stones) {
        if (!row_groups.has(x)) {
            row_groups.set(x, group_count++);
        }
        if (!col_groups.has(y + 10001)) { // Offset by max row index
            col_groups.set(y + 10001, group_count++);
        }
        let group_x = row_groups.get(x),
            group_y = col_groups.get(y + 10001);

        if (!groups.has(group_x)) {
            groups.set(group_x, []);
        }
        if (!groups.has(group_y)) {
            groups.set(group_y, []);
        }
        groups.get(group_x).push(group_y);
        groups.get(group_y).push(group_x);
    }

    let visited = new Array(group_count).fill(false);

    function dfs(groupId) {
        if (visited[groupId]) {
            return 0;
        }
        visited[groupId] = true;
        let size = 1;

        for (const neighbor of groups.get(groupId)) {
            size += dfs(neighbor);
        }

        return size;
    }

    let max_stones = 0;
    for (let groupId = 0; groupId < group_count; groupId++) {
        max_stones += dfs(groupId) - 1;
    }

    return max_stones;
}
```
Each stone marked by a coordinate (x, y) on the plane is represented by two groups, one for the row and one for the column. We use the group counts as groupId in the group maps. First, we iterate through the stones and update the row and col groups.

Next, we create a graph represented by "groups". Each groupId has a list of connected groupIds. We connect the row's groupId to the column's groupId.

After constructing the graph, we perform a depth-first search (DFS) and track the connected groupId sizes. The number of stones that can be removed is the sum of connected components' sizes minus 1. This is because only (size - 1) edges connect the connected components; therefore, we can remove only (size - 1) stones without breaking the connections.

We apply the DFS in every defined language and return the max_stones which is the maximum number of stones that can be removed.


# Sum of Even Numbers After Queries

- slug: sum-of-even-numbers-after-queries
- difficulty: Medium

You are given an integer array `nums` and an array `queries` where `queries[i] = [vali, indexi]`.

For each query `i`, first, apply `nums[indexi] = nums[indexi] + vali`, then print the sum of the even values of `nums`.

Return _an integer array_ `answer` _where_ `answer[i]` _is the answer to the_ `ith` _query_.

**Example 1:**

**Input:** nums = \[1,2,3,4\], queries = \[\[1,0\],\[-3,1\],\[-4,0\],\[2,3\]\]
**Output:** \[8,6,2,4\]
**Explanation:** At the beginning, the array is \[1,2,3,4\].
After adding 1 to nums\[0\], the array is \[2,2,3,4\], and the sum of even values is 2 + 2 + 4 = 8.
After adding -3 to nums\[1\], the array is \[2,-1,3,4\], and the sum of even values is 2 + 4 = 6.
After adding -4 to nums\[0\], the array is \[-2,-1,3,4\], and the sum of even values is -2 + 4 = 2.
After adding 2 to nums\[3\], the array is \[-2,-1,3,6\], and the sum of even values is -2 + 6 = 4.

**Example 2:**

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

**Constraints:**

*   `1 <= nums.length <= 104`
*   `-104 <= nums[i] <= 104`
*   `1 <= queries.length <= 104`
*   `-104 <= vali <= 104`
*   `0 <= indexi < nums.length`

## A solution in Java

```java
import java.util.Arrays;

public int bagOfTokensScore(int[] tokens, int power) {
    Arrays.sort(tokens);
    int score = 0, maxScore = 0;
    int left = 0, right = tokens.length - 1;

    while (left <= right) {
        if (power >= tokens[left]) {
            power -= tokens[left++];
            score++;
            maxScore = Math.max(maxScore, score);
        } else if (score > 0) {
            power += tokens[right--];
            score--;
        } else {
            break;
        }
    }
    return maxScore;
}
```
1. Sort the `tokens` array in ascending order.
2. Initialize the score and maxScore to 0.
3. Initialize two pointers, left and right, left starting at the beginning of the array (0), and right at the end of the array (tokens.length - 1).
4. While left <= right:
   a. If the power is greater or equal to tokens[left], subtract tokens[left] from the power, increment the left pointer, and increment the score. Update maxScore with the maximum value of score and maxScore.
   b. If the score is greater than 0 but the power is insufficient to play tokens[left], we can sacrifice a previously gained point to play tokens[right] and regain power. Add tokens[right] to power, decrement the right pointer, and decrement the score.
   c. If we can't play the tokens[left] and the score is 0, break the loop since there are no more possible moves to maximize the score.
5. Return the maxScore.

## A solution in C++

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

int bagOfTokensScore(std::vector<int>& tokens, int power) {
    std::sort(tokens.begin(), tokens.end());
    int score = 0, maxScore = 0;
    int left = 0, right = tokens.size() - 1;

    while (left <= right) {
        if (power >= tokens[left]) {
            power -= tokens[left++];
            score++;
            maxScore = std::max(maxScore, score);
        } else if (score > 0) {
            power += tokens[right--];
            score--;
        } else {
            break;
        }
    }
    return maxScore;
}
```
1. Sort the `tokens` array in ascending order.
2. Initialize the score and maxScore to 0.
3. Initialize two pointers, left and right, left starting at the beginning of the array (0), and right at the end of the array (tokens.length - 1).
4. While left <= right:
   a. If the power is greater or equal to tokens[left], subtract tokens[left] from the power, increment the left pointer, and increment the score. Update maxScore with the maximum value of score and maxScore.
   b. If the score is greater than 0 but the power is insufficient to play tokens[left], we can sacrifice a previously gained point to play tokens[right] and regain power. Add tokens[right] to power, decrement the right pointer, and decrement the score.
   c. If we can't play the tokens[left] and the score is 0, break the loop since there are no more possible moves to maximize the score.
5. Return the maxScore.

## A solution in Python

```python
def bag_of_tokens_score(tokens, power):
    tokens.sort()
    max_score = score = 0
    left, right = 0, len(tokens) - 1

    while left <= right:
        if power >= tokens[left]:
            power -= tokens[left]
            left += 1
            score += 1
            max_score = max(max_score, score)
        elif score > 0:
            power += tokens[right]
            right -= 1
            score -= 1
        else:
            break

    return max_score
```
1. Sort the `tokens` array in ascending order.
2. Initialize the score and maxScore to 0.
3. Initialize two pointers, left and right, left starting at the beginning of the array (0), and right at the end of the array (tokens.length - 1).
4. While left <= right:
   a. If the power is greater or equal to tokens[left], subtract tokens[left] from the power, increment the left pointer, and increment the score. Update maxScore with the maximum value of score and maxScore.
   b. If the score is greater than 0 but the power is insufficient to play tokens[left], we can sacrifice a previously gained point to play tokens[right] and regain power. Add tokens[right] to power, decrement the right pointer, and decrement the score.
   c. If we can't play the tokens[left] and the score is 0, break the loop since there are no more possible moves to maximize the score.
5. Return the maxScore.

## A solution in Javascript

```javascript
function bagOfTokensScore(tokens, power) {
    tokens.sort((a, b) => a - b);
    let maxScore = 0, score = 0;
    let left = 0, right = tokens.length - 1;

    while (left <= right) {
        if (power >= tokens[left]) {
            power -= tokens[left++];
            score++;
            maxScore = Math.max(maxScore, score);
        } else if (score > 0) {
            power += tokens[right--];
            score--;
        } else {
            break;
        }
    }

    return maxScore;
}
```
1. Sort the `tokens` array in ascending order.
2. Initialize the score and maxScore to 0.
3. Initialize two pointers, left and right, left starting at the beginning of the array (0), and right at the end of the array (tokens.length - 1).
4. While left <= right:
   a. If the power is greater or equal to tokens[left], subtract tokens[left] from the power, increment the left pointer, and increment the score. Update maxScore with the maximum value of score and maxScore.
   b. If the score is greater than 0 but the power is insufficient to play tokens[left], we can sacrifice a previously gained point to play tokens[right] and regain power. Add tokens[right] to power, decrement the right pointer, and decrement the score.
   c. If we can't play the tokens[left] and the score is 0, break the loop since there are no more possible moves to maximize the score.
5. Return the maxScore.


# Interval List Intersections

- slug: interval-list-intersections
- difficulty: Medium

You are given two lists of closed intervals, `firstList` and `secondList`, where `firstList[i] = [starti, endi]` and `secondList[j] = [startj, endj]`. Each list of intervals is pairwise **disjoint** and in **sorted order**.

Return _the intersection of these two interval lists_.

A **closed interval** `[a, b]` (with `a <= b`) denotes the set of real numbers `x` with `a <= x <= b`.

The **intersection** of two closed intervals is a set of real numbers that are either empty or represented as a closed interval. For example, the intersection of `[1, 3]` and `[2, 4]` is `[2, 3]`.

**Example 1:**

**Input:** firstList = \[\[0,2\],\[5,10\],\[13,23\],\[24,25\]\], secondList = \[\[1,5\],\[8,12\],\[15,24\],\[25,26\]\]
**Output:** \[\[1,2\],\[5,5\],\[8,10\],\[15,23\],\[24,24\],\[25,25\]\]

**Example 2:**

**Input:** firstList = \[\[1,3\],\[5,9\]\], secondList = \[\]
**Output:** \[\]

**Constraints:**

*   `0 <= firstList.length, secondList.length <= 1000`
*   `firstList.length + secondList.length >= 1`
*   `0 <= starti < endi <= 109`
*   `endi < starti+1`
*   `0 <= startj < endj <= 109`
*   `endj < startj+1`

## A solution in Java

```java
import java.util.Arrays;

public String largestTimeFromDigits(int[] A) {
    Arrays.sort(A);
    for (int i = 3; i >= 0; i--) {
        if (A[i] <= 2) {
            for (int j = 3; j >= 0; j--) {
                if ((A[i] != 2 || A[j] <= 3) && A[j] != A[i]) {
                    for (int k = 3; k >= 0; k--) {
                        if (A[k] <= 5 && A[k] != A[i] && A[k] != A[j]) {
                            int l = 6 - i - j - k;
                            return String.format("%d%d:%d%d", A[i], A[j], A[k], A[l]);
                        }
                    }
                }
            }
        }
    }
    return "";
}
```
The algorithm first tries to find all the permutations of the given array `arr`. For each permutation, it checks if this permutation can yield a valid 24-hour time format. An integer multiplication is used to extract hours and minutes from the digits.

We check if the resulting hours and minutes are valid (less than 24 for hours and less than 60 for minutes). If so, we calculate the current time and compare it with the current maximum. If the current time is greater than the current maximum time, we update our max_time variable.

Finally, we return the max_time value in "HH:MM" format. If no valid time is found, we return an empty string.

## A solution in C++

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

std::string largestTimeFromDigits(std::vector<int>& arr) {
    std::sort(arr.begin(), arr.end(), std::greater<>());
    do {
        if ((arr[0] < 3 || (arr[0] == 2 && arr[1] < 4)) && arr[2] < 6){
            return std::to_string(arr[0]) + std::to_string(arr[1]) + ':' + std::to_string(arr[2]) + std::to_string(arr[3]);
        }
    } while (std::prev_permutation(arr.begin(), arr.end()));
    return "";
}
```
The algorithm first tries to find all the permutations of the given array `arr`. For each permutation, it checks if this permutation can yield a valid 24-hour time format. An integer multiplication is used to extract hours and minutes from the digits.

We check if the resulting hours and minutes are valid (less than 24 for hours and less than 60 for minutes). If so, we calculate the current time and compare it with the current maximum. If the current time is greater than the current maximum time, we update our max_time variable.

Finally, we return the max_time value in "HH:MM" format. If no valid time is found, we return an empty string.

## A solution in Python

```python
from itertools import permutations

def largestTimeFromDigits(arr):
    max_time = -1
    for h, i, j, k in permutations(arr):
        hour = h * 10 + i
        minute = j * 10 + k
        time = hour * 60 + minute
        if hour < 24 and minute < 60 and time > max_time:
            max_time = time

    if max_time == -1:
        return ""
    else:
        return "{:02d}:{:02d}".format(max_time // 60, max_time % 60)
```
The algorithm first tries to find all the permutations of the given array `arr`. For each permutation, it checks if this permutation can yield a valid 24-hour time format. An integer multiplication is used to extract hours and minutes from the digits.

We check if the resulting hours and minutes are valid (less than 24 for hours and less than 60 for minutes). If so, we calculate the current time and compare it with the current maximum. If the current time is greater than the current maximum time, we update our max_time variable.

Finally, we return the max_time value in "HH:MM" format. If no valid time is found, we return an empty string.

## A solution in Javascript

```javascript
function largestTimeFromDigits(arr) {
    let maxTime = -1;
    for (let i = 0; i < 4; i++) {
        if (arr[i] > 2) continue;
        for (let j = 0; j < 4; j++) {
            if (j === i || (arr[i] === 2 && arr[j] > 3)) continue;
            for (let k = 0; k < 4; k++) {
                if (k === i || k === j || arr[k] > 5) continue;
                let l = 6 - i - j - k;
                let time = 60 * (10 * arr[i] + arr[j]) + 10 * arr[k] + arr[l];
                maxTime = Math.max(maxTime, time);
            }
        }
    }
    if (maxTime === -1) return "";
    else return `${String(Math.trunc(maxTime / 60)).padStart(2, '0')}:${String(maxTime % 60).padStart(2, '0')}`;
}
```
The algorithm first tries to find all the permutations of the given array `arr`. For each permutation, it checks if this permutation can yield a valid 24-hour time format. An integer multiplication is used to extract hours and minutes from the digits.

We check if the resulting hours and minutes are valid (less than 24 for hours and less than 60 for minutes). If so, we calculate the current time and compare it with the current maximum. If the current time is greater than the current maximum time, we update our max_time variable.

Finally, we return the max_time value in "HH:MM" format. If no valid time is found, we return an empty string.


# Vertical Order Traversal of a Binary Tree

- slug: vertical-order-traversal-of-a-binary-tree
- difficulty: Hard

Given the `root` of a binary tree, calculate the **vertical order traversal** of the binary tree.

For each node at position `(row, col)`, its left and right children will be at positions `(row + 1, col - 1)` and `(row + 1, col + 1)` respectively. The root of the tree is at `(0, 0)`.

The **vertical order traversal** of a binary tree is a list of top-to-bottom orderings for each column index starting from the leftmost column and ending on the rightmost column. There may be multiple nodes in the same row and same column. In such a case, sort these nodes by their values.

Return _the **vertical order traversal** of the binary tree_.

**Example 1:**

**Input:** root = \[3,9,20,null,null,15,7\]
**Output:** \[\[9\],\[3,15\],\[20\],\[7\]\]
**Explanation:**
Column -1: Only node 9 is in this column.
Column 0: Nodes 3 and 15 are in this column in that order from top to bottom.
Column 1: Only node 20 is in this column.
Column 2: Only node 7 is in this column.

**Example 2:**

**Input:** root = \[1,2,3,4,5,6,7\]
**Output:** \[\[4\],\[2\],\[1,5,6\],\[3\],\[7\]\]
**Explanation:**
Column -2: Only node 4 is in this column.
Column -1: Only node 2 is in this column.
Column 0: Nodes 1, 5, and 6 are in this column.
          1 is at the top, so it comes first.
          5 and 6 are at the same position (2, 0), so we order them by their value, 5 before 6.
Column 1: Only node 3 is in this column.
Column 2: Only node 7 is in this column.

**Example 3:**

**Input:** root = \[1,2,3,4,6,5,7\]
**Output:** \[\[4\],\[2\],\[1,5,6\],\[3\],\[7\]\]
**Explanation:**
This case is the exact same as example 2, but with nodes 5 and 6 swapped.
Note that the solution remains the same since 5 and 6 are in the same location and should be ordered by their values.

**Constraints:**

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

## A solution in Java

```java
import java.util.*;

public int[] deckRevealedIncreasing(int[] deck) {
    int n = deck.length;
    Queue<Integer> index = new LinkedList<>();
    for (int i = 0; i < n; i++)
        index.add(i);

    int[] ans = new int[n];
    Arrays.sort(deck);
    for (int card : deck) {
        ans[index.poll()] = card;
        if (!index.isEmpty()) {
            index.add(index.poll());
        }
    }
    return ans;
}
```
The algorithm creates an index deque (or Queue in JavaScript and Java) that stores the indices from 0 to N-1. It then sorts the given deck in increasing order. For each card in the sorted deck, it assigns the card to the answer array at the index taken from the front of the index deque. After that, while the index deque is not empty, it moves the next index at the front of the deque to the back.

This approach simulates the process of revealing cards and reordering the index deque.

## A solution in C++

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

std::vector<int> deckRevealedIncreasing(std::vector<int>& deck) {
    int n = deck.size();
    std::deque<int> index;
    for (int i = 0; i < n; ++i)
        index.push_back(i);

    std::vector<int> ans(n);
    std::sort(deck.begin(), deck.end());

    for (int card : deck) {
        ans[index.front()] = card;
        index.pop_front();
        if (!index.empty()) {
            index.push_back(index.front());
            index.pop_front();
        }
    }

    return ans;
}
```
The algorithm creates an index deque (or Queue in JavaScript and Java) that stores the indices from 0 to N-1. It then sorts the given deck in increasing order. For each card in the sorted deck, it assigns the card to the answer array at the index taken from the front of the index deque. After that, while the index deque is not empty, it moves the next index at the front of the deque to the back.

This approach simulates the process of revealing cards and reordering the index deque.

## A solution in Python

```python
from collections import deque

def deckRevealedIncreasing(deck):
    n = len(deck)
    index = deque(range(n))
    ans = [0] * n

    deck.sort()
    for card in deck:
        ans[index.popleft()] = card
        if index:
            index.append(index.popleft())

    return ans
```
The algorithm creates an index deque (or Queue in JavaScript and Java) that stores the indices from 0 to N-1. It then sorts the given deck in increasing order. For each card in the sorted deck, it assigns the card to the answer array at the index taken from the front of the index deque. After that, while the index deque is not empty, it moves the next index at the front of the deque to the back.

This approach simulates the process of revealing cards and reordering the index deque.

## A solution in Javascript

```javascript
function deckRevealedIncreasing(deck) {
    const n = deck.length;
    const index = [];
    for (let i = 0; i < n; i++) {
        index.push(i);
    }

    const ans = new Array(n);
    deck.sort((a, b) => a - b);

    for (const card of deck) {
        ans[index.shift()] = card;
        if (index.length) {
            index.push(index.shift());
        }
    }
    return ans;
}
```
The algorithm creates an index deque (or Queue in JavaScript and Java) that stores the indices from 0 to N-1. It then sorts the given deck in increasing order. For each card in the sorted deck, it assigns the card to the answer array at the index taken from the front of the index deque. After that, while the index deque is not empty, it moves the next index at the front of the deque to the back.

This approach simulates the process of revealing cards and reordering the index deque.


# Smallest String Starting From Leaf

- slug: smallest-string-starting-from-leaf
- difficulty: Medium

You are given the `root` of a binary tree where each node has a value in the range `[0, 25]` representing the letters `'a'` to `'z'`.

Return _the **lexicographically smallest** string that starts at a leaf of this tree and ends at the root_.

As a reminder, any shorter prefix of a string is **lexicographically smaller**.

*   For example, `"ab "` is lexicographically smaller than `"aba "`.

A leaf of a node is a node that has no children.

**Example 1:**

**Input:** root = \[0,1,2,3,4,3,4\]
**Output:**  "dba "

**Example 2:**

**Input:** root = \[25,1,3,1,3,0,2\]
**Output:**  "adz "

**Example 3:**

**Input:** root = \[2,2,1,null,1,0,null,0\]
**Output:**  "abc "

**Constraints:**

*   The number of nodes in the tree is in the range `[1, 8500]`.
*   `0 <= Node.val <= 25`

## A solution in Java

```java
public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

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

public boolean flipEquiv(TreeNode root1, TreeNode root2) {
    if (root1 == null && root2 == null) return true;
    if (root1 == null || root2 == null) return false;
    if (root1.val != root2.val) return false;
    return (flipEquiv(root1.left, root2.left) && flipEquiv(root1.right, root2.right)) ||
           (flipEquiv(root1.left, root2.right) && flipEquiv(root1.right, root2.left));
}
```
The algorithm works recursively by calling `flipEquiv()` for both children of each node in both trees. For each call, it checks the following conditions:
- If both nodes in the current pair are null, the subtrees are structurally equal and flip equivalent, so return true.
- If either of the nodes in the current pair is null, the subtrees have different structures, so they cannot be flip equivalent, and return false.
- If the values at the current nodes are different, the trees cannot be flip equivalent, so return false.

If none of the above conditions hold, recurse and check the two possibilities - either the nodes are already in the same flipped state, in which case both pairs of subtrees should be flip equivalent (`flipEquiv(left1, left2) && flipEquiv(right1, right2)`), or one pair of subtrees should be flipped, in which case the opposite pairs should be equivalent (`flipEquiv(left1, right2) && flipEquiv(right1, left2)`). Return the result of the OR between these two possibilities.

## A solution in C++

```cpp
#include <cstdlib>

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

bool flipEquiv(TreeNode* root1, TreeNode* root2) {
    if (root1 == nullptr && root2 == nullptr) return true;
    if (root1 == nullptr || root2 == nullptr) return false;
    if (root1->val != root2->val) return false;
    return (flipEquiv(root1->left, root2->left) && flipEquiv(root1->right, root2->right)) ||
           (flipEquiv(root1->left, root2->right) && flipEquiv(root1->right, root2->left));
}
```
The algorithm works recursively by calling `flipEquiv()` for both children of each node in both trees. For each call, it checks the following conditions:
- If both nodes in the current pair are null, the subtrees are structurally equal and flip equivalent, so return true.
- If either of the nodes in the current pair is null, the subtrees have different structures, so they cannot be flip equivalent, and return false.
- If the values at the current nodes are different, the trees cannot be flip equivalent, so return false.

If none of the above conditions hold, recurse and check the two possibilities - either the nodes are already in the same flipped state, in which case both pairs of subtrees should be flip equivalent (`flipEquiv(left1, left2) && flipEquiv(right1, right2)`), or one pair of subtrees should be flipped, in which case the opposite pairs should be equivalent (`flipEquiv(left1, right2) && flipEquiv(right1, left2)`). Return the result of the OR between these two possibilities.

## A solution in Python

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

def flipEquiv(root1, root2):
    if not root1 and not root2: return True
    if not root1 or not root2: return False
    if root1.val != root2.val: return False
    return (flipEquiv(root1.left, root2.left) and flipEquiv(root1.right, root2.right)) or \
           (flipEquiv(root1.left, root2.right) and flipEquiv(root1.right, root2.left))
```
The algorithm works recursively by calling `flipEquiv()` for both children of each node in both trees. For each call, it checks the following conditions:
- If both nodes in the current pair are null, the subtrees are structurally equal and flip equivalent, so return true.
- If either of the nodes in the current pair is null, the subtrees have different structures, so they cannot be flip equivalent, and return false.
- If the values at the current nodes are different, the trees cannot be flip equivalent, so return false.

If none of the above conditions hold, recurse and check the two possibilities - either the nodes are already in the same flipped state, in which case both pairs of subtrees should be flip equivalent (`flipEquiv(left1, left2) && flipEquiv(right1, right2)`), or one pair of subtrees should be flipped, in which case the opposite pairs should be equivalent (`flipEquiv(left1, right2) && flipEquiv(right1, left2)`). Return the result of the OR between these two possibilities.

## A solution in Javascript

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

function flipEquiv(root1, root2) {
    if (!root1 && !root2) return true;
    if (!root1 || !root2) return false;
    if (root1.val !== root2.val) return false;
    return (flipEquiv(root1.left, root2.left) && flipEquiv(root1.right, root2.right)) ||
           (flipEquiv(root1.left, root2.right) && flipEquiv(root1.right, root2.left));
}
```
The algorithm works recursively by calling `flipEquiv()` for both children of each node in both trees. For each call, it checks the following conditions:
- If both nodes in the current pair are null, the subtrees are structurally equal and flip equivalent, so return true.
- If either of the nodes in the current pair is null, the subtrees have different structures, so they cannot be flip equivalent, and return false.
- If the values at the current nodes are different, the trees cannot be flip equivalent, so return false.

If none of the above conditions hold, recurse and check the two possibilities - either the nodes are already in the same flipped state, in which case both pairs of subtrees should be flip equivalent (`flipEquiv(left1, left2) && flipEquiv(right1, right2)`), or one pair of subtrees should be flipped, in which case the opposite pairs should be equivalent (`flipEquiv(left1, right2) && flipEquiv(right1, left2)`). Return the result of the OR between these two possibilities.


# Add to Array-Form of Integer

- slug: add-to-array-form-of-integer
- difficulty: Easy

The **array-form** of an integer `num` is an array representing its digits in left to right order.

*   For example, for `num = 1321`, the array form is `[1,3,2,1]`.

Given `num`, the **array-form** of an integer, and an integer `k`, return _the **array-form** of the integer_ `num + k`.

**Example 1:**

**Input:** num = \[1,2,0,0\], k = 34
**Output:** \[1,2,3,4\]
**Explanation:** 1200 + 34 = 1234

**Example 2:**

**Input:** num = \[2,7,4\], k = 181
**Output:** \[4,5,5\]
**Explanation:** 274 + 181 = 455

**Example 3:**

**Input:** num = \[2,1,5\], k = 806
**Output:** \[1,0,2,1\]
**Explanation:** 215 + 806 = 1021

**Constraints:**

*   `1 <= num.length <= 104`
*   `0 <= num[i] <= 9`
*   `num` does not contain any leading zeros except for the zero itself.
*   `1 <= k <= 104`

## A solution in Java

```java
import java.util.*;

class Solution {
    public int largestComponentSize(int[] nums) {
        int count = 0;
        Map<Integer, Set<Integer>> graph = new HashMap<>();
        Set<Integer> visited = new HashSet<>();

        for (int num : nums) {
            int prime = primes(num);
            graph.computeIfAbsent(prime, k -> new HashSet<>()).add(num);
            if (num != prime) graph.computeIfAbsent(num, k -> new HashSet<>()).add(prime);
        }

        for (int num : nums) {
            count = Math.max(count, dfs(num, visited, graph));
        }
        return count;
    }

    private int dfs(int node, Set<Integer> visited, Map<Integer, Set<Integer>> graph) {
        if (!visited.add(node)) return 0;
        int res = 1;
        for (int neighbor : graph.getOrDefault(node, Collections.emptySet())) {
            res += dfs(neighbor, visited, graph);
        }
        return res;
    }

    private int primes(int n) {
        for (int i = 2; i * i <= n; ++i) {
            if (n % i == 0) return i;
        }
        return n;
    }
}
```
The algorithm uses the following steps:

1. For each number in `nums`, find the smallest prime divisor, which is the prime number that divides the current number.
2. Construct a graph where the nodes are numbers, and the edges are between each number and its smallest prime divisor.
3. Perform a depth-first search (DFS) on the graph for each number in `nums`, counting the size of connected components and keeping track of visited nodes.
4. Return the size of the largest connected component in the graph.

This algorithm starts by mapping each number to its smallest prime divisor, and then building a graph to model the relationships between the numbers and the divisors. The DFS traversal helps to find connected components, and the largest connected component is returned. The time complexity of this algorithm is O(N√W), where N is the size of the nums array, and W is the maximum number in it.

## A solution in C++

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

using namespace std;

int primes(int n) {
    for (int i = 2; i * i <= n; ++i) {
        if (n % i == 0) return i;
    }
    return n;
}

int largestComponentSize(vector<int>& nums) {
    int count = 0;
    unordered_map<int, unordered_set<int>> graph;
    unordered_set<int> visited;
    for (int num : nums) {
        int prime = primes(num);
        graph[prime].insert(num);
        if (num != prime) graph[num].insert(prime);
    }

    function<int(int)> dfs = [&](int node) {
        if (!visited.insert(node).second) return 0;
        int res = 1;
        for (int neighbor : graph[node]) {
            res += dfs(neighbor);
        }
        return res;
    };

    for (int num : nums) {
        count = max(count, dfs(num));
    }
    return count;
}
```
The algorithm uses the following steps:

1. For each number in `nums`, find the smallest prime divisor, which is the prime number that divides the current number.
2. Construct a graph where the nodes are numbers, and the edges are between each number and its smallest prime divisor.
3. Perform a depth-first search (DFS) on the graph for each number in `nums`, counting the size of connected components and keeping track of visited nodes.
4. Return the size of the largest connected component in the graph.

This algorithm starts by mapping each number to its smallest prime divisor, and then building a graph to model the relationships between the numbers and the divisors. The DFS traversal helps to find connected components, and the largest connected component is returned. The time complexity of this algorithm is O(N√W), where N is the size of the nums array, and W is the maximum number in it.

## A solution in Python

```python
from collections import defaultdict

def largestComponentSize(nums):
    def primes(n):
        for i in range(2, int(n**0.5) + 1):
            if n % i == 0:
                return i
        return n

    def dfs(node, visited, graph):
        if node in visited:
            return 0
        visited.add(node)
        size = 1
        for neighbor in graph[node]:
            size += dfs(neighbor, visited, graph)
        return size

    graph = defaultdict(set)
    visited = set()

    for num in nums:
        prime = primes(num)
        graph[prime].add(num)
        if num != prime:
            graph[num].add(prime)

    count = 0
    for num in nums:
        count = max(count, dfs(num, visited, graph))

    return count
```
The algorithm uses the following steps:

1. For each number in `nums`, find the smallest prime divisor, which is the prime number that divides the current number.
2. Construct a graph where the nodes are numbers, and the edges are between each number and its smallest prime divisor.
3. Perform a depth-first search (DFS) on the graph for each number in `nums`, counting the size of connected components and keeping track of visited nodes.
4. Return the size of the largest connected component in the graph.

This algorithm starts by mapping each number to its smallest prime divisor, and then building a graph to model the relationships between the numbers and the divisors. The DFS traversal helps to find connected components, and the largest connected component is returned. The time complexity of this algorithm is O(N√W), where N is the size of the nums array, and W is the maximum number in it.

## A solution in Javascript

```javascript
function largestComponentSize(nums) {
    function primes(n) {
        for (let i = 2; i * i <= n; ++i) {
            if (n % i === 0) return i;
        }
        return n;
    }

    function dfs(node, visited, graph) {
        if (visited.has(node)) return 0;
        visited.add(node);
        let size = 1;
        for (let neighbor of graph[node]) {
            size += dfs(neighbor, visited, graph);
        }
        return size;
    }

    const graph = new Map();
    const visited = new Set();

    for (const num of nums) {
        const prime = primes(num);
        if (!graph.has(prime)) graph.set(prime, new Set());
        graph.get(prime).add(num);
        if (num !== prime) {
            if (!graph.has(num)) graph.set(num, new Set());
            graph.get(num).add(prime);
        }
    }

    let count = 0;
    for (const num of nums) {
        count = Math.max(count, dfs(num, visited, graph));
    }

    return count;
}
```
The algorithm uses the following steps:

1. For each number in `nums`, find the smallest prime divisor, which is the prime number that divides the current number.
2. Construct a graph where the nodes are numbers, and the edges are between each number and its smallest prime divisor.
3. Perform a depth-first search (DFS) on the graph for each number in `nums`, counting the size of connected components and keeping track of visited nodes.
4. Return the size of the largest connected component in the graph.

This algorithm starts by mapping each number to its smallest prime divisor, and then building a graph to model the relationships between the numbers and the divisors. The DFS traversal helps to find connected components, and the largest connected component is returned. The time complexity of this algorithm is O(N√W), where N is the size of the nums array, and W is the maximum number in it.


# Satisfiability of Equality Equations

- slug: satisfiability-of-equality-equations
- difficulty: Medium

You are given an array of strings `equations` that represent relationships between variables where each string `equations[i]` is of length `4` and takes one of two different forms: `"xi==yi "` or `"xi!=yi "`.Here, `xi` and `yi` are lowercase letters (not necessarily different) that represent one-letter variable names.

Return `true` _if it is possible to assign integers to variable names so as to satisfy all the given equations, or_ `false` _otherwise_.

**Example 1:**

**Input:** equations = \[ "a==b ", "b!=a "\]
**Output:** false
**Explanation:** If we assign say, a = 1 and b = 1, then the first equation is satisfied, but not the second.
There is no way to assign the variables to satisfy both equations.

**Example 2:**

**Input:** equations = \[ "b==a ", "a==b "\]
**Output:** true
**Explanation:** We could assign a = 1 and b = 1 to satisfy both equations.

**Constraints:**

*   `1 <= equations.length <= 500`
*   `equations[i].length == 4`
*   `equations[i][0]` is a lowercase letter.
*   `equations[i][1]` is either `'='` or `'!'`.
*   `equations[i][2]` is `'='`.
*   `equations[i][3]` is a lowercase letter.

## A solution in Java

```java
public boolean isAlienSorted(String[] words, String order) {
    int[] alien_order = new int[26];
    for (int i = 0; i < 26; i++) {
        alien_order[order.charAt(i) - 'a'] = i;
    }

    for (int i = 1; i < words.length; i++) {
        for (int j = 0; j < words[i - 1].length(); j++) {
            if (j == words[i].length()) {
                return false;
            }

            if (words[i - 1].charAt(j) != words[i].charAt(j)) {
                if (alien_order[words[i - 1].charAt(j) - 'a'] > alien_order[words[i].charAt(j) - 'a']) {
                    return false;
                }
                break;
            }
        }
    }

    return true;
}
```
The algorithm first creates a mapping of the alien alphabet to their respective orders using a dictionary/map. Then, it loops through the given words, checking if they are sorted lexicographically. It compares each character of the adjacent words using the alien alphabet order. If any unordered pair is found, it returns false. If the loop completes, it returns true, indicating the words are sorted lexicographically in the alien language.

## A solution in C++

```cpp
bool isAlienSorted(vector<string>& words, string order) {
    int alien_order[26];
    for (int i = 0; i < 26; ++i) {
        alien_order[order[i] - 'a'] = i;
    }

    for (int i = 1; i < words.size(); ++i) {
        for (int j = 0; j < words[i - 1].size(); ++j) {
            if (j == words[i].size()) {
                return false;
            }

            if (words[i - 1][j] != words[i][j]) {
                if (alien_order[words[i - 1][j] - 'a'] > alien_order[words[i][j] - 'a']) {
                    return false;
                }
                break;
            }
        }
    }

    return true;
}
```
The algorithm first creates a mapping of the alien alphabet to their respective orders using a dictionary/map. Then, it loops through the given words, checking if they are sorted lexicographically. It compares each character of the adjacent words using the alien alphabet order. If any unordered pair is found, it returns false. If the loop completes, it returns true, indicating the words are sorted lexicographically in the alien language.

## A solution in Python

```python
def is_alien_sorted(words, order):
    alien_order = {char: i for i, char in enumerate(order)}

    for i in range(1, len(words)):
        for j in range(len(words[i - 1])):
            if j == len(words[i]):
                return False

            if words[i - 1][j] != words[i][j]:
                if alien_order[words[i - 1][j]] > alien_order[words[i][j]]:
                    return False
                break

    return True
```
The algorithm first creates a mapping of the alien alphabet to their respective orders using a dictionary/map. Then, it loops through the given words, checking if they are sorted lexicographically. It compares each character of the adjacent words using the alien alphabet order. If any unordered pair is found, it returns false. If the loop completes, it returns true, indicating the words are sorted lexicographically in the alien language.

## A solution in Javascript

```javascript
function isAlienSorted(words, order) {
    const alien_order = new Map();
    for (let i = 0; i < 26; i++) {
        alien_order.set(order[i], i);
    }

    for (let i = 1; i < words.length; i++) {
        for (let j = 0; j < words[i - 1].length; j++) {
            if (j === words[i].length) {
                return false;
            }

            if (words[i - 1][j] !== words[i][j]) {
                if (alien_order.get(words[i - 1][j]) > alien_order.get(words[i][j])) {
                    return false;
                }
                break;
            }
        }
    }

    return true;
}
```
The algorithm first creates a mapping of the alien alphabet to their respective orders using a dictionary/map. Then, it loops through the given words, checking if they are sorted lexicographically. It compares each character of the adjacent words using the alien alphabet order. If any unordered pair is found, it returns false. If the loop completes, it returns true, indicating the words are sorted lexicographically in the alien language.


# Broken Calculator

- slug: broken-calculator
- difficulty: Medium

There is a broken calculator that has the integer `startValue` on its display initially. In one operation, you can:

*   multiply the number on display by `2`, or
*   subtract `1` from the number on display.

Given two integers `startValue` and `target`, return _the minimum number of operations needed to display_ `target` _on the calculator_.

**Example 1:**

**Input:** startValue = 2, target = 3
**Output:** 2
**Explanation:** Use double operation and then decrement operation {2 -> 4 -> 3}.

**Example 2:**

**Input:** startValue = 5, target = 8
**Output:** 2
**Explanation:** Use decrement and then double {5 -> 4 -> 8}.

**Example 3:**

**Input:** startValue = 3, target = 10
**Output:** 3
**Explanation:** Use double, decrement and double {3 -> 6 -> 5 -> 10}.

**Constraints:**

*   `1 <= startValue, target <= 109`

## A solution in Java

```java
import java.util.Arrays;
import java.util.HashMap;

public boolean canReorderArray(int[] arr) {
    HashMap<Integer, Integer> count = new HashMap<>();
    for (int n : arr) {
        count.put(n, count.getOrDefault(n, 0) + 1);
    }
    Arrays.sort(arr);
    for (int x : arr) {
        if (count.get(x) == 0) {
            continue;
        }
        if (count.getOrDefault(2 * x, 0) > 0) {
            count.put(x, count.get(x) - 1);
            count.put(2 * x, count.get(2 * x) - 1);
        } else {
            return false;
        }
    }
    return true;
}
```
The algorithm first counts the occurrences of each number in the input array `arr` by creating a hash map called `count`. Then sort the input array in ascending order. Then we iterate through the sorted array, checking if there's a number twice as large as the current number available in the hash map. If so, we decrement the counts for both the current number and twice the current number. If not, we return false because it's not possible to reorder the array as required. If all the numbers have been processed and the condition was satisfied for all, return true.

## A solution in C++

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

bool canReorderArray(std::vector<int>& arr) {
    std::unordered_map<int, int> count;
    for (int n : arr) {
        count[n]++;
    }
    sort(arr.begin(), arr.end());
    for (int x : arr) {
        if (count[x] == 0) {
            continue;
        }
        if (count[2 * x] > 0) {
            count[x]--;
            count[2 * x]--;
        } else {
            return false;
        }
    }
    return true;
}
```
The algorithm first counts the occurrences of each number in the input array `arr` by creating a hash map called `count`. Then sort the input array in ascending order. Then we iterate through the sorted array, checking if there's a number twice as large as the current number available in the hash map. If so, we decrement the counts for both the current number and twice the current number. If not, we return false because it's not possible to reorder the array as required. If all the numbers have been processed and the condition was satisfied for all, return true.

## A solution in Python

```python
def can_reorder_array(arr):
    from collections import Counter

    count = Counter(arr)
    arr = sorted(arr)
    for x in arr:
        if count[x] == 0:
            continue
        if count[2 * x] > 0:
            count[x] -= 1
            count[2 * x] -= 1
        else:
            return False
    return True
```
The algorithm first counts the occurrences of each number in the input array `arr` by creating a hash map called `count`. Then sort the input array in ascending order. Then we iterate through the sorted array, checking if there's a number twice as large as the current number available in the hash map. If so, we decrement the counts for both the current number and twice the current number. If not, we return false because it's not possible to reorder the array as required. If all the numbers have been processed and the condition was satisfied for all, return true.

## A solution in Javascript

```javascript
function canReorderArray(arr) {
    const count = {};
    for (const n of arr) {
        count[n] = (count[n] || 0) + 1;
    }
    arr.sort((a, b) => a - b);
    for (const x of arr) {
        if (count[x] === 0) {
            continue;
        }
        if (count[2 * x] > 0) {
            count[x]--;
            count[2 * x]--;
        } else {
            return false;
        }
    }
    return true;
}
```
The algorithm first counts the occurrences of each number in the input array `arr` by creating a hash map called `count`. Then sort the input array in ascending order. Then we iterate through the sorted array, checking if there's a number twice as large as the current number available in the hash map. If so, we decrement the counts for both the current number and twice the current number. If not, we return false because it's not possible to reorder the array as required. If all the numbers have been processed and the condition was satisfied for all, return true.


# Subarrays with K Different Integers

- slug: subarrays-with-k-different-integers
- difficulty: Hard

Given an integer array `nums` and an integer `k`, return _the number of **good subarrays** of_ `nums`.

A **good array** is an array where the number of different integers in that array is exactly `k`.

*   For example, `[1,2,3,1,2]` has `3` different integers: `1`, `2`, and `3`.

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

**Example 1:**

**Input:** nums = \[1,2,1,2,3\], k = 2
**Output:** 7
**Explanation:** Subarrays formed with exactly 2 different integers: \[1,2\], \[2,1\], \[1,2\], \[2,3\], \[1,2,1\], \[2,1,2\], \[1,2,1,2\]

**Example 2:**

**Input:** nums = \[1,2,1,3,4\], k = 3
**Output:** 3
**Explanation:** Subarrays formed with exactly 3 different integers: \[1,2,1,3\], \[2,1,3\], \[1,3,4\].

**Constraints:**

*   `1 <= nums.length <= 2 * 104`
*   `1 <= nums[i], k <= nums.length`

## A solution in Java

```java
class Solution {
    public int minDeletionSize(String[] strs) {
        int n = strs.length;
        int m = strs[0].length();
        int[] dp = new int[m];
        for (int j = 0; j < m; ++j) {
            dp[j] = 1;
            for (int i = 0; i < j; ++i) {
                boolean flag = true;
                for (int k = 0; k < n - 1; ++k)
                    flag = flag && (strs[k].charAt(i) <= strs[k].charAt(j));
                dp[j] = flag ? Math.max(dp[j], dp[i] + 1) : dp[j];
            }
        }

        int maxLength = 0;
        for (int num : dp)
            maxLength = Math.max(maxLength, num);

        return m - maxLength;
    }
}
```
The problem can be solved using dynamic programming.
1. Create a `dp` array of the length of the strings in the input array, initialized with 1.
2. Loop through the characters of the string elements twice (using two nested loops with indices `i` and `j`).
3. For every pair of characters (strs[k][i] and strs[k][j]), check if i-th characters of all the strings are less than or equal to j-th characters in lexicographic order. If this condition is satisfied for all the i-th and j-th characters, update the value of dp[j] with the maximum of its current value and dp[i] + 1.
4. The minimum number of deletion indices is the difference between the length of the strings in the input array and the maximum value in the `dp` array.

This approach ensures a dynamic update of the `dp` array by keeping track of the valid pairs of indices where lexicographic order is maintained. The final maximum value in the `dp` array represents the longest valid sequence of characters with lexicographic order maintained. The difference between this value and the length of the strings gives us the required minimum deletion indices to achieve lexicographic order.

## A solution in C++

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

int minDeletionSize(vector<string>& strs) {
    int n = strs.size();
    int m = strs[0].length();
    vector<int> dp(m, 1);

    for (int j = 0; j < m; ++j)
        for (int i = 0; i < j; ++i) {
            bool flag = true;
            for (int k = 0; k < n - 1; ++k)
                flag = flag && (strs[k][i] <= strs[k][j]);
            dp[j] = flag ? max(dp[j], dp[i] + 1) : dp[j];
        }

    return m - *max_element(dp.begin(), dp.end());
}
```
The problem can be solved using dynamic programming.
1. Create a `dp` array of the length of the strings in the input array, initialized with 1.
2. Loop through the characters of the string elements twice (using two nested loops with indices `i` and `j`).
3. For every pair of characters (strs[k][i] and strs[k][j]), check if i-th characters of all the strings are less than or equal to j-th characters in lexicographic order. If this condition is satisfied for all the i-th and j-th characters, update the value of dp[j] with the maximum of its current value and dp[i] + 1.
4. The minimum number of deletion indices is the difference between the length of the strings in the input array and the maximum value in the `dp` array.

This approach ensures a dynamic update of the `dp` array by keeping track of the valid pairs of indices where lexicographic order is maintained. The final maximum value in the `dp` array represents the longest valid sequence of characters with lexicographic order maintained. The difference between this value and the length of the strings gives us the required minimum deletion indices to achieve lexicographic order.

## A solution in Python

```python
class Solution:
    def minDeletionSize(self, strs: List[str]) -> int:
        n = len(strs)
        m = len(strs[0])
        dp = [1] * m

        for j in range(m):
            for i in range(j):
                flag = all(strs[k][i] <= strs[k][j] for k in range(n - 1))
                dp[j] = max(dp[j], dp[i] + 1) if flag else dp[j]

        return m - max(dp)
```
The problem can be solved using dynamic programming.
1. Create a `dp` array of the length of the strings in the input array, initialized with 1.
2. Loop through the characters of the string elements twice (using two nested loops with indices `i` and `j`).
3. For every pair of characters (strs[k][i] and strs[k][j]), check if i-th characters of all the strings are less than or equal to j-th characters in lexicographic order. If this condition is satisfied for all the i-th and j-th characters, update the value of dp[j] with the maximum of its current value and dp[i] + 1.
4. The minimum number of deletion indices is the difference between the length of the strings in the input array and the maximum value in the `dp` array.

This approach ensures a dynamic update of the `dp` array by keeping track of the valid pairs of indices where lexicographic order is maintained. The final maximum value in the `dp` array represents the longest valid sequence of characters with lexicographic order maintained. The difference between this value and the length of the strings gives us the required minimum deletion indices to achieve lexicographic order.

## A solution in Javascript

```javascript
var minDeletionSize = function (strs) {
  let n = strs.length;
  let m = strs[0].length;
  let dp = new Array(m).fill(1);

  for (let j = 0; j < m; ++j) {
    for (let i = 0; i < j; ++i) {
      let flag = true;
      for (let k = 0; k < n - 1; ++k)
        flag = flag && (strs[k][i] <= strs[k][j]);
      dp[j] = flag ? Math.max(dp[j], dp[i] + 1) : dp[j];
    }
  }

  return m - Math.max(...dp);
};
```
The problem can be solved using dynamic programming.
1. Create a `dp` array of the length of the strings in the input array, initialized with 1.
2. Loop through the characters of the string elements twice (using two nested loops with indices `i` and `j`).
3. For every pair of characters (strs[k][i] and strs[k][j]), check if i-th characters of all the strings are less than or equal to j-th characters in lexicographic order. If this condition is satisfied for all the i-th and j-th characters, update the value of dp[j] with the maximum of its current value and dp[i] + 1.
4. The minimum number of deletion indices is the difference between the length of the strings in the input array and the maximum value in the `dp` array.

This approach ensures a dynamic update of the `dp` array by keeping track of the valid pairs of indices where lexicographic order is maintained. The final maximum value in the `dp` array represents the longest valid sequence of characters with lexicographic order maintained. The difference between this value and the length of the strings gives us the required minimum deletion indices to achieve lexicographic order.


# Cousins in Binary Tree

- slug: cousins-in-binary-tree
- difficulty: Easy

Given the `root` of a binary tree with unique values and the values of two different nodes of the tree `x` and `y`, return `true` _if the nodes corresponding to the values_ `x` _and_ `y` _in the tree are **cousins**, or_ `false` _otherwise._

Two nodes of a binary tree are **cousins** if they have the same depth with different parents.

Note that in a binary tree, the root node is at the depth `0`, and children of each depth `k` node are at the depth `k + 1`.

**Example 1:**

**Input:** root = \[1,2,3,4\], x = 4, y = 3
**Output:** false

**Example 2:**

**Input:** root = \[1,2,3,null,4,null,5\], x = 5, y = 4
**Output:** true

**Example 3:**

**Input:** root = \[1,2,3,null,4\], x = 2, y = 3
**Output:** false

**Constraints:**

*   The number of nodes in the tree is in the range `[2, 100]`.
*   `1 <= Node.val <= 100`
*   Each node has a **unique** value.
*   `x != y`
*   `x` and `y` are exist in the tree.

## A solution in Java

```java
public int tallestBillboard(int[] rods) {
    int n = rods.length;
    int totalLength = Arrays.stream(rods).sum();
    int[][] dp = new int[n + 1][totalLength + 1];
    for (int i = 0; i < n + 1; i++) {
        Arrays.fill(dp[i], -1);
    }
    dp[0][0] = 0;

    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= totalLength; j++) {
            dp[i][j] = dp[i - 1][j];
            if (rods[i - 1] <= j) dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - rods[i - 1]] + rods[i - 1]);
            if (rods[i - 1] <= totalLength - j) dp[i][j] = Math.max(dp[i][j], dp[i - 1][j + rods[i - 1]]);
        }
    }

    return dp[n][0] / 2;
}
```
The given problem can be solved using Dynamic Programming. We calculate the sum of all the lengths of rods available, this will help us in creating an NxM, where N is the number of rods and M is the sum of all lengths, table filled with "-1". Then we initialize the first row of this table with 0.

Now, we loop through the table and refer to the previous row while remaining within the boundaries of total sum. We make comparisons with the previous row values by checking if the current rod can be added to the current total length or not. If yes, we check for the maximum value by adding and updating the current value. This approach allows us to deduce the maximum equal length of rods that can be created.

Finally, we return the value at (n,0)th index divided by 2 as our final result. This gives us the largest possible height of the supported billboard. If it's not possible to support the billboard, the function returns 0.

## A solution in C++

```cpp
int tallestBillboard(vector<int>& rods) {
    int n = rods.size();
    int totalLength = accumulate(rods.begin(), rods.end(), 0);
    vector<vector<int>> dp(n + 1, vector<int>(totalLength + 1, -1));
    dp[0][0] = 0;

    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= totalLength; j++) {
            dp[i][j] = dp[i - 1][j];
            if (rods[i - 1] <= j) dp[i][j] = max(dp[i][j], dp[i - 1][j - rods[i - 1]] + rods[i - 1]);
            if (rods[i - 1] <= totalLength - j) dp[i][j] = max(dp[i][j], dp[i - 1][j + rods[i - 1]]);
        }
    }

    return dp[n][0] / 2;
}
```
The given problem can be solved using Dynamic Programming. We calculate the sum of all the lengths of rods available, this will help us in creating an NxM, where N is the number of rods and M is the sum of all lengths, table filled with "-1". Then we initialize the first row of this table with 0.

Now, we loop through the table and refer to the previous row while remaining within the boundaries of total sum. We make comparisons with the previous row values by checking if the current rod can be added to the current total length or not. If yes, we check for the maximum value by adding and updating the current value. This approach allows us to deduce the maximum equal length of rods that can be created.

Finally, we return the value at (n,0)th index divided by 2 as our final result. This gives us the largest possible height of the supported billboard. If it's not possible to support the billboard, the function returns 0.

## A solution in Python

```python
def tallestBillboard(rods):
    n = len(rods)
    totalLength = sum(rods)
    dp = [[-1] * (totalLength + 1) for _ in range(n + 1)]
    dp[0][0] = 0

    for i in range(1, n + 1):
        for j in range(totalLength + 1):
            dp[i][j] = dp[i - 1][j]
            if rods[i - 1] <= j:
                dp[i][j] = max(dp[i][j], dp[i - 1][j - rods[i - 1]] + rods[i - 1])
            if rods[i - 1] <= totalLength - j:
                dp[i][j] = max(dp[i][j], dp[i - 1][j + rods[i - 1]])

    return dp[n][0] // 2
```
The given problem can be solved using Dynamic Programming. We calculate the sum of all the lengths of rods available, this will help us in creating an NxM, where N is the number of rods and M is the sum of all lengths, table filled with "-1". Then we initialize the first row of this table with 0.

Now, we loop through the table and refer to the previous row while remaining within the boundaries of total sum. We make comparisons with the previous row values by checking if the current rod can be added to the current total length or not. If yes, we check for the maximum value by adding and updating the current value. This approach allows us to deduce the maximum equal length of rods that can be created.

Finally, we return the value at (n,0)th index divided by 2 as our final result. This gives us the largest possible height of the supported billboard. If it's not possible to support the billboard, the function returns 0.

## A solution in Javascript

```javascript
function tallestBillboard(rods) {
    const n = rods.length;
    const totalLength = rods.reduce((sum, rod) => sum + rod, 0);
    const dp = Array.from({length: n + 1}, () => Array(totalLength + 1).fill(-1));

    dp[0][0] = 0;

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

    return dp[n][0] / 2;
}
```
The given problem can be solved using Dynamic Programming. We calculate the sum of all the lengths of rods available, this will help us in creating an NxM, where N is the number of rods and M is the sum of all lengths, table filled with "-1". Then we initialize the first row of this table with 0.

Now, we loop through the table and refer to the previous row while remaining within the boundaries of total sum. We make comparisons with the previous row values by checking if the current rod can be added to the current total length or not. If yes, we check for the maximum value by adding and updating the current value. This approach allows us to deduce the maximum equal length of rods that can be created.

Finally, we return the value at (n,0)th index divided by 2 as our final result. This gives us the largest possible height of the supported billboard. If it's not possible to support the billboard, the function returns 0.


# Rotting Oranges

- slug: rotting-oranges
- difficulty: Medium

You are given an `m x n` `grid` where each cell can have one of three values:

*   `0` representing an empty cell,
*   `1` representing a fresh orange, or
*   `2` representing a rotten orange.

Every minute, any fresh orange that is **4-directionally adjacent** to a rotten orange becomes rotten.

Return _the minimum number of minutes that must elapse until no cell has a fresh orange_. If _this is impossible, return_ `-1`.

**Example 1:**

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

**Example 2:**

**Input:** grid = \[\[2,1,1\],\[0,1,1\],\[1,0,1\]\]
**Output:** -1
**Explanation:** The orange in the bottom left corner (row 2, column 0) is never rotten, because rotting only happens 4-directionally.

**Example 3:**

**Input:** grid = \[\[0,2\]\]
**Output:** 0
**Explanation:** Since there are already no fresh oranges at minute 0, the answer is just 0.

**Constraints:**

*   `m == grid.length`
*   `n == grid[i].length`
*   `1 <= m, n <= 10`
*   `grid[i][j]` is `0`, `1`, or `2`.

## A solution in Java

```java
public int[] prisonAfterNDays(int[] cells, int n) {
    int[] temp = new int[8];
    n = n % 14 == 0 ? 14 : n % 14; // Pattern repeats every 14 days

    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j < 7; ++j) {
            temp[j] = cells[j - 1] == cells[j + 1] ? 1 : 0;
        }
        cells = temp.clone();
    }

    return cells;
}
```
The algorithm iterates for `n` days, but since the pattern repeats itself every 14 days, we first calculate the effective number of days to iterate as `n % 14`. For each day, create a temporary array to store the new state of the prison cells. Iterate through the middle cells (1 to 6) and check if the adjacent cells are equal, if they are, then the new state for the current cell is occupied (1), otherwise, it's vacant (0). Update the `cells` array with the new state and repeat the process for the required number of days. Finally, return the new state of the prison cells after `n` days.

## A solution in C++

```cpp
#include <vector>

std::vector<int> prisonAfterNDays(std::vector<int>& cells, int n) {
    std::vector<int> temp(8, 0);
    n = n % 14 == 0 ? 14 : n % 14; // Pattern repeats every 14 days

    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j < 7; ++j) {
            temp[j] = !(cells[j - 1] ^ cells[j + 1]);
        }
        cells = temp;
    }

    return cells;
}
```
The algorithm iterates for `n` days, but since the pattern repeats itself every 14 days, we first calculate the effective number of days to iterate as `n % 14`. For each day, create a temporary array to store the new state of the prison cells. Iterate through the middle cells (1 to 6) and check if the adjacent cells are equal, if they are, then the new state for the current cell is occupied (1), otherwise, it's vacant (0). Update the `cells` array with the new state and repeat the process for the required number of days. Finally, return the new state of the prison cells after `n` days.

## A solution in Python

```python
def prisonAfterNDays(cells, n):
    n = n % 14 if n % 14 != 0 else 14 # Pattern repeats every 14 days

    for _ in range(n):
        temp = [0] * 8
        for i in range(1, 7):
            temp[i] = int(cells[i - 1] == cells[i + 1])
        cells = temp

    return cells
```
The algorithm iterates for `n` days, but since the pattern repeats itself every 14 days, we first calculate the effective number of days to iterate as `n % 14`. For each day, create a temporary array to store the new state of the prison cells. Iterate through the middle cells (1 to 6) and check if the adjacent cells are equal, if they are, then the new state for the current cell is occupied (1), otherwise, it's vacant (0). Update the `cells` array with the new state and repeat the process for the required number of days. Finally, return the new state of the prison cells after `n` days.

## A solution in Javascript

```javascript
function prisonAfterNDays(cells, n) {
    let temp = new Array(8).fill(0);
    n = n % 14 === 0 ? 14 : n % 14; // Pattern repeats every 14 days

    for (let i = 1; i <= n; ++i) {
        for (let j = 1; j < 7; ++j) {
            temp[j] = cells[j - 1] === cells[j + 1] ? 1 : 0;
        }
        cells = [...temp];
    }

    return cells;
}
```
The algorithm iterates for `n` days, but since the pattern repeats itself every 14 days, we first calculate the effective number of days to iterate as `n % 14`. For each day, create a temporary array to store the new state of the prison cells. Iterate through the middle cells (1 to 6) and check if the adjacent cells are equal, if they are, then the new state for the current cell is occupied (1), otherwise, it's vacant (0). Update the `cells` array with the new state and repeat the process for the required number of days. Finally, return the new state of the prison cells after `n` days.


# Minimum Number of K Consecutive Bit Flips

- slug: minimum-number-of-k-consecutive-bit-flips
- difficulty: Hard

You are given a binary array `nums` and an integer `k`.

A **k-bit flip** is choosing a **subarray** of length `k` from `nums` and simultaneously changing every `0` in the subarray to `1`, and every `1` in the subarray to `0`.

Return _the minimum number of **k-bit flips** required so that there is no_ `0` _in the array_. If it is not possible, return `-1`.

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

**Example 1:**

**Input:** nums = \[0,1,0\], k = 1
**Output:** 2
**Explanation:** Flip nums\[0\], then flip nums\[2\].

**Example 2:**

**Input:** nums = \[1,1,0\], k = 2
**Output:** -1
**Explanation:** No matter how we flip subarrays of size 2, we cannot make the array become \[1,1,1\].

**Example 3:**

**Input:** nums = \[0,0,0,1,0,1,1,0\], k = 3
**Output:** 3
**Explanation:**
Flip nums\[0\],nums\[1\],nums\[2\]: nums becomes \[1,1,1,1,0,1,1,0\]
Flip nums\[4\],nums\[5\],nums\[6\]: nums becomes \[1,1,1,1,1,0,0,0\]
Flip nums\[5\],nums\[6\],nums\[7\]: nums becomes \[1,1,1,1,1,1,1,1\]

**Constraints:**

*   `1 <= nums.length <= 105`
*   `1 <= k <= nums.length`

## A solution in Java

```java
public int minKBitFlips(int[] nums, int k) {
    int n = nums.length;
    int[] flipped = new int[n];
    int flips = 0, ans = 0;
    for (int i = 0; i < n; ++i) {
        if (i >= k) flips -= flipped[i - k];
        if ((flips + nums[i]) % 2 == 0) {
            if (i + k > n) return -1;
            flipped[i] = 1;
            flips++;
            ans++;
        }
    }
    return ans;
}
```
The algorithm uses the "lazy flipping" technique where, for each index `i` in `nums`, it checks whether there is a flip required, and if so, applies that flip "lazily" in the form of maintaining a separate `flipped` array. The `flipped` array indicators are then kept and updated as the algorithm iterates through the indices in `nums`.

For each index `i` in `nums`, the algorithm does the following:
1. Removes the effect of a flip done K indices before by decrementing the `flips` counter.
2. Checks if a flip is needed at the current index i.
3. If a flip is required and it would go out of the array, return -1 as it is not possible.
4. If a flip is possible, update the `flipped[i]` indicator, increment the `flips` counter, and increment the answer counter.
5. Return the answer counter as the minimum number of k-bit flips required.

The final result is obtained by summing the flips as we move along the array effectively determining the minimum number of flips needed.

## A solution in C++

```cpp
int minKBitFlips(vector<int>& nums, int k) {
    int n = nums.size();
    vector<int> flipped(n, 0);
    int flips = 0, ans = 0;
    for (int i = 0; i < n; ++i) {
        if (i >= k) flips = (flips - flipped[i - k]) % 2;
        if ((flips + nums[i]) % 2 == 0) {
            if (i + k > n) return -1;
            flipped[i] = 1;
            flips = (flips + 1) % 2;
            ans++;
        }
    }
    return ans;
}
```
The algorithm uses the "lazy flipping" technique where, for each index `i` in `nums`, it checks whether there is a flip required, and if so, applies that flip "lazily" in the form of maintaining a separate `flipped` array. The `flipped` array indicators are then kept and updated as the algorithm iterates through the indices in `nums`.

For each index `i` in `nums`, the algorithm does the following:
1. Removes the effect of a flip done K indices before by decrementing the `flips` counter.
2. Checks if a flip is needed at the current index i.
3. If a flip is required and it would go out of the array, return -1 as it is not possible.
4. If a flip is possible, update the `flipped[i]` indicator, increment the `flips` counter, and increment the answer counter.
5. Return the answer counter as the minimum number of k-bit flips required.

The final result is obtained by summing the flips as we move along the array effectively determining the minimum number of flips needed.

## A solution in Python

```python
def min_k_bit_flips(nums, k):
    n = len(nums)
    flipped = [0] * n
    flips = ans = 0
    for i in range(n):
        if i >= k:
            flips -= flipped[i - k]
        if (flips + nums[i]) % 2 == 0:
            if i + k > n:
                return -1
            flipped[i] = 1
            flips += 1
            ans += 1
    return ans
```
The algorithm uses the "lazy flipping" technique where, for each index `i` in `nums`, it checks whether there is a flip required, and if so, applies that flip "lazily" in the form of maintaining a separate `flipped` array. The `flipped` array indicators are then kept and updated as the algorithm iterates through the indices in `nums`.

For each index `i` in `nums`, the algorithm does the following:
1. Removes the effect of a flip done K indices before by decrementing the `flips` counter.
2. Checks if a flip is needed at the current index i.
3. If a flip is required and it would go out of the array, return -1 as it is not possible.
4. If a flip is possible, update the `flipped[i]` indicator, increment the `flips` counter, and increment the answer counter.
5. Return the answer counter as the minimum number of k-bit flips required.

The final result is obtained by summing the flips as we move along the array effectively determining the minimum number of flips needed.

## A solution in Javascript

```javascript
function minKBitFlips(nums, k) {
    const n = nums.length;
    const flipped = Array(n).fill(0);
    let flips = 0, ans = 0;
    for (let i = 0; i < n; ++i) {
        if (i >= k) flips -= flipped[i - k];
        if ((flips + nums[i]) % 2 === 0) {
            if (i + k > n) return -1;
            flipped[i] = 1;
            flips++;
            ans++;
        }
    }
    return ans;
}
```
The algorithm uses the "lazy flipping" technique where, for each index `i` in `nums`, it checks whether there is a flip required, and if so, applies that flip "lazily" in the form of maintaining a separate `flipped` array. The `flipped` array indicators are then kept and updated as the algorithm iterates through the indices in `nums`.

For each index `i` in `nums`, the algorithm does the following:
1. Removes the effect of a flip done K indices before by decrementing the `flips` counter.
2. Checks if a flip is needed at the current index i.
3. If a flip is required and it would go out of the array, return -1 as it is not possible.
4. If a flip is possible, update the `flipped[i]` indicator, increment the `flips` counter, and increment the answer counter.
5. Return the answer counter as the minimum number of k-bit flips required.

The final result is obtained by summing the flips as we move along the array effectively determining the minimum number of flips needed.


# Number of Squareful Arrays

- slug: number-of-squareful-arrays
- difficulty: Hard

An array is **squareful** if the sum of every pair of adjacent elements is a **perfect square**.

Given an integer array nums, return _the number of permutations of_ `nums` _that are **squareful**_.

Two permutations `perm1` and `perm2` are different if there is some index `i` such that `perm1[i] != perm2[i]`.

**Example 1:**

**Input:** nums = \[1,17,8\]
**Output:** 2
**Explanation:** \[1,8,17\] and \[17,8,1\] are the valid permutations.

**Example 2:**

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

**Constraints:**

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

## A solution in Java

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

public int numSquarefulPerms(int[] nums) {
    Map<Integer, Integer> counter = new HashMap<>();
    for (int num : nums)
        counter.put(num, counter.getOrDefault(num, 0) + 1);

    return dfs(nums, 0, counter);
}

private boolean isSquare(int n) {
    int root = (int) Math.sqrt(n);
    return root * root == n;
}

private int dfs(int[] nums, int idx, Map<Integer, Integer> counter) {
    if (idx == nums.length)
        return 1;

    int count = 0;
    for (int key : counter.keySet()) {
        if (counter.get(key) != 0 && (idx == 0 || isSquare(nums[idx - 1] + key))) {
            counter.put(key, counter.get(key) - 1);
            nums[idx] = key;
            count += dfs(nums, idx + 1, counter);
            counter.put(key, counter.get(key) + 1);
        }
    }

    return count;
}
```
The algorithm first captures the frequency of each number in the input `nums` with a counter. Using a depth-first search algorithm, it then processes each permutation that starts with a number existing in `nums`, ensuring that the sum of adjacent elements in the permutation being processed is a perfect square. With each valid instance, the algorithm increases the count.

The base case for the recursive `dfs` function is when the current index `idx` is equal to the length of the `nums`, which is when a valid permutation is found. If this happens, the function returns 1, signaling the completion of the permutation.

The `isSquare` helper function checks if the given number `n` is a perfect square by taking its square root, then squaring the result again and comparing the squared value to the original value of `n`.

For each language, the code starts by creating a counter dict or map for `nums`, which stores the frequency of each element in `nums`. The `dfs` function then deals with forming the permutations and checking if they are squareful. If a permutation is found to be squareful, the count is incremented by 1 until all permutations are checked. The final count is returned.

## A solution in C++

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

bool isSquare(int n) {
    int root = sqrt(n);
    return root * root == n;
}

void dfs(std::vector<int>& nums, int idx, int& count,
         std::unordered_map<int, int>& counter) {
    if (idx == nums.size()) {
        count++;
        return;
    }

    for (auto it : counter) {
        if (it.second && (idx == 0 || isSquare(nums[idx - 1] + it.first))) {
            counter[it.first]--;
            nums[idx] = it.first;
            dfs(nums, idx + 1, count, counter);
            counter[it.first]++;
        }
    }
}

int numSquarefulPerms(std::vector<int>& nums) {
    std::unordered_map<int, int> counter;
    for (int num : nums)
        counter[num]++;

    int count = 0;
    dfs(nums, 0, count, counter);
    return count;
}
```
The algorithm first captures the frequency of each number in the input `nums` with a counter. Using a depth-first search algorithm, it then processes each permutation that starts with a number existing in `nums`, ensuring that the sum of adjacent elements in the permutation being processed is a perfect square. With each valid instance, the algorithm increases the count.

The base case for the recursive `dfs` function is when the current index `idx` is equal to the length of the `nums`, which is when a valid permutation is found. If this happens, the function returns 1, signaling the completion of the permutation.

The `isSquare` helper function checks if the given number `n` is a perfect square by taking its square root, then squaring the result again and comparing the squared value to the original value of `n`.

For each language, the code starts by creating a counter dict or map for `nums`, which stores the frequency of each element in `nums`. The `dfs` function then deals with forming the permutations and checking if they are squareful. If a permutation is found to be squareful, the count is incremented by 1 until all permutations are checked. The final count is returned.

## A solution in Python

```python
from collections import Counter

def numSquarefulPerms(nums):
    def is_square(n):
        return int(n ** 0.5) ** 2 == n

    def dfs(idx):
        if idx == len(nums):
            return 1

        count = 0
        for key in counter.keys():
            if counter[key] and (idx == 0 or is_square(nums[idx - 1] + key)):
                counter[key] -= 1
                nums[idx] = key
                count += dfs(idx + 1)
                counter[key] += 1

        return count

    key_set, counter = set(nums), Counter(nums)
    return dfs(0)
```
The algorithm first captures the frequency of each number in the input `nums` with a counter. Using a depth-first search algorithm, it then processes each permutation that starts with a number existing in `nums`, ensuring that the sum of adjacent elements in the permutation being processed is a perfect square. With each valid instance, the algorithm increases the count.

The base case for the recursive `dfs` function is when the current index `idx` is equal to the length of the `nums`, which is when a valid permutation is found. If this happens, the function returns 1, signaling the completion of the permutation.

The `isSquare` helper function checks if the given number `n` is a perfect square by taking its square root, then squaring the result again and comparing the squared value to the original value of `n`.

For each language, the code starts by creating a counter dict or map for `nums`, which stores the frequency of each element in `nums`. The `dfs` function then deals with forming the permutations and checking if they are squareful. If a permutation is found to be squareful, the count is incremented by 1 until all permutations are checked. The final count is returned.

## A solution in Javascript

```javascript
function numSquarefulPerms(nums) {
    const counter = new Map();
    nums.forEach(num => counter.set(num, (counter.get(num) || 0) + 1));

    const isSquare = n => {
        const root = Math.sqrt(n);
        return Math.floor(root) * Math.floor(root) === n;
    };

    const dfs = (idx) => {
        if (idx === nums.length)
            return 1;

        let count = 0;
        for (let key of counter.keys()) {
            if (counter.get(key) !== 0 && (idx === 0 || isSquare(nums[idx - 1] + key))) {
                counter.set(key, counter.get(key) - 1);
                nums[idx] = key;
                count += dfs(idx + 1);
                counter.set(key, counter.get(key) + 1);
            }
        }

        return count;
    };

    return dfs(0);
}
```
The algorithm first captures the frequency of each number in the input `nums` with a counter. Using a depth-first search algorithm, it then processes each permutation that starts with a number existing in `nums`, ensuring that the sum of adjacent elements in the permutation being processed is a perfect square. With each valid instance, the algorithm increases the count.

The base case for the recursive `dfs` function is when the current index `idx` is equal to the length of the `nums`, which is when a valid permutation is found. If this happens, the function returns 1, signaling the completion of the permutation.

The `isSquare` helper function checks if the given number `n` is a perfect square by taking its square root, then squaring the result again and comparing the squared value to the original value of `n`.

For each language, the code starts by creating a counter dict or map for `nums`, which stores the frequency of each element in `nums`. The `dfs` function then deals with forming the permutations and checking if they are squareful. If a permutation is found to be squareful, the count is incremented by 1 until all permutations are checked. The final count is returned.


# Find the Town Judge

- slug: find-the-town-judge
- difficulty: Easy

In a town, there are `n` people labeled from `1` to `n`. There is a rumor that one of these people is secretly the town judge.

If the town judge exists, then:

1.  The town judge trusts nobody.
2.  Everybody (except for the town judge) trusts the town judge.
3.  There is exactly one person that satisfies properties **1** and **2**.

You are given an array `trust` where `trust[i] = [ai, bi]` representing that the person labeled `ai` trusts the person labeled `bi`. If a trust relationship does not exist in `trust` array, then such a trust relationship does not exist.

Return _the label of the town judge if the town judge exists and can be identified, or return_ `-1` _otherwise_.

**Example 1:**

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

**Example 2:**

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

**Example 3:**

**Input:** n = 3, trust = \[\[1,3\],\[2,3\],\[3,1\]\]
**Output:** -1

**Constraints:**

*   `1 <= n <= 1000`
*   `0 <= trust.length <= 104`
*   `trust[i].length == 2`
*   All the pairs of `trust` are **unique**.
*   `ai != bi`
*   `1 <= ai, bi <= n`

## A solution in Java

```java
public int findJudge(int n, int[][] trust) {
    int[] trustCounts = new int[n + 1];
    for (int[] t : trust) {
        trustCounts[t[0]]--;
        trustCounts[t[1]]++;
    }
    for (int i = 1; i <= n; i++) {
        if (trustCounts[i] == n - 1)
            return i;
    }
    return -1;
}
```
1. Create an array `trustCounts` to store the number of trusts for each person.
2. Loop through the trust relationships, decrement the count in `trustCounts` for the person who trusts (a), and increment the count for the person being trusted (b).
3. Loop through the `trustCounts` array and check if any person has a trust count equal to `n - 1`, as this would mean that everyone trusts that person (except for themselves).
4. If such a person is found, return their index as the town judge. If no such person is found, return -1.

## A solution in C++

```cpp
int findJudge(int n, vector<vector<int>>& trust) {
    vector<int> trustCounts(n + 1, 0);
    for (auto& t : trust) {
        trustCounts[t[0]]--;
        trustCounts[t[1]]++;
    }
    for (int i = 1; i <= n; i++) {
        if (trustCounts[i] == n - 1)
            return i;
    }
    return -1;
}
```
1. Create an array `trustCounts` to store the number of trusts for each person.
2. Loop through the trust relationships, decrement the count in `trustCounts` for the person who trusts (a), and increment the count for the person being trusted (b).
3. Loop through the `trustCounts` array and check if any person has a trust count equal to `n - 1`, as this would mean that everyone trusts that person (except for themselves).
4. If such a person is found, return their index as the town judge. If no such person is found, return -1.

## A solution in Python

```python
def findJudge(n, trust):
    trust_counts = [0] * (n + 1)
    for a, b in trust:
        trust_counts[a] -= 1
        trust_counts[b] += 1
    for i in range(1, n + 1):
        if trust_counts[i] == n - 1:
            return i
    return -1
```
1. Create an array `trustCounts` to store the number of trusts for each person.
2. Loop through the trust relationships, decrement the count in `trustCounts` for the person who trusts (a), and increment the count for the person being trusted (b).
3. Loop through the `trustCounts` array and check if any person has a trust count equal to `n - 1`, as this would mean that everyone trusts that person (except for themselves).
4. If such a person is found, return their index as the town judge. If no such person is found, return -1.

## A solution in Javascript

```javascript
function findJudge(n, trust) {
    let trustCounts = new Array(n + 1).fill(0);
    for (let [a, b] of trust) {
        trustCounts[a]--;
        trustCounts[b]++;
    }
    for (let i = 1; i <= n; i++) {
        if (trustCounts[i] === n - 1)
            return i;
    }
    return -1;
}
```
1. Create an array `trustCounts` to store the number of trusts for each person.
2. Loop through the trust relationships, decrement the count in `trustCounts` for the person who trusts (a), and increment the count for the person being trusted (b).
3. Loop through the `trustCounts` array and check if any person has a trust count equal to `n - 1`, as this would mean that everyone trusts that person (except for themselves).
4. If such a person is found, return their index as the town judge. If no such person is found, return -1.