# Maximum Binary Tree II

- slug: maximum-binary-tree-ii
- difficulty: Medium

A **maximum tree** is a tree where every node has a value greater than any other value in its subtree.

You are given the `root` of a maximum binary tree and an integer `val`.

Just as in the [previous problem](https://leetcode.com/problems/maximum-binary-tree/), the given tree was constructed from a list `a` (`root = Construct(a)`) recursively with the following `Construct(a)` routine:

*   If `a` is empty, return `null`.
*   Otherwise, let `a[i]` be the largest element of `a`. Create a `root` node with the value `a[i]`.
*   The left child of `root` will be `Construct([a[0], a[1], ..., a[i - 1]])`.
*   The right child of `root` will be `Construct([a[i + 1], a[i + 2], ..., a[a.length - 1]])`.
*   Return `root`.

Note that we were not given `a` directly, only a root node `root = Construct(a)`.

Suppose `b` is a copy of `a` with the value `val` appended to it. It is guaranteed that `b` has unique values.

Return `Construct(b)`.

**Example 1:**

**Input:** root = \[4,1,3,null,null,2\], val = 5
**Output:** \[5,4,null,1,3,null,null,2\]
**Explanation:** a = \[1,4,2,3\], b = \[1,4,2,3,5\]

**Example 2:**

**Input:** root = \[5,2,4,null,1\], val = 3
**Output:** \[5,2,4,null,1,null,3\]
**Explanation:** a = \[2,1,5,4\], b = \[2,1,5,4,3\]

**Example 3:**

**Input:** root = \[5,2,3,null,1\], val = 4
**Output:** \[5,2,4,null,1,3\]
**Explanation:** a = \[2,1,5,3\], b = \[2,1,5,3,4\]

**Constraints:**

*   The number of nodes in the tree is in the range `[1, 100]`.
*   `1 <= Node.val <= 100`
*   All the values of the tree are **unique**.
*   `1 <= val <= 100`

## A solution in Java

```java
import java.util.*;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public boolean isCompleteTree(TreeNode root) {
    if (root == null)
        return true;

    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while (queue.peek() != null) {
        TreeNode node = queue.poll();
        queue.offer(node.left);
        queue.offer(node.right);
    }
    while (!queue.isEmpty() && queue.peek() == null) {
        queue.poll();
    }
    return queue.isEmpty();
}
```
To check if the given binary tree is a complete binary tree, we can use a method called Breadth First Search (BFS) or level-order traversal.

1. Start by creating a queue and adding the root node to it.
2. Then, use a loop to iterate through nodes in the queue. For each node, dequeue it, and enqueue its left and right children (if any) in the order they appear.
3. Keep iterating until you find a node with no left child or right child.
4. After that, check if all remaining nodes in the queue also have no children. If yes, then the given tree is a complete binary tree. Otherwise, it's not.

The time complexity of this algorithm is O(n), where n is the number of nodes in the binary tree, as each node is visited once.

## A solution in C++

```cpp
#include <queue>

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

bool isCompleteTree(TreeNode* root) {
    if (!root)
        return true;
    std::queue<TreeNode*> q;
    q.push(root);
    while (q.front() != nullptr) {
        TreeNode* node = q.front();
        q.pop();
        q.push(node->left);
        q.push(node->right);
    }
    while (!q.empty() && q.front() == nullptr) {
        q.pop();
    }
    return q.empty();
}
```
To check if the given binary tree is a complete binary tree, we can use a method called Breadth First Search (BFS) or level-order traversal.

1. Start by creating a queue and adding the root node to it.
2. Then, use a loop to iterate through nodes in the queue. For each node, dequeue it, and enqueue its left and right children (if any) in the order they appear.
3. Keep iterating until you find a node with no left child or right child.
4. After that, check if all remaining nodes in the queue also have no children. If yes, then the given tree is a complete binary tree. Otherwise, it's not.

The time complexity of this algorithm is O(n), where n is the number of nodes in the binary tree, as each node is visited once.

## A solution in Python

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

def is_complete_tree(root: TreeNode) -> bool:
    if not root:
        return True

    queue = [root]
    while queue[0]:
        node = queue.pop(0)
        queue.append(node.left)
        queue.append(node.right)
    while queue and not queue[0]:
        queue.pop(0)
    return not queue
```
To check if the given binary tree is a complete binary tree, we can use a method called Breadth First Search (BFS) or level-order traversal.

1. Start by creating a queue and adding the root node to it.
2. Then, use a loop to iterate through nodes in the queue. For each node, dequeue it, and enqueue its left and right children (if any) in the order they appear.
3. Keep iterating until you find a node with no left child or right child.
4. After that, check if all remaining nodes in the queue also have no children. If yes, then the given tree is a complete binary tree. Otherwise, it's not.

The time complexity of this algorithm is O(n), where n is the number of nodes in the binary tree, as each node is visited once.

## A solution in Javascript

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

function isCompleteTree(root) {
    if (!root) return true;

    let queue = [root];
    let hasGap = false;
    while (queue.length) {
        let node = queue.shift();
        if (node.left) {
            if (hasGap) return false;
            queue.push(node.left);
        } else {
            hasGap = true;
        }
        if (node.right) {
            if (hasGap) return false;
            queue.push(node.right);
        } else {
            hasGap = true;
        }
    }
    return true;
}
```
To check if the given binary tree is a complete binary tree, we can use a method called Breadth First Search (BFS) or level-order traversal.

1. Start by creating a queue and adding the root node to it.
2. Then, use a loop to iterate through nodes in the queue. For each node, dequeue it, and enqueue its left and right children (if any) in the order they appear.
3. Keep iterating until you find a node with no left child or right child.
4. After that, check if all remaining nodes in the queue also have no children. If yes, then the given tree is a complete binary tree. Otherwise, it's not.

The time complexity of this algorithm is O(n), where n is the number of nodes in the binary tree, as each node is visited once.


# Minimum Cost to Merge Stones

- slug: minimum-cost-to-merge-stones
- difficulty: Hard

There are `n` piles of `stones` arranged in a row. The `ith` pile has `stones[i]` stones.

A move consists of merging exactly `k` **consecutive** piles into one pile, and the cost of this move is equal to the total number of stones in these `k` piles.

Return _the minimum cost to merge all piles of stones into one pile_. If it is impossible, return `-1`.

**Example 1:**

**Input:** stones = \[3,2,4,1\], k = 2
**Output:** 20
**Explanation:** We start with \[3, 2, 4, 1\].
We merge \[3, 2\] for a cost of 5, and we are left with \[5, 4, 1\].
We merge \[4, 1\] for a cost of 5, and we are left with \[5, 5\].
We merge \[5, 5\] for a cost of 10, and we are left with \[10\].
The total cost was 20, and this is the minimum possible.

**Example 2:**

**Input:** stones = \[3,2,4,1\], k = 3
**Output:** -1
**Explanation:** After any merge operation, there are 2 piles left, and we can't merge anymore.  So the task is impossible.

**Example 3:**

**Input:** stones = \[3,5,1,2,6\], k = 3
**Output:** 25
**Explanation:** We start with \[3, 5, 1, 2, 6\].
We merge \[5, 1, 2\] for a cost of 8, and we are left with \[3, 8, 6\].
We merge \[3, 8, 6\] for a cost of 17, and we are left with \[17\].
The total cost was 25, and this is the minimum possible.

**Constraints:**

*   `n == stones.length`
*   `1 <= n <= 30`
*   `1 <= stones[i] <= 100`
*   `2 <= k <= 30`

## A solution in Java

```java
public int minDeletionSize(String[] strs) {
    int rows = strs.length, cols = strs[0].length();
    int count = 0;
    for (int c = 0; c < cols; ++c) {
        for (int r = 1; r < rows; ++r) {
            if (strs[r - 1].charAt(c) > strs[r].charAt(c)) {
                ++count;
                break;
            }
        }
    }
    return count;
}
```
For a given set of strings, we need to find how many characters can be deleted so that each remaining string is in lexicographic order. To achieve this, we iterate through each column (character position) of the strings and compare each character in the current column to its adjacent one in the next row. If the character violates lexicographic order, we increment the deletion count and move to the next column. We do this for all columns and return the minimum number of character deletions required to satisfy the conditions mentioned.

## A solution in C++

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

int minDeletionSize(std::vector<std::string>& strs) {
    int rows = strs.size(), cols = strs[0].size();
    int count = 0;
    for (int c = 0; c < cols; ++c) {
        for (int r = 1; r < rows; ++r) {
            if (strs[r - 1][c] > strs[r][c]) {
                ++count;
                break;
            }
        }
    }
    return count;
}
```
For a given set of strings, we need to find how many characters can be deleted so that each remaining string is in lexicographic order. To achieve this, we iterate through each column (character position) of the strings and compare each character in the current column to its adjacent one in the next row. If the character violates lexicographic order, we increment the deletion count and move to the next column. We do this for all columns and return the minimum number of character deletions required to satisfy the conditions mentioned.

## A solution in Python

```python
def min_deletion_size(strs):
    rows, cols = len(strs), len(strs[0])
    count = 0
    for c in range(cols):
        for r in range(1, rows):
            if strs[r - 1][c] > strs[r][c]:
                count += 1
                break
    return count
```
For a given set of strings, we need to find how many characters can be deleted so that each remaining string is in lexicographic order. To achieve this, we iterate through each column (character position) of the strings and compare each character in the current column to its adjacent one in the next row. If the character violates lexicographic order, we increment the deletion count and move to the next column. We do this for all columns and return the minimum number of character deletions required to satisfy the conditions mentioned.

## A solution in Javascript

```javascript
function minDeletionSize(strs) {
    const rows = strs.length;
    const cols = strs[0].length;
    let count = 0;
    for (let c = 0; c < cols; ++c) {
        for (let r = 1; r < rows; ++r) {
            if (strs[r - 1][c] > strs[r][c]) {
                ++count;
                break;
            }
        }
    }
    return count;
}
```
For a given set of strings, we need to find how many characters can be deleted so that each remaining string is in lexicographic order. To achieve this, we iterate through each column (character position) of the strings and compare each character in the current column to its adjacent one in the next row. If the character violates lexicographic order, we increment the deletion count and move to the next column. We do this for all columns and return the minimum number of character deletions required to satisfy the conditions mentioned.


# Grid Illumination

- slug: grid-illumination
- difficulty: Hard

There is a 2D `grid` of size `n x n` where each cell of this grid has a lamp that is initially **turned off**.

You are given a 2D array of lamp positions `lamps`, where `lamps[i] = [rowi, coli]` indicates that the lamp at `grid[rowi][coli]` is **turned on**. Even if the same lamp is listed more than once, it is turned on.

When a lamp is turned on, it **illuminates its cell** and **all other cells** in the same **row, column, or diagonal**.

You are also given another 2D array `queries`, where `queries[j] = [rowj, colj]`. For the `jth` query, determine whether `grid[rowj][colj]` is illuminated or not. After answering the `jth` query, **turn off** the lamp at `grid[rowj][colj]` and its **8 adjacent lamps** if they exist. A lamp is adjacent if its cell shares either a side or corner with `grid[rowj][colj]`.

Return _an array of integers_ `ans`_,_ _where_ `ans[j]` _should be_ `1` _if the cell in the_ `jth` _query was illuminated, or_ `0` _if the lamp was not._

**Example 1:**

**Input:** n = 5, lamps = \[\[0,0\],\[4,4\]\], queries = \[\[1,1\],\[1,0\]\]
**Output:** \[1,0\]
**Explanation:** We have the initial grid with all lamps turned off. In the above picture we see the grid after turning on the lamp at grid\[0\]\[0\] then turning on the lamp at grid\[4\]\[4\].
The 0th query asks if the lamp at grid\[1\]\[1\] is illuminated or not (the blue square). It is illuminated, so set ans\[0\] = 1. Then, we turn off all lamps in the red square.

The 1st query asks if the lamp at grid\[1\]\[0\] is illuminated or not (the blue square). It is not illuminated, so set ans\[1\] = 0. Then, we turn off all lamps in the red rectangle.

**Example 2:**

**Input:** n = 5, lamps = \[\[0,0\],\[4,4\]\], queries = \[\[1,1\],\[1,1\]\]
**Output:** \[1,1\]

**Example 3:**

**Input:** n = 5, lamps = \[\[0,0\],\[0,4\]\], queries = \[\[0,4\],\[0,1\],\[1,4\]\]
**Output:** \[1,1,0\]

**Constraints:**

*   `1 <= n <= 109`
*   `0 <= lamps.length <= 20000`
*   `0 <= queries.length <= 20000`
*   `lamps[i].length == 2`
*   `0 <= rowi, coli < n`
*   `queries[j].length == 2`
*   `0 <= rowj, colj < n`

## A solution in Java

```java
public int repeatedNTimes(int[] nums) {
    Map<Integer, Integer> hashMap = new HashMap<>();
    for (int num : nums) {
        hashMap.put(num, hashMap.getOrDefault(num, 0) + 1);
        if (hashMap.get(num) > 1) return num;
    }
    return -1;
}
```
The algorithm works in a simple way:

1. Create an empty hash map to store the count of each number in the input array.
2. Iterate through the input array nums.
3. For each number in nums, increment its count in the hash map. If the count becomes greater than 1, return the number as it's the repeated element n times.

The algorithm has a linear time complexity by iterating through the input array once, and it uses a hash map to count the frequency of each element.

## A solution in C++

```cpp
int repeatedNTimes(vector<int>& nums) {
    unordered_map<int, int> hashMap;
    for (int num : nums) {
        if (++hashMap[num] > 1) return num;
    }
}
```
The algorithm works in a simple way:

1. Create an empty hash map to store the count of each number in the input array.
2. Iterate through the input array nums.
3. For each number in nums, increment its count in the hash map. If the count becomes greater than 1, return the number as it's the repeated element n times.

The algorithm has a linear time complexity by iterating through the input array once, and it uses a hash map to count the frequency of each element.

## A solution in Python

```python
def repeatedNTimes(nums):
    hash_map = {}
    for num in nums:
        if num in hash_map:
            return num
        else:
            hash_map[num] = 1
```
The algorithm works in a simple way:

1. Create an empty hash map to store the count of each number in the input array.
2. Iterate through the input array nums.
3. For each number in nums, increment its count in the hash map. If the count becomes greater than 1, return the number as it's the repeated element n times.

The algorithm has a linear time complexity by iterating through the input array once, and it uses a hash map to count the frequency of each element.

## A solution in Javascript

```javascript
function repeatedNTimes(nums) {
    const hashMap = {};
    for (const num of nums) {
        if (hashMap[num]) return num;
        hashMap[num] = 1;
    }
}
```
The algorithm works in a simple way:

1. Create an empty hash map to store the count of each number in the input array.
2. Iterate through the input array nums.
3. For each number in nums, increment its count in the hash map. If the count becomes greater than 1, return the number as it's the repeated element n times.

The algorithm has a linear time complexity by iterating through the input array once, and it uses a hash map to count the frequency of each element.


# Find Common Characters

- slug: find-common-characters
- difficulty: Easy

Given a string array `words`, return _an array of all characters that show up in all strings within the_ `words` _(including duplicates)_. You may return the answer in **any order**.

**Example 1:**

**Input:** words = \["bella","label","roller"\]
**Output:** \["e","l","l"\]

**Example 2:**

**Input:** words = \["cool","lock","cook"\]
**Output:** \["c","o"\]

**Constraints:**

*   `1 <= words.length <= 100`
*   `1 <= words[i].length <= 100`
*   `words[i]` consists of lowercase English letters.

## A solution in Java

```java
import java.util.*;

public int maxWidthRamp(int[] nums) {
    Integer[] indices = new Integer[nums.length];
    for (int i = 0; i < nums.length; i++) {
        indices[i] = i;
    }

    Arrays.sort(indices, (i, j) -> nums[i] == nums[j] ? i - j : nums[i] - nums[j]);

    int maxWidth = 0;
    int minIndex = Integer.MAX_VALUE;
    for (int index : indices) {
        maxWidth = Math.max(maxWidth, index - minIndex);
        minIndex = Math.min(minIndex, index);
    }

    return maxWidth;
}
```
1. First, create an array of indices of the input array.
2. Sort the indices based on its corresponding value in the input array. In case of equal values, sort based on the index itself.
3. Initialize maxWidth (maximum width of ramp) with 0 and minIndex (smallest index encountered so far) with maximum integer value.
4. Iterate through the sorted indices array. Each iteration, calculate the width between the current index and minIndex, and update maxWidth if the calculated width is greater than the current max width. Update minIndex with the smallest value between the current index and minIndex.
5. At the end of the iteration, maxWidth will hold the maximum width of a ramp in the nums array, and this value is returned.

## A solution in C++

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

int maxWidthRamp(std::vector<int>& nums) {
    std::vector<int> indices(nums.size());
    for (int i = 0; i < nums.size(); ++i) {
        indices[i] = i;
    }

    std::sort(indices.begin(), indices.end(), [&](int i, int j) {
        return nums[i] == nums[j] ? i < j : nums[i] < nums[j];
    });

    int maxWidth = 0;
    int minIndex = std::numeric_limits<int>::max();
    for (int index : indices) {
        maxWidth = std::max(maxWidth, index - minIndex);
        minIndex = std::min(minIndex, index);
    }

    return maxWidth;
}
```
1. First, create an array of indices of the input array.
2. Sort the indices based on its corresponding value in the input array. In case of equal values, sort based on the index itself.
3. Initialize maxWidth (maximum width of ramp) with 0 and minIndex (smallest index encountered so far) with maximum integer value.
4. Iterate through the sorted indices array. Each iteration, calculate the width between the current index and minIndex, and update maxWidth if the calculated width is greater than the current max width. Update minIndex with the smallest value between the current index and minIndex.
5. At the end of the iteration, maxWidth will hold the maximum width of a ramp in the nums array, and this value is returned.

## A solution in Python

```javascript
function maxWidthRamp(nums) {
    const indices = [...Array(nums.length).keys()].sort((i, j) => {
        return nums[i] === nums[j] ? i - j : nums[i] - nums[j];
    });

    let maxWidth = 0;
    let minIndex = Infinity;
    for (const index of indices) {
        maxWidth = Math.max(maxWidth, index - minIndex);
        minIndex = Math.min(minIndex, index);
    }

    return maxWidth;
}
```
1. First, create an array of indices of the input array.
2. Sort the indices based on its corresponding value in the input array. In case of equal values, sort based on the index itself.
3. Initialize maxWidth (maximum width of ramp) with 0 and minIndex (smallest index encountered so far) with maximum integer value.
4. Iterate through the sorted indices array. Each iteration, calculate the width between the current index and minIndex, and update maxWidth if the calculated width is greater than the current max width. Update minIndex with the smallest value between the current index and minIndex.
5. At the end of the iteration, maxWidth will hold the maximum width of a ramp in the nums array, and this value is returned.

## A solution in Javascript

```python
def maxWidthRamp(nums):
    indices = sorted(range(len(nums)), key=lambda i: (nums[i], i))

    maxWidth = 0
    minIndex = float('inf')
    for index in indices:
        maxWidth = max(maxWidth, index - minIndex)
        minIndex = min(minIndex, index)

    return maxWidth
```
1. First, create an array of indices of the input array.
2. Sort the indices based on its corresponding value in the input array. In case of equal values, sort based on the index itself.
3. Initialize maxWidth (maximum width of ramp) with 0 and minIndex (smallest index encountered so far) with maximum integer value.
4. Iterate through the sorted indices array. Each iteration, calculate the width between the current index and minIndex, and update maxWidth if the calculated width is greater than the current max width. Update minIndex with the smallest value between the current index and minIndex.
5. At the end of the iteration, maxWidth will hold the maximum width of a ramp in the nums array, and this value is returned.


# Check If Word Is Valid After Substitutions

- slug: check-if-word-is-valid-after-substitutions
- difficulty: Medium

Given a string `s`, determine if it is **valid**.

A string `s` is **valid** if, starting with an empty string `t = " "`, you can **transform** `t` **into** `s` after performing the following operation **any number of times**:

*   Insert string `"abc "` into any position in `t`. More formally, `t` becomes `tleft + "abc " + tright`, where `t == tleft + tright`. Note that `tleft` and `tright` may be **empty**.

Return `true` _if_ `s` _is a **valid** string, otherwise, return_ `false`.

**Example 1:**

**Input:** s =  "aabcbc "
**Output:** true
**Explanation:**
 " " ->  "abc " ->  "aabcbc "
Thus,  "aabcbc " is valid.

**Example 2:**

**Input:** s =  "abcabcababcc "
**Output:** true
**Explanation:**
 " " ->  "abc " ->  "abcabc " ->  "abcabcabc " ->  "abcabcababcc "
Thus,  "abcabcababcc " is valid.

**Example 3:**

**Input:** s =  "abccba "
**Output:** false
**Explanation:** It is impossible to get  "abccba " using the operation.

**Constraints:**

*   `1 <= s.length <= 2 * 104`
*   `s` consists of letters `'a'`, `'b'`, and `'c'`

## A solution in Java

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

public double minAreaFreeRect(int[][] points) {
    double minArea = Double.POSITIVE_INFINITY;
    Map<Integer, Set<Integer>> xGroups = new HashMap<>();

    for (int[] point : points) {
        xGroups.computeIfAbsent(point[0], k -> new HashSet<>()).add(point[1]);
    }

    for (Map.Entry<Integer, Set<Integer>> x1Entry : xGroups.entrySet()) {
        for (Map.Entry<Integer, Set<Integer>> x2Entry : xGroups.entrySet()) {
            int x1 = x1Entry.getKey(), x2 = x2Entry.getKey();
            if (x1 == x2) continue;

            Set<Integer> ys1 = x1Entry.getValue(), ys2 = x2Entry.getValue();
            for (int y1 : ys1) {
                for (int y2 : ys2) {
                    if (ys1.contains(y2) && ys2.contains(y1)) {
                        double area = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)) * Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y1, 2));
                        minArea = Math.min(minArea, area);
                    }
                }
            }
        }
    }

    return minArea == Double.POSITIVE_INFINITY ? 0 : minArea;
}
```
1. Create a dictionary (hash map) to store the Y values for each unique X value.
2. Iterate through all possible pairs of X values. For each pair, iterate through all possible combinations of Y values for this pair.
3. Check if the four points defined by the two X values and two Y values can form a rectangle by checking if the Y values exist for both X values. If they can form a rectangle, calculate the area and compare it with the current minimum area found.
4. Return the minimum area found or 0 if no rectangle was found.

## A solution in C++

```cpp
#include <unordered_map>
#include <set>
#include <cmath>
#include <vector>
#include <limits>

using namespace std;

double minAreaFreeRect(vector<vector<int>>& points) {
    double minArea = numeric_limits<double>::infinity();
    unordered_map<int, set<int>> xGroups;

    for (const auto& point : points) {
        xGroups[point[0]].insert(point[1]);
    }

    for (const auto& [x1, ys1] : xGroups) {
        for (const auto& [x2, ys2] : xGroups) {
            if (x1 == x2) continue;

            for (int y1 : ys1) {
                for (int y2 : ys2) {
                    if (ys1.find(y2) != ys1.end() && ys2.find(y1) != ys2.end()) {
                        double area = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2)) * sqrt(pow(x1 - x2, 2) + pow(y1 - y1, 2));
                        minArea = min(minArea, area);
                    }
                }
            }
        }
    }

    return minArea == numeric_limits<double>::infinity() ? 0 : minArea;
}
```
1. Create a dictionary (hash map) to store the Y values for each unique X value.
2. Iterate through all possible pairs of X values. For each pair, iterate through all possible combinations of Y values for this pair.
3. Check if the four points defined by the two X values and two Y values can form a rectangle by checking if the Y values exist for both X values. If they can form a rectangle, calculate the area and compare it with the current minimum area found.
4. Return the minimum area found or 0 if no rectangle was found.

## A solution in Python

```python
from collections import defaultdict
from math import sqrt, inf

def minAreaFreeRect(points):
    minArea = inf
    xGroups = defaultdict(set)

    for x, y in points:
        xGroups[x].add(y)

    for x1, ys1 in xGroups.items():
        for x2, ys2 in xGroups.items():
            if x1 == x2:
                continue

            for y1 in ys1:
                for y2 in ys2:
                    if y2 in ys1 and y1 in ys2:
                        area = sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2) * sqrt((x1 - x2) ** 2 + (y1 - y1) ** 2)
                        minArea = min(minArea, area)

    return minArea if minArea != inf else 0
```
1. Create a dictionary (hash map) to store the Y values for each unique X value.
2. Iterate through all possible pairs of X values. For each pair, iterate through all possible combinations of Y values for this pair.
3. Check if the four points defined by the two X values and two Y values can form a rectangle by checking if the Y values exist for both X values. If they can form a rectangle, calculate the area and compare it with the current minimum area found.
4. Return the minimum area found or 0 if no rectangle was found.

## A solution in Javascript

```javascript
function minAreaFreeRect(points) {
    let minArea = Infinity;
    const xGroups = new Map();

    for (const [x, y] of points) {
        if (!xGroups.has(x)) {
            xGroups.set(x, new Set());
        }
        xGroups.get(x).add(y);
    }

    for (const [x1, ys1] of xGroups.entries()) {
        for (const [x2, ys2] of xGroups.entries()) {
            if (x1 === x2) continue;

            for (const y1 of ys1) {
                for (const y2 of ys2) {
                    if (ys1.has(y2) && ys2.has(y1)) {
                        const area = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)) * Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y1, 2));
                        minArea = Math.min(minArea, area);
                    }
                }
            }
        }
    }

    return minArea === Infinity ? 0 : minArea;
}
```
1. Create a dictionary (hash map) to store the Y values for each unique X value.
2. Iterate through all possible pairs of X values. For each pair, iterate through all possible combinations of Y values for this pair.
3. Check if the four points defined by the two X values and two Y values can form a rectangle by checking if the Y values exist for both X values. If they can form a rectangle, calculate the area and compare it with the current minimum area found.
4. Return the minimum area found or 0 if no rectangle was found.


# Max Consecutive Ones III

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

Given a binary array `nums` and an integer `k`, return _the maximum number of consecutive_ `1`_'s in the array if you can flip at most_ `k` `0`'s.

**Example 1:**

**Input:** nums = \[1,1,1,0,0,0,1,1,1,1,0\], k = 2
**Output:** 6
**Explanation:** \[1,1,1,0,0,**1**,1,1,1,1,**1**\]
Bolded numbers were flipped from 0 to 1. The longest subarray is underlined.

**Example 2:**

**Input:** nums = \[0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1\], k = 3
**Output:** 10
**Explanation:** \[0,0,1,1,**1**,**1**,1,1,1,**1**,1,1,0,0,0,1,1,1,1\]
Bolded numbers were flipped from 0 to 1. The longest subarray is underlined.

**Constraints:**

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

## A solution in Java

```java
public int leastOpsExpressTarget(int x, int target) {
    if (x == target) return 0;
    if (target == 1) return 1;
    if (x > target) return Math.min(2 * target - 1, 2 * (x - target));

    int k = 0;
    long p = x;
    while (p < target) {
        k++;
        p *= x;
    }

    int ans = Integer.MAX_VALUE;
    long d = 1;

    for (int i = k - 1; i >= 0; i--) {
        while (p >= target + d * (1 - x)) {
            p -= d;
            ans = Math.min(ans, i + (int) (Math.log(target / d) / Math.log(2) + 1) + (int) (d == 1 ? -1 : 0));
        }
        d = d * x + 1;
    }

    return ans;
}
```
1. If x is equal to the target, we don't need any operation, so we return 0.
2. If the target is equal to 1, we need only 1 operation (+ or - x), so we return 1.
3. If x is greater than the target, we need 2 * (target - 1) or 2 * (x - target) operations to build the target.
4. The main idea of the algorithm is to analyze the potential range within which we can build the expression by multiplying the base x value.
5. We use the logarithm to reduce the numbers and find the minimum number of operations to reach the target in this range.
6. We keep updating the minimum number of operations while traversing through the loop.
7. In the end, we return the minimum number of operations.

## A solution in C++

```cpp
int leastOpsExpressTarget(int x, int target) {
    if (x == target) return 0;
    if (target == 1) return 1;
    if (x > target) return min(2 * target - 1, 2 * (x - target));

    int k = 0;
    long long p = x;
    while (p < target) {
        k++;
        p *= x;
    }

    int ans = INT_MAX;
    long long d = 1;

    for (int i = k - 1; i >= 0; i--) {
        while (p >= target + d * (1 - x)) {
            p -= d;
            ans = min(ans, i + (int) (log2(target / d) + 1) + (int) (d == 1 ? -1 : 0));
        }
        d = d * x + 1;
    }

    return ans;
}
```
1. If x is equal to the target, we don't need any operation, so we return 0.
2. If the target is equal to 1, we need only 1 operation (+ or - x), so we return 1.
3. If x is greater than the target, we need 2 * (target - 1) or 2 * (x - target) operations to build the target.
4. The main idea of the algorithm is to analyze the potential range within which we can build the expression by multiplying the base x value.
5. We use the logarithm to reduce the numbers and find the minimum number of operations to reach the target in this range.
6. We keep updating the minimum number of operations while traversing through the loop.
7. In the end, we return the minimum number of operations.

## A solution in Python

```python
def least_ops_express_target(x, target):
    if x == target:
        return 0
    if target == 1:
        return 1
    if x > target:
        return min(2 * target - 1, 2 * (x - target))

    k = 0
    p = x
    while p < target:
        k += 1
        p *= x

    ans = float('inf')
    d = 1

    for i in range(k - 1, -1, -1):
        while p >= target + d * (1 - x):
            p -= d
            ans = min(ans, i + int(math.log2(target // d) + 1) + int(d == 1 and -1 or 0))
        d = d * x + 1

    return ans
```
1. If x is equal to the target, we don't need any operation, so we return 0.
2. If the target is equal to 1, we need only 1 operation (+ or - x), so we return 1.
3. If x is greater than the target, we need 2 * (target - 1) or 2 * (x - target) operations to build the target.
4. The main idea of the algorithm is to analyze the potential range within which we can build the expression by multiplying the base x value.
5. We use the logarithm to reduce the numbers and find the minimum number of operations to reach the target in this range.
6. We keep updating the minimum number of operations while traversing through the loop.
7. In the end, we return the minimum number of operations.

## A solution in Javascript

```javascript
function leastOpsExpressTarget(x, target) {
    if (x === target) return 0;
    if (target === 1) return 1;
    if (x > target) return Math.min(2 * target - 1, 2 * (x - target));

    let k = 0;
    let p = x;
    while (p < target) {
        k++;
        p *= x;
    }

    let ans = Infinity;
    let d = 1;

    for (let i = k - 1; i >= 0; i--) {
        while (p >= target + d * (1 - x)) {
            p -= d;
            ans = Math.min(ans, i + Math.floor(Math.log2(target / d) + 1) + (d === 1 ? -1 : 0));
        }
        d = d * x + 1;
    }

    return ans;
}
```
1. If x is equal to the target, we don't need any operation, so we return 0.
2. If the target is equal to 1, we need only 1 operation (+ or - x), so we return 1.
3. If x is greater than the target, we need 2 * (target - 1) or 2 * (x - target) operations to build the target.
4. The main idea of the algorithm is to analyze the potential range within which we can build the expression by multiplying the base x value.
5. We use the logarithm to reduce the numbers and find the minimum number of operations to reach the target in this range.
6. We keep updating the minimum number of operations while traversing through the loop.
7. In the end, we return the minimum number of operations.


# Maximize Sum Of Array After K Negations

- slug: maximize-sum-of-array-after-k-negations
- difficulty: Easy

Given an integer array `nums` and an integer `k`, modify the array in the following way:

*   choose an index `i` and replace `nums[i]` with `-nums[i]`.

You should apply this process exactly `k` times. You may choose the same index `i` multiple times.

Return _the largest possible sum of the array after modifying it in this way_.

**Example 1:**

**Input:** nums = \[4,2,3\], k = 1
**Output:** 5
**Explanation:** Choose index 1 and nums becomes \[4,-2,3\].

**Example 2:**

**Input:** nums = \[3,-1,0,2\], k = 3
**Output:** 6
**Explanation:** Choose indices (1, 2, 2) and nums becomes \[3,1,0,2\].

**Example 3:**

**Input:** nums = \[2,-3,-1,5,-4\], k = 2
**Output:** 13
**Explanation:** Choose indices (1, 4) and nums becomes \[2,3,-1,5,4\].

**Constraints:**

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

## A solution in Java

```java
public boolean isUnivalued(TreeNode root) {
    return isUnivalued(root, -1);
}

private boolean isUnivalued(TreeNode root, int val) {
    if (root == null) return true;
    if (val == -1) val = root.val;
    return root.val == val && isUnivalued(root.left, val) && isUnivalued(root.right, val);
}
```
The algorithm first checks if the root node is null, if it is, the function returns true as an empty tree is uni-valued. If this is the first call to the function (indicated by default value for val), it sets the val to the root node's value. For all other calls, val is already set, and it only checks if the current node's value is equal to val. If it is equal, it recursively calls for the left and right sub-trees. If all calls return true, the tree is uni-valued, otherwise it's not.

## A solution in C++

```cpp
bool isUnivalued(TreeNode* root, int val = -1) {
    if (!root) return true;
    if (val == -1) val = root->val;
    return root->val == val && isUnivalued(root->left, val) && isUnivalued(root->right, val);
}
```
The algorithm first checks if the root node is null, if it is, the function returns true as an empty tree is uni-valued. If this is the first call to the function (indicated by default value for val), it sets the val to the root node's value. For all other calls, val is already set, and it only checks if the current node's value is equal to val. If it is equal, it recursively calls for the left and right sub-trees. If all calls return true, the tree is uni-valued, otherwise it's not.

## A solution in Python

```python
def is_univalued(root, val=None):
    if not root:
        return True
    if val is None:
        val = root.val
    return root.val == val and is_univalued(root.left, val) and is_univalued(root.right, val)
```
The algorithm first checks if the root node is null, if it is, the function returns true as an empty tree is uni-valued. If this is the first call to the function (indicated by default value for val), it sets the val to the root node's value. For all other calls, val is already set, and it only checks if the current node's value is equal to val. If it is equal, it recursively calls for the left and right sub-trees. If all calls return true, the tree is uni-valued, otherwise it's not.

## A solution in Javascript

```javascript
function isUnivalued(root, val = null) {
    if (!root) return true;
    if (val === null) val = root.val;
    return root.val === val && isUnivalued(root.left, val) && isUnivalued(root.right, val);
}
```
The algorithm first checks if the root node is null, if it is, the function returns true as an empty tree is uni-valued. If this is the first call to the function (indicated by default value for val), it sets the val to the root node's value. For all other calls, val is already set, and it only checks if the current node's value is equal to val. If it is equal, it recursively calls for the left and right sub-trees. If all calls return true, the tree is uni-valued, otherwise it's not.


# Clumsy Factorial

- slug: clumsy-factorial
- difficulty: Medium

The **factorial** of a positive integer `n` is the product of all positive integers less than or equal to `n`.

*   For example, `factorial(10) = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1`.

We make a **clumsy factorial** using the integers in decreasing order by swapping out the multiply operations for a fixed rotation of operations with multiply `'*'`, divide `'/'`, add `'+'`, and subtract `'-'` in this order.

*   For example, `clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1`.

However, these operations are still applied using the usual order of operations of arithmetic. We do all multiplication and division steps before any addition or subtraction steps, and multiplication and division steps are processed left to right.

Additionally, the division that we use is floor division such that `10 * 9 / 8 = 90 / 8 = 11`.

Given an integer `n`, return _the clumsy factorial of_ `n`.

**Example 1:**

**Input:** n = 4
**Output:** 7
**Explanation:** 7 = 4 \* 3 / 2 + 1

**Example 2:**

**Input:** n = 10
**Output:** 12
**Explanation:** 12 = 10 \* 9 / 8 + 7 - 6 \* 5 / 4 + 3 - 2 \* 1

**Constraints:**

*   `1 <= n <= 104`

## A solution in Java

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

public List<String> spellchecker(String[] wordlist, String[] queries) {
    Map<String, String> wordMap = new HashMap<>();
    Map<String, String> wordMapLowerCase = new HashMap<>();
    Map<String, String> wordMapVowelReplaced = new HashMap<>();

    for (String word : wordlist) {
        String lowerWord = word.toLowerCase();
        String vowelReplacedWord = lowerWord.replaceAll("[aeiou]", "#");

        wordMap.putIfAbsent(word, word);
        wordMapLowerCase.putIfAbsent(lowerWord, word);
        wordMapVowelReplaced.putIfAbsent(vowelReplacedWord, word);
    }

    List<String> result = new ArrayList<>();
    for (String query : queries) {
        String lowerQuery = query.toLowerCase();
        String vowelReplacedQuery = lowerQuery.replaceAll("[aeiou]", "#");

        if (wordMap.containsKey(query)) {
            result.add(wordMap.get(query));
        } else if (wordMapLowerCase.containsKey(lowerQuery)) {
            result.add(wordMapLowerCase.get(lowerQuery));
        } else if (wordMapVowelReplaced.containsKey(vowelReplacedQuery)) {
            result.add(wordMapVowelReplaced.get(vowelReplacedQuery));
        } else {
            result.add("");
        }
    }

    return result;
}
```
The algorithm first creates 3 maps: `wordMap`, `wordMapLowerCase`, and `wordMapVowelReplaced`. `wordMap` stores the exact word from the wordlist, `wordMapLowerCase` stores words in lowercase (if it wasn't already stored), and `wordMapVowelReplaced` stores words with vowels replaced by `#` (if it wasn't already stored). The maps are built specifically to satisfy the spellchecker rules.

The spellchecker iterates through the queries and performs the following operations on each query: lowercase conversion and vowel replacement with `#`. Then, using an if-else branching and the three hash maps created earlier, the algorithm checks for matching words and populates the result array based on the spellchecker rules in the order of precedence specified.

Once all queries have been processed, the result array is returned.

## A solution in C++

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

std::vector<std::string> spellchecker(std::vector<std::string>& wordlist, std::vector<std::string>& queries) {
    std::unordered_map<std::string, std::string> wordMap;
    std::unordered_map<std::string, std::string> wordMapLowerCase;
    std::unordered_map<std::string, std::string> wordMapVowelReplaced;

    for (const auto &word : wordlist) {
        std::string lowerWord = word;
        for (auto &ch : lowerWord) ch = tolower(ch);
        std::string vowelReplacedWord = lowerWord;
        for (auto &ch : vowelReplacedWord)
            if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') ch = '#';

        wordMap[word] = word;
        if (!wordMapLowerCase.count(lowerWord)) wordMapLowerCase[lowerWord] = word;
        if (!wordMapVowelReplaced.count(vowelReplacedWord)) wordMapVowelReplaced[vowelReplacedWord] = word;
    }

    std::vector<std::string> result;
    for (const auto &query : queries) {
        std::string lowerQuery = query;
        for (auto &ch : lowerQuery) ch = tolower(ch);
        std::string vowelReplacedQuery = lowerQuery;
        for (auto &ch : vowelReplacedQuery)
            if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') ch = '#';

        if (wordMap.count(query)) {
            result.push_back(wordMap[query]);
        } else if (wordMapLowerCase.count(lowerQuery)) {
            result.push_back(wordMapLowerCase[lowerQuery]);
        } else if (wordMapVowelReplaced.count(vowelReplacedQuery)) {
            result.push_back(wordMapVowelReplaced[vowelReplacedQuery]);
        } else {
            result.push_back("");
        }
    }

    return result;
}
```
The algorithm first creates 3 maps: `wordMap`, `wordMapLowerCase`, and `wordMapVowelReplaced`. `wordMap` stores the exact word from the wordlist, `wordMapLowerCase` stores words in lowercase (if it wasn't already stored), and `wordMapVowelReplaced` stores words with vowels replaced by `#` (if it wasn't already stored). The maps are built specifically to satisfy the spellchecker rules.

The spellchecker iterates through the queries and performs the following operations on each query: lowercase conversion and vowel replacement with `#`. Then, using an if-else branching and the three hash maps created earlier, the algorithm checks for matching words and populates the result array based on the spellchecker rules in the order of precedence specified.

Once all queries have been processed, the result array is returned.

## A solution in Python

```python
def spellchecker(wordlist, queries):
    word_map = {word: word for word in wordlist}
    word_map_lower_case = {word.lower(): word for word in wordlist if word.lower() not in word_map_lower_case}
    word_map_vowel_replaced = {replace_vowels(word.lower()): word for word in wordlist if replace_vowels(word.lower()) not in word_map_vowel_replaced}

    result = []
    for query in queries:
        lower_query = query.lower()
        vowel_replaced_query = replace_vowels(lower_query)

        if query in word_map:
            result.append(word_map[query])
        elif lower_query in word_map_lower_case:
            result.append(word_map_lower_case[lower_query])
        elif vowel_replaced_query in word_map_vowel_replaced:
            result.append(word_map_vowel_replaced[vowel_replaced_query])
        else:
            result.append("")

    return result

def replace_vowels(word):
    return ''.join(['#' if ch in 'aeiou' else ch for ch in word])
```
The algorithm first creates 3 maps: `wordMap`, `wordMapLowerCase`, and `wordMapVowelReplaced`. `wordMap` stores the exact word from the wordlist, `wordMapLowerCase` stores words in lowercase (if it wasn't already stored), and `wordMapVowelReplaced` stores words with vowels replaced by `#` (if it wasn't already stored). The maps are built specifically to satisfy the spellchecker rules.

The spellchecker iterates through the queries and performs the following operations on each query: lowercase conversion and vowel replacement with `#`. Then, using an if-else branching and the three hash maps created earlier, the algorithm checks for matching words and populates the result array based on the spellchecker rules in the order of precedence specified.

Once all queries have been processed, the result array is returned.

## A solution in Javascript

```javascript
function spellchecker(wordlist, queries) {
    const wordMap = {};
    const wordMapLowerCase = {};
    const wordMapVowelReplaced = {};

    for (const word of wordlist) {
        const lowerWord = word.toLowerCase();
        const vowelReplacedWord = lowerWord.replace(/[aeiou]/g, "#");

        if (!wordMap[word]) wordMap[word] = word;
        if (!wordMapLowerCase[lowerWord]) wordMapLowerCase[lowerWord] = word;
        if (!wordMapVowelReplaced[vowelReplacedWord]) wordMapVowelReplaced[vowelReplacedWord] = word;
    }

    const result = [];
    for (const query of queries) {
        const lowerQuery = query.toLowerCase();
        const vowelReplacedQuery = lowerQuery.replace(/[aeiou]/g, "#");

        if (wordMap[query]) {
            result.push(wordMap[query]);
        } else if (wordMapLowerCase[lowerQuery]) {
            result.push(wordMapLowerCase[lowerQuery]);
        } else if (wordMapVowelReplaced[vowelReplacedQuery]) {
            result.push(wordMapVowelReplaced[vowelReplacedQuery]);
        } else {
            result.push("");
        }
    }

    return result;
}
```
The algorithm first creates 3 maps: `wordMap`, `wordMapLowerCase`, and `wordMapVowelReplaced`. `wordMap` stores the exact word from the wordlist, `wordMapLowerCase` stores words in lowercase (if it wasn't already stored), and `wordMapVowelReplaced` stores words with vowels replaced by `#` (if it wasn't already stored). The maps are built specifically to satisfy the spellchecker rules.

The spellchecker iterates through the queries and performs the following operations on each query: lowercase conversion and vowel replacement with `#`. Then, using an if-else branching and the three hash maps created earlier, the algorithm checks for matching words and populates the result array based on the spellchecker rules in the order of precedence specified.

Once all queries have been processed, the result array is returned.


# Minimum Domino Rotations For Equal Row

- slug: minimum-domino-rotations-for-equal-row
- difficulty: Medium

In a row of dominoes, `tops[i]` and `bottoms[i]` represent the top and bottom halves of the `ith` domino. (A domino is a tile with two numbers from 1 to 6 - one on each half of the tile.)

We may rotate the `ith` domino, so that `tops[i]` and `bottoms[i]` swap values.

Return the minimum number of rotations so that all the values in `tops` are the same, or all the values in `bottoms` are the same.

If it cannot be done, return `-1`.

**Example 1:**

**Input:** tops = \[2,1,2,4,2,2\], bottoms = \[5,2,6,2,3,2\]
**Output:** 2
**Explanation:**
The first figure represents the dominoes as given by tops and bottoms: before we do any rotations.
If we rotate the second and fourth dominoes, we can make every value in the top row equal to 2, as indicated by the second figure.

**Example 2:**

**Input:** tops = \[3,5,1,2,3\], bottoms = \[3,6,3,3,4\]
**Output:** -1
**Explanation:**
In this case, it is not possible to rotate the dominoes to make one row of values equal.

**Constraints:**

*   `2 <= tops.length <= 2 * 104`
*   `bottoms.length == tops.length`
*   `1 <= tops[i], bottoms[i] <= 6`

## A solution in Java

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

public List<Integer> numsSameConsecDiff(int n, int k) {
    List<Integer> result = new ArrayList<>();
    if (n == 1) result.add(0);

    void dfs(String current) {
        if (current.length() == n) {
            result.add(Integer.parseInt(current));
            return;
        }

        char last_digit = current.charAt(current.length() - 1);
        if (last_digit - k >= '0') dfs(current + (char) (last_digit - k));
        if (k != 0 && last_digit + k <= '9') dfs(current + (char) (last_digit + k));
    }

    for (char i = '1'; i <= '9'; ++i) {
        dfs(Character.toString(i));
    }

    return result;
}
```
The algorithm uses depth-first search (DFS) to explore all possible numbers that meet the condition.

1. If `n == 1`, add 0 to the result as a single-digit number is valid.
2. Define a DFS function that takes the current number as a string.
   - If the length of the current number equals `n`, convert it to an integer and add it to the result.
   - For the last digit of the current number, calculate the next two possible digits: the last digit minus `k` and the last digit plus `k`.
   - If the calculated digits are valid (not negative and not more than 9), call the DFS function recursively with the new digits.
3. Initialize the DFS search starting from digits 1 to 9 to avoid leading zeros.

The algorithm explores all possible numbers using DFS, ensuring that the absolute difference between every two consecutive digits is `k`. Finally, it returns a list of valid numbers.

## A solution in C++

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

std::vector<int> numsSameConsecDiff(int n, int k) {
    std::vector<int> result;
    if (n == 1) result.push_back(0);

    std::function<void(std::string)> dfs = [&](std::string current) {
        if (current.size() == n) {
            result.push_back(stoi(current));
            return;
        }

        char last_digit = current.back();
        if (last_digit - k >= '0') dfs(current + static_cast<char>(last_digit - k));
        if (k != 0 && last_digit + k <= '9') dfs(current + static_cast<char>(last_digit + k));
    };

    for (char i = '1'; i <= '9'; ++i) {
        dfs(std::string(1, i));
    }

    return result;
}
```
The algorithm uses depth-first search (DFS) to explore all possible numbers that meet the condition.

1. If `n == 1`, add 0 to the result as a single-digit number is valid.
2. Define a DFS function that takes the current number as a string.
   - If the length of the current number equals `n`, convert it to an integer and add it to the result.
   - For the last digit of the current number, calculate the next two possible digits: the last digit minus `k` and the last digit plus `k`.
   - If the calculated digits are valid (not negative and not more than 9), call the DFS function recursively with the new digits.
3. Initialize the DFS search starting from digits 1 to 9 to avoid leading zeros.

The algorithm explores all possible numbers using DFS, ensuring that the absolute difference between every two consecutive digits is `k`. Finally, it returns a list of valid numbers.

## A solution in Python

```python
def numsSameConsecDiff(n, k):
    result = []
    if n == 1: result.append(0)

    def dfs(current):
        if len(current) == n:
            result.append(int(current))
            return

        last_digit = current[-1]
        if last_digit - k >= 0: dfs(current + str(last_digit - k))
        if k != 0 and last_digit + k <= 9: dfs(current + str(last_digit + k))

    for i in range(1, 10):
        dfs(str(i))

    return result
```
The algorithm uses depth-first search (DFS) to explore all possible numbers that meet the condition.

1. If `n == 1`, add 0 to the result as a single-digit number is valid.
2. Define a DFS function that takes the current number as a string.
   - If the length of the current number equals `n`, convert it to an integer and add it to the result.
   - For the last digit of the current number, calculate the next two possible digits: the last digit minus `k` and the last digit plus `k`.
   - If the calculated digits are valid (not negative and not more than 9), call the DFS function recursively with the new digits.
3. Initialize the DFS search starting from digits 1 to 9 to avoid leading zeros.

The algorithm explores all possible numbers using DFS, ensuring that the absolute difference between every two consecutive digits is `k`. Finally, it returns a list of valid numbers.

## A solution in Javascript

```javascript
function numsSameConsecDiff(n, k) {
    let result = [];
    if (n === 1) result.push(0);

    function dfs(current) {
        if (current.length === n) {
            result.push(Number(current));
            return;
        }

        let last_digit = current[current.length - 1];
        if (last_digit - k >= 0) dfs(current + (last_digit - k));
        if (k !== 0 && last_digit + k <= 9) dfs(current + (last_digit + k));
    }

    for (let i = 1; i <= 9; ++i) {
        dfs(String(i));
    }

    return result;
}
```
The algorithm uses depth-first search (DFS) to explore all possible numbers that meet the condition.

1. If `n == 1`, add 0 to the result as a single-digit number is valid.
2. Define a DFS function that takes the current number as a string.
   - If the length of the current number equals `n`, convert it to an integer and add it to the result.
   - For the last digit of the current number, calculate the next two possible digits: the last digit minus `k` and the last digit plus `k`.
   - If the calculated digits are valid (not negative and not more than 9), call the DFS function recursively with the new digits.
3. Initialize the DFS search starting from digits 1 to 9 to avoid leading zeros.

The algorithm explores all possible numbers using DFS, ensuring that the absolute difference between every two consecutive digits is `k`. Finally, it returns a list of valid numbers.


# Construct Binary Search Tree from Preorder Traversal

- slug: construct-binary-search-tree-from-preorder-traversal
- difficulty: Medium

Given an array of integers preorder, which represents the **preorder traversal** of a BST (i.e., **binary search tree**), construct the tree and return _its root_.

It is **guaranteed** that there is always possible to find a binary search tree with the given requirements for the given test cases.

A **binary search tree** is a binary tree where for every node, any descendant of `Node.left` has a value **strictly less than** `Node.val`, and any descendant of `Node.right` has a value **strictly greater than** `Node.val`.

A **preorder traversal** of a binary tree displays the value of the node first, then traverses `Node.left`, then traverses `Node.right`.

**Example 1:**

**Input:** preorder = \[8,5,1,7,10,12\]
**Output:** \[8,5,10,1,7,null,12\]

**Example 2:**

**Input:** preorder = \[1,3\]
**Output:** \[1,null,3\]

**Constraints:**

*   `1 <= preorder.length <= 100`
*   `1 <= preorder[i] <= 1000`
*   All the values of `preorder` are **unique**.

## A solution in Java

```java
public int minCameraCover(TreeNode root) {
    int[] ans = new int[1];
    return (dfs(root, ans) < 1 ? 1 : 0) + ans[0];
}

private int dfs(TreeNode node, int[] ans) {
    if (node == null) return 2;
    int left = dfs(node.left, ans);
    int right = dfs(node.right, ans);
    if (left == 0 || right == 0) {
        ans[0]++;
        return 1;
    }
    return left == 1 || right == 1 ? 2 : 0;
}
```
The algorithm uses a depth-first search (dfs) to traverse the binary tree. It starts at the root and recurses through the left and right children until a leaf node is reached. At each node of the tree, we decide to place a camera or not.

The dfs function returns one of three values:
0. A camera is needed: Indicates that the node itself needs a camera.
1. A camera exists:  Indicates that the node has a camera monitoring itself, its parent, and its children.
2. No camera needed: Indicates that the node is monitored by its children but it itself doesn't have a camera.

The algorithm proceeds as follow:
1. For each node, dfs is called for both of its children.
2. If either of the children needs a camera (return value is 0), we place a camera at the parent node and update the ans count.
3. If either child has a camera (return value is 1), the parent is already monitored and doesn't need a camera so we return 2 for no camera needed. Otherwise, the parent node will need a camera so we return 0.

At the end, if the root node still needs a camera, we increment the ans count by 1, representing the camera necessary to monitor the entire tree. Finally, the minimum number of cameras (ans) is returned.

## A solution in C++

```cpp
int minCameraCover(TreeNode* root) {
    int ans = 0;
    return (dfs(root, ans) < 1 ? 1 : 0) + ans;
}

int dfs(TreeNode* node, int& ans) {
    if (!node) return 2;
    int left = dfs(node->left, ans);
    int right = dfs(node->right, ans);
    if (left == 0 || right == 0) {
        ans++;
        return 1;
    }
    return left == 1 || right == 1 ? 2 : 0;
}
```
The algorithm uses a depth-first search (dfs) to traverse the binary tree. It starts at the root and recurses through the left and right children until a leaf node is reached. At each node of the tree, we decide to place a camera or not.

The dfs function returns one of three values:
0. A camera is needed: Indicates that the node itself needs a camera.
1. A camera exists:  Indicates that the node has a camera monitoring itself, its parent, and its children.
2. No camera needed: Indicates that the node is monitored by its children but it itself doesn't have a camera.

The algorithm proceeds as follow:
1. For each node, dfs is called for both of its children.
2. If either of the children needs a camera (return value is 0), we place a camera at the parent node and update the ans count.
3. If either child has a camera (return value is 1), the parent is already monitored and doesn't need a camera so we return 2 for no camera needed. Otherwise, the parent node will need a camera so we return 0.

At the end, if the root node still needs a camera, we increment the ans count by 1, representing the camera necessary to monitor the entire tree. Finally, the minimum number of cameras (ans) is returned.

## A solution in Python

```python
def min_camera_cover(root):
    ans = [0]
    return (dfs(root, ans) < 1) + ans[0]

def dfs(node, ans):
    if not node:
        return 2
    left = dfs(node.left, ans)
    right = dfs(node.right, ans)
    if left == 0 or right == 0:
        ans[0] += 1
        return 1
    return 2 if left == 1 or right == 1 else 0
```
The algorithm uses a depth-first search (dfs) to traverse the binary tree. It starts at the root and recurses through the left and right children until a leaf node is reached. At each node of the tree, we decide to place a camera or not.

The dfs function returns one of three values:
0. A camera is needed: Indicates that the node itself needs a camera.
1. A camera exists:  Indicates that the node has a camera monitoring itself, its parent, and its children.
2. No camera needed: Indicates that the node is monitored by its children but it itself doesn't have a camera.

The algorithm proceeds as follow:
1. For each node, dfs is called for both of its children.
2. If either of the children needs a camera (return value is 0), we place a camera at the parent node and update the ans count.
3. If either child has a camera (return value is 1), the parent is already monitored and doesn't need a camera so we return 2 for no camera needed. Otherwise, the parent node will need a camera so we return 0.

At the end, if the root node still needs a camera, we increment the ans count by 1, representing the camera necessary to monitor the entire tree. Finally, the minimum number of cameras (ans) is returned.

## A solution in Javascript

```javascript
function minCameraCover(root) {
    let ans = { count: 0 };
    return (dfs(root, ans) < 1 ? 1 : 0) + ans.count;
}

function dfs(node, ans) {
    if (!node) return 2;
    let left = dfs(node.left, ans);
    let right = dfs(node.right, ans);
    if (left === 0 || right === 0) {
        ans.count++;
        return 1;
    }
    return left === 1 || right === 1 ? 2 : 0;
}
```
The algorithm uses a depth-first search (dfs) to traverse the binary tree. It starts at the root and recurses through the left and right children until a leaf node is reached. At each node of the tree, we decide to place a camera or not.

The dfs function returns one of three values:
0. A camera is needed: Indicates that the node itself needs a camera.
1. A camera exists:  Indicates that the node has a camera monitoring itself, its parent, and its children.
2. No camera needed: Indicates that the node is monitored by its children but it itself doesn't have a camera.

The algorithm proceeds as follow:
1. For each node, dfs is called for both of its children.
2. If either of the children needs a camera (return value is 0), we place a camera at the parent node and update the ans count.
3. If either child has a camera (return value is 1), the parent is already monitored and doesn't need a camera so we return 2 for no camera needed. Otherwise, the parent node will need a camera so we return 0.

At the end, if the root node still needs a camera, we increment the ans count by 1, representing the camera necessary to monitor the entire tree. Finally, the minimum number of cameras (ans) is returned.


# Complement of Base 10 Integer

- slug: complement-of-base-10-integer
- difficulty: Easy

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

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

Given an integer `n`, return _its complement_.

**Example 1:**

**Input:** n = 5
**Output:** 2
**Explanation:** 5 is  "101 " in binary, with complement  "010 " in binary, which is 2 in base-10.

**Example 2:**

**Input:** n = 7
**Output:** 0
**Explanation:** 7 is  "111 " in binary, with complement  "000 " in binary, which is 0 in base-10.

**Example 3:**

**Input:** n = 10
**Output:** 5
**Explanation:** 10 is  "1010 " in binary, with complement  "0101 " in binary, which is 5 in base-10.

**Constraints:**

*   `0 <= n < 109`

**Note:** This question is the same as 476: [https://leetcode.com/problems/number-complement/](https://leetcode.com/problems/number-complement/)

## A solution in Java

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

public List<Integer> pancakeSort(int[] arr) {
    List<Integer> flips = new ArrayList<>();
    for (int size = arr.length; size > 1; --size) {
        int maxIdx = getMaxIdx(arr, size);
        flips.add(maxIdx + 1);
        flips.add(size);
        reverse(arr, 0, maxIdx);
        reverse(arr, 0, size - 1);
    }
    return flips;
}

private int getMaxIdx(int[] arr, int size) {
    int maxIdx = 0;
    for (int i = 1; i < size; ++i) {
        if (arr[i] > arr[maxIdx]) {
            maxIdx = i;
        }
    }
    return maxIdx;
}

private void reverse(int[] arr, int start, int end) {
    while (start < end) {
        int temp = arr[start];
        arr[start++] = arr[end];
        arr[end--] = temp;
    }
}
```
The algorithm be:
1. Iterate over the array from the last element to the first.
2. During each iteration, find the index of the maximum element in the unsorted part of the array.
3. Perform a pancake flip at the maximum element index, to move it to the beginning of the array.
4. Perform a pancake flip for the whole unsorted part of the array to place the maximum element at its correct position.
5. Add the flip positions in the list of flips.
6. The algorithm ends when the array is completely sorted.

This guarantees that the array will be sorted within 2 * arr.length flips.

## A solution in C++

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

vector<int> pancakeSort(vector<int>& arr) {
    vector<int> flips;
    for (int size = arr.size(); size > 1; --size) {
        int maxIdx = max_element(arr.begin(), arr.begin() + size) - arr.begin();
        flips.push_back(maxIdx + 1);
        flips.push_back(size);
        reverse(arr.begin(), arr.begin() + maxIdx + 1);
        reverse(arr.begin(), arr.begin() + size);
    }
    return flips;
}
```
The algorithm be:
1. Iterate over the array from the last element to the first.
2. During each iteration, find the index of the maximum element in the unsorted part of the array.
3. Perform a pancake flip at the maximum element index, to move it to the beginning of the array.
4. Perform a pancake flip for the whole unsorted part of the array to place the maximum element at its correct position.
5. Add the flip positions in the list of flips.
6. The algorithm ends when the array is completely sorted.

This guarantees that the array will be sorted within 2 * arr.length flips.

## A solution in Python

```python
def pancakeSort(arr):
    flips = []
    for size in range(len(arr), 1, -1):
        maxIdx = arr.index(max(arr[:size]))
        flips.extend([maxIdx + 1, size])
        arr[:maxIdx + 1] = reversed(arr[:maxIdx + 1])
        arr[:size] = reversed(arr[:size])
    return flips
```
The algorithm be:
1. Iterate over the array from the last element to the first.
2. During each iteration, find the index of the maximum element in the unsorted part of the array.
3. Perform a pancake flip at the maximum element index, to move it to the beginning of the array.
4. Perform a pancake flip for the whole unsorted part of the array to place the maximum element at its correct position.
5. Add the flip positions in the list of flips.
6. The algorithm ends when the array is completely sorted.

This guarantees that the array will be sorted within 2 * arr.length flips.

## A solution in Javascript

```javascript
function pancakeSort(arr) {
    const flips = [];
    for (let size = arr.length; size > 1; --size) {
        const maxIdx = getMaxIdx(arr, size);
        flips.push(maxIdx + 1);
        flips.push(size);
        reverse(arr, 0, maxIdx);
        reverse(arr, 0, size - 1);
    }
    return flips;
}

function getMaxIdx(arr, size) {
    let maxIdx = 0;
    for (let i = 1; i < size; ++i) {
        if (arr[i] > arr[maxIdx]) {
            maxIdx = i;
        }
    }
    return maxIdx;
}

function reverse(arr, start, end) {
    while (start < end) {
        const temp = arr[start];
        arr[start++] = arr[end];
        arr[end--] = temp;
    }
}
```
The algorithm be:
1. Iterate over the array from the last element to the first.
2. During each iteration, find the index of the maximum element in the unsorted part of the array.
3. Perform a pancake flip at the maximum element index, to move it to the beginning of the array.
4. Perform a pancake flip for the whole unsorted part of the array to place the maximum element at its correct position.
5. Add the flip positions in the list of flips.
6. The algorithm ends when the array is completely sorted.

This guarantees that the array will be sorted within 2 * arr.length flips.


# Pairs of Songs With Total Durations Divisible by 60

- slug: pairs-of-songs-with-total-durations-divisible-by-60
- difficulty: Medium

You are given a list of songs where the `ith` song has a duration of `time[i]` seconds.

Return _the number of pairs of songs for which their total duration in seconds is divisible by_ `60`. Formally, we want the number of indices `i`, `j` such that `i < j` with `(time[i] + time[j]) % 60 == 0`.

**Example 1:**

**Input:** time = \[30,20,150,100,40\]
**Output:** 3
**Explanation:** Three pairs have a total duration divisible by 60:
(time\[0\] = 30, time\[2\] = 150): total duration 180
(time\[1\] = 20, time\[3\] = 100): total duration 120
(time\[1\] = 20, time\[4\] = 40): total duration 60

**Example 2:**

**Input:** time = \[60,60,60\]
**Output:** 3
**Explanation:** All three pairs have a total duration of 120, which is divisible by 60.

**Constraints:**

*   `1 <= time.length <= 6 * 104`
*   `1 <= time[i] <= 500`

## A solution in Java

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

public List<Integer> powerfulIntegers(int x, int y, int bound) {
    HashSet<Integer> resultSet = new HashSet<>();
    for (int i = 0; Math.pow(x, i) <= bound; ++i) {
        for (int j = 0; Math.pow(x, i) + Math.pow(y, j) <= bound; ++j) {
            resultSet.add((int)(Math.pow(x, i) + Math.pow(y, j)));
        }
    }
    return new ArrayList<>(resultSet);
}
```
The algorithm starts by iterating through all possible values of `i` and `j` (using nested loops). For each combination of `i` and `j`, it calculates the potential powerful integer as `x^i + y^j`. If the potential powerful integer is less than or equal to `bound`, it is added to the result set. The result set ensures that each value occurs at most once.

The final result is a collection of unique powerful integers.

In C++ and Java, we use `std::set` and `HashSet` respectively to store unique powerful integers, whereas in Python and JavaScript, we use the built-in `set` and `Set` objects respectively. For returning the result as a list, C++ and Java require conversion of the set to a list (or vector), while Python and JavaScript can directly return the result as a list using the `list()` and `Array.from()` functions respectively.

## A solution in C++

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

std::vector<int> powerful_integers(int x, int y, int bound) {
    std::set<int> result;
    for (int i = 0; pow(x, i) <= bound; ++i) {
        for (int j = 0; pow(x, i) + pow(y, j) <= bound; ++j) {
            result.insert(pow(x, i) + pow(y, j));
        }
    }
    return std::vector<int>(result.begin(), result.end());
}
```
The algorithm starts by iterating through all possible values of `i` and `j` (using nested loops). For each combination of `i` and `j`, it calculates the potential powerful integer as `x^i + y^j`. If the potential powerful integer is less than or equal to `bound`, it is added to the result set. The result set ensures that each value occurs at most once.

The final result is a collection of unique powerful integers.

In C++ and Java, we use `std::set` and `HashSet` respectively to store unique powerful integers, whereas in Python and JavaScript, we use the built-in `set` and `Set` objects respectively. For returning the result as a list, C++ and Java require conversion of the set to a list (or vector), while Python and JavaScript can directly return the result as a list using the `list()` and `Array.from()` functions respectively.

## A solution in Python

```python
def powerful_integers(x, y, bound):
    result = set()
    for i in range(20):
        for j in range(20):
            val = x**i + y**j
            if val <= bound:
                result.add(val)
    return list(result)
```
The algorithm starts by iterating through all possible values of `i` and `j` (using nested loops). For each combination of `i` and `j`, it calculates the potential powerful integer as `x^i + y^j`. If the potential powerful integer is less than or equal to `bound`, it is added to the result set. The result set ensures that each value occurs at most once.

The final result is a collection of unique powerful integers.

In C++ and Java, we use `std::set` and `HashSet` respectively to store unique powerful integers, whereas in Python and JavaScript, we use the built-in `set` and `Set` objects respectively. For returning the result as a list, C++ and Java require conversion of the set to a list (or vector), while Python and JavaScript can directly return the result as a list using the `list()` and `Array.from()` functions respectively.

## A solution in Javascript

```javascript
function powerfulIntegers(x, y, bound) {
    const result = new Set();
    for (let i = 0; Math.pow(x, i) <= bound; ++i) {
        for (let j = 0; Math.pow(x, i) + Math.pow(y, j) <= bound; ++j) {
            result.add(Math.pow(x, i) + Math.pow(y, j));
        }
    }
    return Array.from(result);
}
```
The algorithm starts by iterating through all possible values of `i` and `j` (using nested loops). For each combination of `i` and `j`, it calculates the potential powerful integer as `x^i + y^j`. If the potential powerful integer is less than or equal to `bound`, it is added to the result set. The result set ensures that each value occurs at most once.

The final result is a collection of unique powerful integers.

In C++ and Java, we use `std::set` and `HashSet` respectively to store unique powerful integers, whereas in Python and JavaScript, we use the built-in `set` and `Set` objects respectively. For returning the result as a list, C++ and Java require conversion of the set to a list (or vector), while Python and JavaScript can directly return the result as a list using the `list()` and `Array.from()` functions respectively.


# Capacity To Ship Packages Within D Days

- slug: capacity-to-ship-packages-within-d-days
- difficulty: Medium

A conveyor belt has packages that must be shipped from one port to another within `days` days.

The `ith` package on the conveyor belt has a weight of `weights[i]`. Each day, we load the ship with packages on the conveyor belt (in the order given by `weights`). We may not load more weight than the maximum weight capacity of the ship.

Return the least weight capacity of the ship that will result in all the packages on the conveyor belt being shipped within `days` days.

**Example 1:**

**Input:** weights = \[1,2,3,4,5,6,7,8,9,10\], days = 5
**Output:** 15
**Explanation:** A ship capacity of 15 is the minimum to ship all the packages in 5 days like this:
1st day: 1, 2, 3, 4, 5
2nd day: 6, 7
3rd day: 8
4th day: 9
5th day: 10

Note that the cargo must be shipped in the order given, so using a ship of capacity 14 and splitting the packages into parts like (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) is not allowed.

**Example 2:**

**Input:** weights = \[3,2,2,4,1,4\], days = 3
**Output:** 6
**Explanation:** A ship capacity of 6 is the minimum to ship all the packages in 3 days like this:
1st day: 3, 2
2nd day: 2, 4
3rd day: 1, 4

**Example 3:**

**Input:** weights = \[1,2,3,1,1\], days = 4
**Output:** 3
**Explanation:**
1st day: 1
2nd day: 2
3rd day: 3
4th day: 1, 1

**Constraints:**

*   `1 <= days <= weights.length <= 5 * 104`
*   `1 <= weights[i] <= 500`

## A solution in Java

```java
class Solution {
    int idx;
    List<Integer> flipped;

    void flipRecur(TreeNode node, int[] voyage) {
        if (node == null) return;
        if (node.val != voyage[idx++]) {
            flipped.clear();
            flipped.add(-1);
            return;
        }
        if (idx < voyage.length && node.left != null && node.left.val != voyage[idx]) {
            flipped.add(node.val);
            flipRecur(node.right, voyage);
            flipRecur(node.left, voyage);
        } else {
            flipRecur(node.left, voyage);
            flipRecur(node.right, voyage);
        }
    }

    public List<Integer> flipMatchVoyage(TreeNode root, int[] voyage) {
        idx = 0;
        flipped = new ArrayList<>();
        flipRecur(root, voyage);
        return flipped;
    }
}
```
1. Start with the root node and initialize an empty list `flipped`.
2. Create a recursive function `flipRecur` to traverse the tree, this function will have the following input parameters:
   - node: The current node in the tree.
   - voyage: The given voyage list.
   - idx: A counter to keep track of the position in the voyage list.
   - flipped: A reference to the list of flipped nodes.
3. If the current node is null (leaf node), return the idx.
4. Compare the current node value with the voyage list element at current idx:
   - If they don't match, set flipped list to [-1] and return the idx.
   - If they match, increment idx.
5. Check if the left subtree needs to be flipped by comparing the left child value with the next value in the voyage list.
   - If they don't match (the left subtree needs to be flipped), append the current node value to the flipped list and traverse the right subtree first, followed by the left subtree.
   - If they match, recursively traverse the left subtree, followed by the right subtree.

6. Call the `flipRecur` recursive function with the root node as the starting point.
7. If the first element of flipped list is -1, return [-1], otherwise, return the flipped list.

## A solution in C++

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

void flipRecur(TreeNode* node, vector<int>& voyage, int& idx, vector<int>& flipped)
{
    if (node == nullptr) return;
    if (node->val != voyage[idx++])
    {
        flipped = {-1};
        return;
    }
    if (idx < voyage.size() && node->left != nullptr && node->left->val != voyage[idx])
    {
        flipped.push_back(node->val);
        flipRecur(node->right, voyage, idx, flipped);
        flipRecur(node->left, voyage, idx, flipped);
    }
    else
    {
        flipRecur(node->left, voyage, idx, flipped);
        flipRecur(node->right, voyage, idx, flipped);
    }
}

vector<int> flipMatchVoyage(TreeNode* root, vector<int>& voyage) {
    vector<int> flipped;
    int idx = 0;
    flipRecur(root, voyage, idx, flipped);
    return flipped;
}
```
1. Start with the root node and initialize an empty list `flipped`.
2. Create a recursive function `flipRecur` to traverse the tree, this function will have the following input parameters:
   - node: The current node in the tree.
   - voyage: The given voyage list.
   - idx: A counter to keep track of the position in the voyage list.
   - flipped: A reference to the list of flipped nodes.
3. If the current node is null (leaf node), return the idx.
4. Compare the current node value with the voyage list element at current idx:
   - If they don't match, set flipped list to [-1] and return the idx.
   - If they match, increment idx.
5. Check if the left subtree needs to be flipped by comparing the left child value with the next value in the voyage list.
   - If they don't match (the left subtree needs to be flipped), append the current node value to the flipped list and traverse the right subtree first, followed by the left subtree.
   - If they match, recursively traverse the left subtree, followed by the right subtree.

6. Call the `flipRecur` recursive function with the root node as the starting point.
7. If the first element of flipped list is -1, return [-1], otherwise, return the flipped list.

## A solution in Python

```python
def flipRecur(node, voyage, flipped, idx):
    if not node:
        return idx
    if node.val != voyage[idx]:
        flipped[0] = -1
        return idx
    idx += 1
    if (idx < len(voyage) and node.left and
            node.left.val != voyage[idx]):
        flipped.append(node.val)
        idx = flipRecur(node.right, voyage, flipped, idx)
        idx = flipRecur(node.left, voyage, flipped, idx)
    else:
        idx = flipRecur(node.left, voyage, flipped, idx)
        idx = flipRecur(node.right, voyage, flipped, idx)
    return idx

def flipMatchVoyage(root, voyage):
    flipped = []
    flipRecur(root, voyage, flipped, 0)
    if flipped and flipped[0] == -1:
        return [-1]
    return flipped
```
1. Start with the root node and initialize an empty list `flipped`.
2. Create a recursive function `flipRecur` to traverse the tree, this function will have the following input parameters:
   - node: The current node in the tree.
   - voyage: The given voyage list.
   - idx: A counter to keep track of the position in the voyage list.
   - flipped: A reference to the list of flipped nodes.
3. If the current node is null (leaf node), return the idx.
4. Compare the current node value with the voyage list element at current idx:
   - If they don't match, set flipped list to [-1] and return the idx.
   - If they match, increment idx.
5. Check if the left subtree needs to be flipped by comparing the left child value with the next value in the voyage list.
   - If they don't match (the left subtree needs to be flipped), append the current node value to the flipped list and traverse the right subtree first, followed by the left subtree.
   - If they match, recursively traverse the left subtree, followed by the right subtree.

6. Call the `flipRecur` recursive function with the root node as the starting point.
7. If the first element of flipped list is -1, return [-1], otherwise, return the flipped list.

## A solution in Javascript

```javascript
function flipRecur(node, voyage, flipped, idx) {
    if (!node) return idx;
    if (node.val !== voyage[idx]) {
        flipped[0] = -1;
        return idx;
    }
    idx++;
    if (idx < voyage.length && node.left !== null && node.left.val !== voyage[idx]) {
        flipped.push(node.val);
        idx = flipRecur(node.right, voyage, flipped, idx);
        idx = flipRecur(node.left, voyage, flipped, idx);
    } else {
        idx = flipRecur(node.left, voyage, flipped, idx);
        idx = flipRecur(node.right, voyage, flipped, idx);
    }
    return idx;
}

function flipMatchVoyage(root, voyage) {
    let flipped = [];
    flipRecur(root, voyage, flipped, 0);
    if (flipped.length > 0 && flipped[0] === -1) return [-1];
    return flipped;
}
```
1. Start with the root node and initialize an empty list `flipped`.
2. Create a recursive function `flipRecur` to traverse the tree, this function will have the following input parameters:
   - node: The current node in the tree.
   - voyage: The given voyage list.
   - idx: A counter to keep track of the position in the voyage list.
   - flipped: A reference to the list of flipped nodes.
3. If the current node is null (leaf node), return the idx.
4. Compare the current node value with the voyage list element at current idx:
   - If they don't match, set flipped list to [-1] and return the idx.
   - If they match, increment idx.
5. Check if the left subtree needs to be flipped by comparing the left child value with the next value in the voyage list.
   - If they don't match (the left subtree needs to be flipped), append the current node value to the flipped list and traverse the right subtree first, followed by the left subtree.
   - If they match, recursively traverse the left subtree, followed by the right subtree.

6. Call the `flipRecur` recursive function with the root node as the starting point.
7. If the first element of flipped list is -1, return [-1], otherwise, return the flipped list.


# Numbers With Repeated Digits

- slug: numbers-with-repeated-digits
- difficulty: Hard

Given an integer `n`, return _the number of positive integers in the range_ `[1, n]` _that have **at least one** repeated digit_.

**Example 1:**

**Input:** n = 20
**Output:** 1
**Explanation:** The only positive number (<= 20) with at least 1 repeated digit is 11.

**Example 2:**

**Input:** n = 100
**Output:** 10
**Explanation:** The positive numbers (<= 100) with atleast 1 repeated digit are 11, 22, 33, 44, 55, 66, 77, 88, 99, and 100.

**Example 3:**

**Input:** n = 1000
**Output:** 262

**Constraints:**

*   `1 <= n <= 109`

## A solution in Java

```java
public boolean isRationalEqual(String s, String t) {
    Double num1 = evaluateString(s);
    Double num2 = evaluateString(t);
    return Math.abs(num1 - num2) < 1e-12;
}

private double evaluateString(String s) {
    int i = s.indexOf('(');
    if (i != -1) {
        String base = s.substring(0, i);
        String rep = s.substring(i + 1, s.length() - 1);
        for (int k = 0; k < 20; ++k) {
            base += rep;
        }
        return Double.parseDouble(base);
    }
    return Double.parseDouble(s);
}
```
The given algorithm proceeds in the following steps:

1. Use a lambda function (or a separate function in Java) named 'eval' or 'evaluate' which takes a string representing a rational number as input.
2. Check if the input string has the repeating part (by finding the index of the opening bracket `(`).
3. If the input string has a repeating part, extract the base and repeating part separately. Then append the repeating part 20 times to the base part, and convert the resulting string into a floating-point number. Else, convert the input string into a floating-point number directly.
4. Call the 'eval' or 'evaluate' function for both input strings `s` and `t`, and calculate the absolute difference between the two numbers.
5. Check if the absolute difference is less than 1e-12, and if so, return true; else, return false.

The algorithm thus compares the given rational numbers by converting them into floating-point numbers and checking if they have the same numerical value within a very small margin of error (1e-12). This technique ensures that small differences in the way the numbers are represented do not affect the comparison result.

## A solution in C++

```cpp
bool isRationalEqual(std::string s, std::string t) {
    auto eval = [](std::string s) {
        int i = s.find('(');
        if (i != std::string::npos) {
            std::string base = s.substr(0, i);
            std::string rep = s.substr(i + 1, s.length() - i - 2);
            for (int k = 0; k < 20; ++k) base += rep;
            return stod(base);
        }
        return stod(s);
    };
    return fabs(eval(s) - eval(t)) < 1e-12;
}
```
The given algorithm proceeds in the following steps:

1. Use a lambda function (or a separate function in Java) named 'eval' or 'evaluate' which takes a string representing a rational number as input.
2. Check if the input string has the repeating part (by finding the index of the opening bracket `(`).
3. If the input string has a repeating part, extract the base and repeating part separately. Then append the repeating part 20 times to the base part, and convert the resulting string into a floating-point number. Else, convert the input string into a floating-point number directly.
4. Call the 'eval' or 'evaluate' function for both input strings `s` and `t`, and calculate the absolute difference between the two numbers.
5. Check if the absolute difference is less than 1e-12, and if so, return true; else, return false.

The algorithm thus compares the given rational numbers by converting them into floating-point numbers and checking if they have the same numerical value within a very small margin of error (1e-12). This technique ensures that small differences in the way the numbers are represented do not affect the comparison result.

## A solution in Python

```python
def isRationalEqual(s: str, t: str) -> bool:
    def evaluate(s: str) -> float:
        i = s.find('(')
        if i != -1:
            base = s[:i]
            rep = s[i + 1:-1]
            return float(base + rep * 20)
        return float(s)

    return abs(evaluate(s) - evaluate(t)) < 1e-12
```
The given algorithm proceeds in the following steps:

1. Use a lambda function (or a separate function in Java) named 'eval' or 'evaluate' which takes a string representing a rational number as input.
2. Check if the input string has the repeating part (by finding the index of the opening bracket `(`).
3. If the input string has a repeating part, extract the base and repeating part separately. Then append the repeating part 20 times to the base part, and convert the resulting string into a floating-point number. Else, convert the input string into a floating-point number directly.
4. Call the 'eval' or 'evaluate' function for both input strings `s` and `t`, and calculate the absolute difference between the two numbers.
5. Check if the absolute difference is less than 1e-12, and if so, return true; else, return false.

The algorithm thus compares the given rational numbers by converting them into floating-point numbers and checking if they have the same numerical value within a very small margin of error (1e-12). This technique ensures that small differences in the way the numbers are represented do not affect the comparison result.

## A solution in Javascript

```javascript
function isRationalEqual(s, t) {
    const evaluate = (s) => {
        let i = s.indexOf('(');
        if (i !== -1) {
            let base = s.substring(0, i);
            let rep = s.substring(i + 1, s.length - 1);
            for (let k = 0; k < 20; ++k) {
                base += rep;
            }
            return parseFloat(base);
        }
        return parseFloat(s);
    };
    return Math.abs(evaluate(s) - evaluate(t)) < 1e-12;
}
```
The given algorithm proceeds in the following steps:

1. Use a lambda function (or a separate function in Java) named 'eval' or 'evaluate' which takes a string representing a rational number as input.
2. Check if the input string has the repeating part (by finding the index of the opening bracket `(`).
3. If the input string has a repeating part, extract the base and repeating part separately. Then append the repeating part 20 times to the base part, and convert the resulting string into a floating-point number. Else, convert the input string into a floating-point number directly.
4. Call the 'eval' or 'evaluate' function for both input strings `s` and `t`, and calculate the absolute difference between the two numbers.
5. Check if the absolute difference is less than 1e-12, and if so, return true; else, return false.

The algorithm thus compares the given rational numbers by converting them into floating-point numbers and checking if they have the same numerical value within a very small margin of error (1e-12). This technique ensures that small differences in the way the numbers are represented do not affect the comparison result.


# Partition Array Into Three Parts With Equal Sum

- slug: partition-array-into-three-parts-with-equal-sum
- difficulty: Easy

Given an array of integers `arr`, return `true` if we can partition the array into three **non-empty** parts with equal sums.

Formally, we can partition the array if we can find indexes `i + 1 < j` with `(arr[0] + arr[1] + ... + arr[i] == arr[i + 1] + arr[i + 2] + ... + arr[j - 1] == arr[j] + arr[j + 1] + ... + arr[arr.length - 1])`

**Example 1:**

**Input:** arr = \[0,2,1,-6,6,-7,9,1,2,0,1\]
**Output:** true
**Explanation:** 0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1

**Example 2:**

**Input:** arr = \[0,2,1,-6,6,7,9,-1,2,0,1\]
**Output:** false

**Example 3:**

**Input:** arr = \[3,3,6,5,-2,2,5,1,-9,4\]
**Output:** true
**Explanation:** 3 + 3 = 6 = 5 - 2 + 2 + 5 + 1 - 9 + 4

**Constraints:**

*   `3 <= arr.length <= 5 * 104`
*   `-104 <= arr[i] <= 104`

## A solution in Java

```java
public int fib(int n) {
    if (n <= 1)
        return n;
    int a = 0, b = 1, c;
    for (int i = 2; i <= n; i++) {
        c = a + b;
        a = b;
        b = c;
    }
    return b;
}
```
The algorithm iterates from 2 to n using a loop that calculates the current Fibonacci number by adding the two previous ones. It uses three variables a, b, and c, representing the two previous Fibonacci numbers and the current one, respectively. At each iteration, the algorithm calculates the current Fibonacci number, updates a and b, and repeats. This minimizes the extra space needed and avoids recursion, resulting in an efficient O(n) time complexity solution.

## A solution in C++

```cpp
int fib(int n) {
    if (n <= 1)
        return n;
    int a = 0, b = 1, c;
    for (int i = 2; i <= n; i++) {
        c = a + b;
        a = b;
        b = c;
    }
    return b;
}
```
The algorithm iterates from 2 to n using a loop that calculates the current Fibonacci number by adding the two previous ones. It uses three variables a, b, and c, representing the two previous Fibonacci numbers and the current one, respectively. At each iteration, the algorithm calculates the current Fibonacci number, updates a and b, and repeats. This minimizes the extra space needed and avoids recursion, resulting in an efficient O(n) time complexity solution.

## A solution in Python

```python
def fib(n):
    if n <= 1:
        return n
    a, b = 0, 1
    for _ in range(2, n + 1):
        a, b = b, a + b
    return b
```
The algorithm iterates from 2 to n using a loop that calculates the current Fibonacci number by adding the two previous ones. It uses three variables a, b, and c, representing the two previous Fibonacci numbers and the current one, respectively. At each iteration, the algorithm calculates the current Fibonacci number, updates a and b, and repeats. This minimizes the extra space needed and avoids recursion, resulting in an efficient O(n) time complexity solution.

## A solution in Javascript

```javascript
function fib(n) {
    if (n <= 1)
        return n;
    let a = 0, b = 1, c;
    for (let i = 2; i <= n; i++) {
        c = a + b;
        a = b;
        b = c;
    }
    return b;
}
```
The algorithm iterates from 2 to n using a loop that calculates the current Fibonacci number by adding the two previous ones. It uses three variables a, b, and c, representing the two previous Fibonacci numbers and the current one, respectively. At each iteration, the algorithm calculates the current Fibonacci number, updates a and b, and repeats. This minimizes the extra space needed and avoids recursion, resulting in an efficient O(n) time complexity solution.