# Minimum Index Sum of Two Lists

- slug: minimum-index-sum-of-two-lists
- difficulty: Easy

Given two arrays of strings `list1` and `list2`, find the **common strings with the least index sum**.

A **common string** is a string that appeared in both `list1` and `list2`.

A **common string with the least index sum** is a common string such that if it appeared at `list1[i]` and `list2[j]` then `i + j` should be the minimum value among all the other **common strings**.

Return _all the **common strings with the least index sum**_. Return the answer in **any order**.

**Example 1:**

**Input:** list1 = \[ "Shogun ", "Tapioca Express ", "Burger King ", "KFC "\], list2 = \[ "Piatti ", "The Grill at Torrey Pines ", "Hungry Hunter Steakhouse ", "Shogun "\]
**Output:** \[ "Shogun "\]
**Explanation:** The only common string is  "Shogun ".

**Example 2:**

**Input:** list1 = \[ "Shogun ", "Tapioca Express ", "Burger King ", "KFC "\], list2 = \[ "KFC ", "Shogun ", "Burger King "\]
**Output:** \[ "Shogun "\]
**Explanation:** The common string with the least index sum is  "Shogun " with index sum = (0 + 1) = 1.

**Example 3:**

**Input:** list1 = \[ "happy ", "sad ", "good "\], list2 = \[ "sad ", "happy ", "good "\]
**Output:** \[ "sad ", "happy "\]
**Explanation:** There are three common strings:
 "happy " with index sum = (0 + 1) = 1.
 "sad " with index sum = (1 + 0) = 1.
 "good " with index sum = (2 + 2) = 4.
The strings with the least index sum are  "sad " and  "happy ".

**Constraints:**

*   `1 <= list1.length, list2.length <= 1000`
*   `1 <= list1[i].length, list2[i].length <= 30`
*   `list1[i]` and `list2[i]` consist of spaces `' '` and English letters.
*   All the strings of `list1` are **unique**.
*   All the strings of `list2` are **unique**.
*   There is at least a common string between `list1` and `list2`.

## A solution in Java

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

public List<String> findRestaurant(String[] list1, String[] list2) {
    HashMap<String, Integer> restaurantMap = new HashMap<>();
    for (int i = 0; i < list1.length; i++) {
        restaurantMap.put(list1[i], i);
    }

    int minSum = Integer.MAX_VALUE;
    List<String> result = new ArrayList<>();
    for (int j = 0; j < list2.length; j++) {
        Integer index = restaurantMap.get(list2[j]);
        if (index != null) {
            int sum = j + index;
            if (sum < minSum) {
                result.clear();
                result.add(list2[j]);
                minSum = sum;
            } else if (sum == minSum) {
                result.add(list2[j]);
            }
        }
    }
    return result;
}
```
1. Create a hashmap to store the restaurants and their indices (or just index for Python and JavaScript) in list1.
2. Initialize a variable, minSum, to store the minimum sum of indices, and a result list to store the common restaurants with the least index sum.
3. Iterate through list2; for each restaurant, check if it is in the hashmap.
   a. If it is, calculate the sum of its index in list1 and list2.
   b. If the sum is less than the current minSum, clear the result list, add the current restaurant to the result list, and update minSum.
   c. If the sum is equal to minSum, add the restaurant to the result list.
5. Return the result list.

## A solution in C++

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

std::vector<std::string> findRestaurant(std::vector<std::string>& list1, std::vector<std::string>& list2) {
    std::unordered_map<std::string, int> restaurantMap;
    for (int i = 0; i < list1.size(); i++) {
        restaurantMap[list1[i]] = i;
    }

    int minSum = INT_MAX;
    std::vector<std::string> result;
    for (int j = 0; j < list2.size(); j++) {
        if (restaurantMap.count(list2[j])) {
            int sum = j + restaurantMap[list2[j]];
            if (sum < minSum) {
                result.clear();
                result.push_back(list2[j]);
                minSum = sum;
            } else if (sum == minSum) {
                result.push_back(list2[j]);
            }
        }
    }
    return result;
}
```
1. Create a hashmap to store the restaurants and their indices (or just index for Python and JavaScript) in list1.
2. Initialize a variable, minSum, to store the minimum sum of indices, and a result list to store the common restaurants with the least index sum.
3. Iterate through list2; for each restaurant, check if it is in the hashmap.
   a. If it is, calculate the sum of its index in list1 and list2.
   b. If the sum is less than the current minSum, clear the result list, add the current restaurant to the result list, and update minSum.
   c. If the sum is equal to minSum, add the restaurant to the result list.
5. Return the result list.

## A solution in Python

```python
from typing import List

def findRestaurant(list1: List[str], list2: List[str]) -> List[str]:
    restaurantMap = {restaurant: i for i, restaurant in enumerate(list1)}

    minSum = float("inf")
    result = []
    for j, restaurant in enumerate(list2):
        if restaurant in restaurantMap:
            totalSum = j + restaurantMap[restaurant]
            if totalSum < minSum:
                result = [restaurant]
                minSum = totalSum
            elif totalSum == minSum:
                result.append(restaurant)

    return result
```
1. Create a hashmap to store the restaurants and their indices (or just index for Python and JavaScript) in list1.
2. Initialize a variable, minSum, to store the minimum sum of indices, and a result list to store the common restaurants with the least index sum.
3. Iterate through list2; for each restaurant, check if it is in the hashmap.
   a. If it is, calculate the sum of its index in list1 and list2.
   b. If the sum is less than the current minSum, clear the result list, add the current restaurant to the result list, and update minSum.
   c. If the sum is equal to minSum, add the restaurant to the result list.
5. Return the result list.

## A solution in Javascript

```javascript
function findRestaurant(list1, list2) {
    let restaurantMap = new Map();
    for (let i = 0; i < list1.length; i++) {
        restaurantMap.set(list1[i], i);
    }

    let minSum = Infinity;
    let result = [];
    for (let j = 0; j < list2.length; j++) {
        if (restaurantMap.has(list2[j])) {
            let sum = j + restaurantMap.get(list2[j]);
            if (sum < minSum) {
                result = [list2[j]];
                minSum = sum;
            } else if (sum == minSum) {
                result.push(list2[j]);
            }
        }
    }
    return result;
}
```
1. Create a hashmap to store the restaurants and their indices (or just index for Python and JavaScript) in list1.
2. Initialize a variable, minSum, to store the minimum sum of indices, and a result list to store the common restaurants with the least index sum.
3. Iterate through list2; for each restaurant, check if it is in the hashmap.
   a. If it is, calculate the sum of its index in list1 and list2.
   b. If the sum is less than the current minSum, clear the result list, add the current restaurant to the result list, and update minSum.
   c. If the sum is equal to minSum, add the restaurant to the result list.
5. Return the result list.


# Non-negative Integers without Consecutive Ones

- slug: non-negative-integers-without-consecutive-ones
- difficulty: Hard

Given a positive integer `n`, return the number of the integers in the range `[0, n]` whose binary representations **do not** contain consecutive ones.

**Example 1:**

**Input:** n = 5
**Output:** 5
**Explanation:**
Here are the non-negative integers <= 5 with their corresponding binary representations:
0 : 0
1 : 1
2 : 10
3 : 11
4 : 100
5 : 101
Among them, only integer 3 disobeys the rule (two consecutive ones) and the other 5 satisfy the rule.

**Example 2:**

**Input:** n = 1
**Output:** 2

**Example 3:**

**Input:** n = 2
**Output:** 3

**Constraints:**

*   `1 <= n <= 109`

## A solution in Java

```java
public int findIntegers(int n) {
    int[][] dp = new int[32][2];
    dp[0][0] = 1;
    dp[0][1] = 1;

    for (int i = 1; i < 32; i++) {
        dp[i][0] = dp[i - 1][0] + dp[i - 1][1];
        dp[i][1] = dp[i - 1][0];
    }

    int ans = 0, prev_bit = 0;
    for (int i = 30; i >= 0; i--) {
        if ((n & (1 << i)) != 0) {
            ans += dp[i][0];
            if (prev_bit == 1) break;
            prev_bit = 1;
        } else {
            prev_bit = 0;
        }
    }

    return ans + 1;
}
```
The algorithm uses dynamic programming to count the number of valid integers with no consecutive 1s in their binary representation. It initializes an array `dp` with the dimensions [32][2], where the first dimension represents the length of the binary representation and the second dimension represents whether the last bit is a 1 (consecutive 1s) or a 0.

For every index i from `1` to `32`, dp[i][0] represents the count of valid integers without leading 1s, while dp[i][1] represents the count of valid integers without consecutive 1s ending with a 1. Starting from the highest bit and moving to the lowest bit, the algorithm checks if bit `i` is set in the given number `n`. If the bit is set, the algorithm increments the counter `ans` by the number of valid integers with that bit position.

If the previous bit was set, the algorithm breaks the loop because consecutive 1s were found. Finally, the algorithm returns the count of valid integers incremented by 1 to account for the integer 0, which always satisfies the condition.

## A solution in C++

```cpp
int findIntegers(int n) {
    int dp[32][2] = {0};
    dp[0][0] = dp[0][1] = 1;

    for (int i = 1; i < 32; i++) {
        dp[i][0] = dp[i - 1][0] + dp[i - 1][1];
        dp[i][1] = dp[i - 1][0];
    }

    int ans = 0, prev_bit = 0;
    for (int i = 30; i >= 0; i--) {
        if (n & (1 << i)) {
            ans += dp[i][0];
            if (prev_bit) break;
            prev_bit = 1;
        } else {
            prev_bit = 0;
        }
    }

    return ans + 1;
}
```
The algorithm uses dynamic programming to count the number of valid integers with no consecutive 1s in their binary representation. It initializes an array `dp` with the dimensions [32][2], where the first dimension represents the length of the binary representation and the second dimension represents whether the last bit is a 1 (consecutive 1s) or a 0.

For every index i from `1` to `32`, dp[i][0] represents the count of valid integers without leading 1s, while dp[i][1] represents the count of valid integers without consecutive 1s ending with a 1. Starting from the highest bit and moving to the lowest bit, the algorithm checks if bit `i` is set in the given number `n`. If the bit is set, the algorithm increments the counter `ans` by the number of valid integers with that bit position.

If the previous bit was set, the algorithm breaks the loop because consecutive 1s were found. Finally, the algorithm returns the count of valid integers incremented by 1 to account for the integer 0, which always satisfies the condition.

## A solution in Python

```python
def findIntegers(n: int) -> int:
    dp = [[0, 0] for _ in range(32)]
    dp[0][0], dp[0][1] = 1, 1

    for i in range(1, 32):
        dp[i][0] = dp[i - 1][0] + dp[i - 1][1]
        dp[i][1] = dp[i - 1][0]

    ans = 0
    prev_bit = 0
    for i in range(30, -1, -1):
        if n & (1 << i):
            ans += dp[i][0]
            if prev_bit:
                break
            prev_bit = 1
        else:
            prev_bit = 0

    return ans + 1
```
The algorithm uses dynamic programming to count the number of valid integers with no consecutive 1s in their binary representation. It initializes an array `dp` with the dimensions [32][2], where the first dimension represents the length of the binary representation and the second dimension represents whether the last bit is a 1 (consecutive 1s) or a 0.

For every index i from `1` to `32`, dp[i][0] represents the count of valid integers without leading 1s, while dp[i][1] represents the count of valid integers without consecutive 1s ending with a 1. Starting from the highest bit and moving to the lowest bit, the algorithm checks if bit `i` is set in the given number `n`. If the bit is set, the algorithm increments the counter `ans` by the number of valid integers with that bit position.

If the previous bit was set, the algorithm breaks the loop because consecutive 1s were found. Finally, the algorithm returns the count of valid integers incremented by 1 to account for the integer 0, which always satisfies the condition.

## A solution in Javascript

```javascript
function findIntegers(n) {
    let dp = new Array(32).fill(0).map(() => Array(2).fill(0));
    dp[0][0] = 1;
    dp[0][1] = 1;

    for (let i = 1; i < 32; i++) {
        dp[i][0] = dp[i - 1][0] + dp[i - 1][1];
        dp[i][1] = dp[i - 1][0];
    }

    let ans = 0, prev_bit = 0;
    for (let i = 30; i >= 0; i--) {
        if (n & (1 << i)) {
            ans += dp[i][0];
            if (prev_bit === 1) break;
            prev_bit = 1;
        } else {
            prev_bit = 0;
        }
    }

    return ans + 1;
}
```
The algorithm uses dynamic programming to count the number of valid integers with no consecutive 1s in their binary representation. It initializes an array `dp` with the dimensions [32][2], where the first dimension represents the length of the binary representation and the second dimension represents whether the last bit is a 1 (consecutive 1s) or a 0.

For every index i from `1` to `32`, dp[i][0] represents the count of valid integers without leading 1s, while dp[i][1] represents the count of valid integers without consecutive 1s ending with a 1. Starting from the highest bit and moving to the lowest bit, the algorithm checks if bit `i` is set in the given number `n`. If the bit is set, the algorithm increments the counter `ans` by the number of valid integers with that bit position.

If the previous bit was set, the algorithm breaks the loop because consecutive 1s were found. Finally, the algorithm returns the count of valid integers incremented by 1 to account for the integer 0, which always satisfies the condition.


# Design Compressed String Iterator

- slug: design-compressed-string-iterator
- difficulty: Easy

Design and implement a data structure for a compressed string iterator. The given compressed string will be in the form of each letter followed by a positive integer representing the number of this letter existing in the original uncompressed string.

Implement the StringIterator class:

*   `next()` Returns **the next character** if the original string still has uncompressed characters, otherwise returns a **white space**.
*   `hasNext()` Returns true if there is any letter needs to be uncompressed in the original string, otherwise returns `false`.

**Example 1:**

**Input**
\[ "StringIterator ",  "next ",  "next ",  "next ",  "next ",  "next ",  "next ",  "hasNext ",  "next ",  "hasNext "\]
\[\[ "L1e2t1C1o1d1e1 "\], \[\], \[\], \[\], \[\], \[\], \[\], \[\], \[\], \[\]\]
**Output**
\[null,  "L ",  "e ",  "e ",  "t ",  "C ",  "o ", true,  "d ", true\]

**Explanation**
StringIterator stringIterator = new StringIterator( "L1e2t1C1o1d1e1 ");
stringIterator.next(); // return  "L "
stringIterator.next(); // return  "e "
stringIterator.next(); // return  "e "
stringIterator.next(); // return  "t "
stringIterator.next(); // return  "C "
stringIterator.next(); // return  "o "
stringIterator.hasNext(); // return True
stringIterator.next(); // return  "d "
stringIterator.hasNext(); // return True

**Constraints:**

*   `1 <= compressedString.length <= 1000`
*   `compressedString` consists of lower-case an upper-case English letters and digits.
*   The number of a single character repetitions in `compressedString` is in the range `[1, 10^9]`
*   At most `100` calls will be made to `next` and `hasNext`.

## A solution in Java

```java
import java.util.*;
class StringIterator {
    String s;
    int i;
    int count;
    char ch;

    public StringIterator(String compressedString) {
        s = compressedString;
        i = 0;
        count = 0;
        ch = ' ';
    }

    public char next() {
        if(!hasNext()) {
            return ' ';
        }
        if(count == 0) {
            ch = s.charAt(i++);
            while(i < s.length() && Character.isDigit(s.charAt(i))) {
                count = count * 10 + (s.charAt(i++) - '0');
            }
        }
        count--;
        return ch;
    }

    public boolean hasNext() {
        return i < s.length() || count != 0;
    }
}
```
The main idea of the algorithm is to iterate through the compressed string, extracting each character and its associated count of repetitions. Each extracted character is stored in 'ch' and its count of repetitions is stored in 'count'. The 'next()' function checks if there are still letters to uncompress - if there aren't, it returns a white space. The 'next()' function also checks if the current count of repetitions for the character 'ch' is 0 - if it is, it extracts the next character from the compressed string until it encounters a digit, then extracts the whole count value. The 'hasNext()' function checks if there are any more characters in the compressed string or if the count of repetitions is not 0, meaning there are still characters to be uncompressed.

## A solution in C++

```cpp
#include <string>
class StringIterator {
public:
    StringIterator(const std::string& compressedString) {
        s = compressedString;
        i = 0;
        count = 0;
        ch = ' ';
    }
    char next() {
        if(!hasNext()) return ' ';
        if(count == 0) {
            ch = s[i++];
            while(i < s.size() && isdigit(s[i])) {
                count = count * 10 + (s[i++] - '0');
            }
        }
        count--;
        return ch;
    }
    bool hasNext() {
        return i < s.size() || count != 0;
    }
private:
    std::string s;
    int i;
    int count;
    char ch;
};
```
The main idea of the algorithm is to iterate through the compressed string, extracting each character and its associated count of repetitions. Each extracted character is stored in 'ch' and its count of repetitions is stored in 'count'. The 'next()' function checks if there are still letters to uncompress - if there aren't, it returns a white space. The 'next()' function also checks if the current count of repetitions for the character 'ch' is 0 - if it is, it extracts the next character from the compressed string until it encounters a digit, then extracts the whole count value. The 'hasNext()' function checks if there are any more characters in the compressed string or if the count of repetitions is not 0, meaning there are still characters to be uncompressed.

## A solution in Python

```python
class StringIterator:
    def __init__(self, compressedString: str):
        self.s = compressedString
        self.i = 0
        self.count = 0
        self.ch = " "

    def next(self) -> str:
        if not self.hasNext():
            return " "
        if self.count == 0:
            self.ch = self.s[self.i]
            self.i += 1
            while self.i < len(self.s) and self.s[self.i].isdigit():
                self.count = self.count * 10 + int(self.s[self.i])
                self.i += 1
        self.count -= 1
        return self.ch

    def hasNext(self) -> bool:
        return self.i < len(self.s) or self.count != 0
```
The main idea of the algorithm is to iterate through the compressed string, extracting each character and its associated count of repetitions. Each extracted character is stored in 'ch' and its count of repetitions is stored in 'count'. The 'next()' function checks if there are still letters to uncompress - if there aren't, it returns a white space. The 'next()' function also checks if the current count of repetitions for the character 'ch' is 0 - if it is, it extracts the next character from the compressed string until it encounters a digit, then extracts the whole count value. The 'hasNext()' function checks if there are any more characters in the compressed string or if the count of repetitions is not 0, meaning there are still characters to be uncompressed.

## A solution in Javascript

```javascript
class StringIterator {
    constructor(compressedString) {
        this.s = compressedString;
        this.i = 0;
        this.count = 0;
        this.ch = ' ';
    }

    next() {
        if (!this.hasNext()) {
            return ' ';
        }
        if (this.count === 0) {
            this.ch = this.s[this.i++];
            while (this.i < this.s.length && !isNaN(this.s[this.i])) {
                this.count = this.count * 10 + parseInt(this.s[this.i++]);
            }
        }
        this.count--;
        return this.ch;
    }

    hasNext() {
        return this.i < this.s.length || this.count !== 0;
    }
}
```
The main idea of the algorithm is to iterate through the compressed string, extracting each character and its associated count of repetitions. Each extracted character is stored in 'ch' and its count of repetitions is stored in 'count'. The 'next()' function checks if there are still letters to uncompress - if there aren't, it returns a white space. The 'next()' function also checks if the current count of repetitions for the character 'ch' is 0 - if it is, it extracts the next character from the compressed string until it encounters a digit, then extracts the whole count value. The 'hasNext()' function checks if there are any more characters in the compressed string or if the count of repetitions is not 0, meaning there are still characters to be uncompressed.


# Can Place Flowers

- slug: can-place-flowers
- difficulty: Easy

You have a long flowerbed in which some of the plots are planted, and some are not. However, flowers cannot be planted in **adjacent** plots.

Given an integer array `flowerbed` containing `0`'s and `1`'s, where `0` means empty and `1` means not empty, and an integer `n`, return `true` _if_ `n` _new flowers can be planted in the_ `flowerbed` _without violating the no-adjacent-flowers rule and_ `false` _otherwise_.

**Example 1:**

**Input:** flowerbed = \[1,0,0,0,1\], n = 1
**Output:** true

**Example 2:**

**Input:** flowerbed = \[1,0,0,0,1\], n = 2
**Output:** false

**Constraints:**

*   `1 <= flowerbed.length <= 2 * 104`
*   `flowerbed[i]` is `0` or `1`.
*   There are no two adjacent flowers in `flowerbed`.
*   `0 <= n <= flowerbed.length`

## A solution in Java

```java
public boolean canPlaceFlowers(int[] flowerbed, int n) {
    int count = 0;
    for(int i = 0; i < flowerbed.length; i++) {
        if(flowerbed[i] == 0 && (i == 0 || flowerbed[i - 1] == 0) && (i == flowerbed.length - 1 || flowerbed[i + 1] == 0)) {
            flowerbed[i] = 1;
            count++;
        }
        if(count >= n) return true;
    }
    return count >= n;
}
```
1. Initialize a variable `count` to keep track of the number of flowers planted.
2. Iterate through the flowerbed with a variable `i`.
3. Check the possibility of planting flowers at the current index:
   - If `flowerbed[i]` is already 0,
   - `i` is 0 (first plot) or the plot before the current plot is empty,
   - `i` is the last plot or the plot after the current plot is empty.
4. If all these conditions are met, plant a flower at the current plot by setting `flowerbed[i]` to 1 and increment the count.
5. If the count is equal to or greater than `n`, return true.
6. After iterating through the entire array, if the count is still equal to or greater than `n`, return true; otherwise, return false.

## A solution in C++

```cpp
bool canPlaceFlowers(vector<int>& flowerbed, int n) {
    int count = 0;
    for(int i = 0; i < flowerbed.size(); i++) {
        if(flowerbed[i] == 0 && (i == 0 || flowerbed[i - 1] == 0) && (i == flowerbed.size() - 1 || flowerbed[i + 1] == 0)) {
            flowerbed[i] = 1;
            count++;
        }
        if(count >= n) return true;
    }
    return count >= n;
}
```
1. Initialize a variable `count` to keep track of the number of flowers planted.
2. Iterate through the flowerbed with a variable `i`.
3. Check the possibility of planting flowers at the current index:
   - If `flowerbed[i]` is already 0,
   - `i` is 0 (first plot) or the plot before the current plot is empty,
   - `i` is the last plot or the plot after the current plot is empty.
4. If all these conditions are met, plant a flower at the current plot by setting `flowerbed[i]` to 1 and increment the count.
5. If the count is equal to or greater than `n`, return true.
6. After iterating through the entire array, if the count is still equal to or greater than `n`, return true; otherwise, return false.

## A solution in Python

```python
def canPlaceFlowers(flowerbed, n):
    count = 0
    for i in range(len(flowerbed)):
        if flowerbed[i] == 0 and (i == 0 or flowerbed[i - 1] == 0) and (i == len(flowerbed) - 1 or flowerbed[i + 1] == 0):
            flowerbed[i] = 1
            count += 1
        if count >= n:
            return True
    return count >= n
```
1. Initialize a variable `count` to keep track of the number of flowers planted.
2. Iterate through the flowerbed with a variable `i`.
3. Check the possibility of planting flowers at the current index:
   - If `flowerbed[i]` is already 0,
   - `i` is 0 (first plot) or the plot before the current plot is empty,
   - `i` is the last plot or the plot after the current plot is empty.
4. If all these conditions are met, plant a flower at the current plot by setting `flowerbed[i]` to 1 and increment the count.
5. If the count is equal to or greater than `n`, return true.
6. After iterating through the entire array, if the count is still equal to or greater than `n`, return true; otherwise, return false.

## A solution in Javascript

```javascript
function canPlaceFlowers(flowerbed, n) {
    let count = 0;
    for(let i = 0; i < flowerbed.length; i++) {
        if(flowerbed[i] === 0 && (i === 0 || flowerbed[i - 1] === 0) && (i === flowerbed.length - 1 || flowerbed[i + 1] === 0)) {
            flowerbed[i] = 1;
            count++;
        }
        if(count >= n) return true;
    }
    return count >= n;
}
```
1. Initialize a variable `count` to keep track of the number of flowers planted.
2. Iterate through the flowerbed with a variable `i`.
3. Check the possibility of planting flowers at the current index:
   - If `flowerbed[i]` is already 0,
   - `i` is 0 (first plot) or the plot before the current plot is empty,
   - `i` is the last plot or the plot after the current plot is empty.
4. If all these conditions are met, plant a flower at the current plot by setting `flowerbed[i]` to 1 and increment the count.
5. If the count is equal to or greater than `n`, return true.
6. After iterating through the entire array, if the count is still equal to or greater than `n`, return true; otherwise, return false.


# Construct String from Binary Tree

- slug: construct-string-from-binary-tree
- difficulty: Easy

Given the `root` of a binary tree, construct a string consisting of parenthesis and integers from a binary tree with the preorder traversal way, and return it.

Omit all the empty parenthesis pairs that do not affect the one-to-one mapping relationship between the string and the original binary tree.

**Example 1:**

**Input:** root = \[1,2,3,4\]
**Output:**  "1(2(4))(3) "
**Explanation:** Originally, it needs to be  "1(2(4)())(3()()) ", but you need to omit all the unnecessary empty parenthesis pairs. And it will be  "1(2(4))(3) "

**Example 2:**

**Input:** root = \[1,2,3,null,4\]
**Output:**  "1(2()(4))(3) "
**Explanation:** Almost the same as the first example, except we cannot omit the first parenthesis pair to break the one-to-one mapping relationship between the input and the output.

**Constraints:**

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

## A solution in Java

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

class Solution {
    public String tree2str(TreeNode t) {
        if (t == null) {
            return "";
        }
        if (t.left == null && t.right == null) {
            return t.val + "";
        }
        if (t.right == null) {
            return t.val + "(" + tree2str(t.left) + ")";
        }
        return t.val + "(" + tree2str(t.left) + ")(" + tree2str(t.right) + ")";
    }
}
```
The algorithm performs a modified preorder traversal of the binary tree. During the traversal, when we encounter a non-null node, we add the value of the node followed by left and right sub-trees enclosed in parentheses if they are not null. If the right subtree is null but the left subtree is not, then only the left subtree is added in parentheses. This way, we get a unique string representing the binary tree without any redundant empty parentheses. The algorithm works for each of the languages mentioned in the same way. The traversal is performed using recursion which saves nodes' values in the string representation.

## A solution in C++

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

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

string tree2str(TreeNode* t) {
    if (t == nullptr) {
        return "";
    }
    if (t->left == nullptr && t->right == nullptr) {
        return to_string(t->val);
    }
    if (t->right == nullptr) {
        return to_string(t->val) + "(" + tree2str(t->left) + ")";
    }
    return to_string(t->val) + "(" + tree2str(t->left) + ")(" + tree2str(t->right) + ")";
}
```
The algorithm performs a modified preorder traversal of the binary tree. During the traversal, when we encounter a non-null node, we add the value of the node followed by left and right sub-trees enclosed in parentheses if they are not null. If the right subtree is null but the left subtree is not, then only the left subtree is added in parentheses. This way, we get a unique string representing the binary tree without any redundant empty parentheses. The algorithm works for each of the languages mentioned in the same way. The traversal is performed using recursion which saves nodes' values in the string representation.

## A solution in Python

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

def tree2str(t):
    if not t:
        return ""
    if not t.left and not t.right:
        return str(t.val)
    if not t.right:
        return "{}({})".format(t.val, tree2str(t.left))
    return "{}({})({})".format(t.val, tree2str(t.left), tree2str(t.right))
```
The algorithm performs a modified preorder traversal of the binary tree. During the traversal, when we encounter a non-null node, we add the value of the node followed by left and right sub-trees enclosed in parentheses if they are not null. If the right subtree is null but the left subtree is not, then only the left subtree is added in parentheses. This way, we get a unique string representing the binary tree without any redundant empty parentheses. The algorithm works for each of the languages mentioned in the same way. The traversal is performed using recursion which saves nodes' values in the string representation.

## A solution in Javascript

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

var tree2str = function(t) {
    if (!t) {
        return "";
    }
    if (!t.left && !t.right) {
        return t.val + "";
    }
    if (!t.right) {
        return t.val + "(" + tree2str(t.left) + ")";
    }
    return t.val + "(" + tree2str(t.left) + ")(" + tree2str(t.right) + ")";
};
```
The algorithm performs a modified preorder traversal of the binary tree. During the traversal, when we encounter a non-null node, we add the value of the node followed by left and right sub-trees enclosed in parentheses if they are not null. If the right subtree is null but the left subtree is not, then only the left subtree is added in parentheses. This way, we get a unique string representing the binary tree without any redundant empty parentheses. The algorithm works for each of the languages mentioned in the same way. The traversal is performed using recursion which saves nodes' values in the string representation.


# Find Duplicate File in System

- slug: find-duplicate-file-in-system
- difficulty: Medium

Given a list `paths` of directory info, including the directory path, and all the files with contents in this directory, return _all the duplicate files in the file system in terms of their paths_. You may return the answer in **any order**.

A group of duplicate files consists of at least two files that have the same content.

A single directory info string in the input list has the following format:

*   `"root/d1/d2/.../dm f1.txt(f1_content) f2.txt(f2_content) ... fn.txt(fn_content) "`

It means there are `n` files `(f1.txt, f2.txt ... fn.txt)` with content `(f1_content, f2_content ... fn_content)` respectively in the directory "`root/d1/d2/.../dm "`. Note that `n >= 1` and `m >= 0`. If `m = 0`, it means the directory is just the root directory.

The output is a list of groups of duplicate file paths. For each group, it contains all the file paths of the files that have the same content. A file path is a string that has the following format:

*   `"directory_path/file_name.txt "`

**Example 1:**

**Input:** paths = \["root/a 1.txt(abcd) 2.txt(efgh)","root/c 3.txt(abcd)","root/c/d 4.txt(efgh)","root 4.txt(efgh)"\]
**Output:** \[\["root/a/2.txt","root/c/d/4.txt","root/4.txt"\],\["root/a/1.txt","root/c/3.txt"\]\]

**Example 2:**

**Input:** paths = \["root/a 1.txt(abcd) 2.txt(efgh)","root/c 3.txt(abcd)","root/c/d 4.txt(efgh)"\]
**Output:** \[\["root/a/2.txt","root/c/d/4.txt"\],\["root/a/1.txt","root/c/3.txt"\]\]

**Constraints:**

*   `1 <= paths.length <= 2 * 104`
*   `1 <= paths[i].length <= 3000`
*   `1 <= sum(paths[i].length) <= 5 * 105`
*   `paths[i]` consist of English letters, digits, `'/'`, `'.'`, `'('`, `')'`, and `' '`.
*   You may assume no files or directories share the same name in the same directory.
*   You may assume each given directory info represents a unique directory. A single blank space separates the directory path and file info.

**Follow up:**

*   Imagine you are given a real file system, how will you search files? DFS or BFS?
*   If the file content is very large (GB level), how will you modify your solution?
*   If you can only read the file by 1kb each time, how will you modify your solution?
*   What is the time complexity of your modified solution? What is the most time-consuming part and memory-consuming part of it? How to optimize?
*   How to make sure the duplicated files you find are not false positive?

## A solution in Java

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

public List<List<String>> findDuplicate(String[] paths) {
    HashMap<String, List<String>> contentMap = new HashMap<>();
    for (String path : paths) {
        String[] parts = path.split(" ");
        String directory = parts[0];
        for (int i = 1; i < parts.length; i++) {
            int start = parts[i].indexOf('(');
            int end = parts[i].indexOf(')');
            String content = parts[i].substring(start + 1, end);
            String filePath = directory + "/" + parts[i].substring(0, start);
            contentMap.computeIfAbsent(content, k -> new ArrayList<>()).add(filePath);
        }
    }
    List<List<String>> result = new ArrayList<>();
    for (List<String> filePaths : contentMap.values()) {
        if (filePaths.size() > 1) {
            result.add(filePaths);
        }
    }
    return result;
}
```
The algorithm proceeds as follows:

1. Create a hash map (content_map) with the content as the key and the list of corresponding file paths as the value.
2. Iterate through the paths list.
3. For each path, split it into components (directory and files).
4. Iterate through the files, and for each file, find the content between the parentheses and the file path.
5. Add the file path to the corresponding content entry in the content_map.
6. After processing all the paths, iterate through the content_map entries and add the lists with more than 1 file path to the result.

This algorithm has a time complexity of O(N), where N is the total number of files, as it processes each file once.

## A solution in C++

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

std::vector<std::vector<std::string>> findDuplicate(std::vector<std::string>& paths) {
    std::unordered_map<std::string, std::vector<std::string>> content_map;
    for (const std::string &path : paths) {
        std::istringstream iss(path);
        std::string directory;
        iss >> directory;
        std::string file;
        while (iss >> file) {
            size_t start = file.find('(');
            size_t end = file.find(')');
            std::string content = file.substr(start + 1, end - start - 1);
            std::string file_path = directory + "/" + file.substr(0, start);
            content_map[content].push_back(file_path);
        }
    }
    std::vector<std::vector<std::string>> result;
    for (const auto &entry : content_map) {
        if (entry.second.size() > 1) {
            result.push_back(entry.second);
        }
    }
    return result;
}
```
The algorithm proceeds as follows:

1. Create a hash map (content_map) with the content as the key and the list of corresponding file paths as the value.
2. Iterate through the paths list.
3. For each path, split it into components (directory and files).
4. Iterate through the files, and for each file, find the content between the parentheses and the file path.
5. Add the file path to the corresponding content entry in the content_map.
6. After processing all the paths, iterate through the content_map entries and add the lists with more than 1 file path to the result.

This algorithm has a time complexity of O(N), where N is the total number of files, as it processes each file once.

## A solution in Python

```python
from collections import defaultdict

def find_duplicate(paths):
    content_map = defaultdict(list)
    for path in paths:
        parts = path.split()
        directory = parts[0]
        for file in parts[1:]:
            start = file.index('(')
            end = file.index(')')
            content = file[start + 1:end]
            file_path = directory + '/' + file[:start]
            content_map[content].append(file_path)

    result = [file_paths for file_paths in content_map.values() if len(file_paths) > 1]
    return result
```
The algorithm proceeds as follows:

1. Create a hash map (content_map) with the content as the key and the list of corresponding file paths as the value.
2. Iterate through the paths list.
3. For each path, split it into components (directory and files).
4. Iterate through the files, and for each file, find the content between the parentheses and the file path.
5. Add the file path to the corresponding content entry in the content_map.
6. After processing all the paths, iterate through the content_map entries and add the lists with more than 1 file path to the result.

This algorithm has a time complexity of O(N), where N is the total number of files, as it processes each file once.

## A solution in Javascript

```javascript
function findDuplicate(paths) {
    const contentMap = new Map();

    for (const path of paths) {
        const parts = path.split(' ');
        const directory = parts[0];
        for (let i = 1; i < parts.length; i++) {
            const start = parts[i].indexOf('(');
            const end = parts[i].indexOf(')');
            const content = parts[i].substring(start + 1, end);
            const filePath = directory + '/' + parts[i].substring(0, start);

            if (!contentMap.has(content)) {
                contentMap.set(content, []);
            }
            contentMap.get(content).push(filePath);
        }
    }
    const result = [];
    for (const filePaths of contentMap.values()) {
        if (filePaths.length > 1) {
            result.push(filePaths);
        }
    }
    return result;
}
```
The algorithm proceeds as follows:

1. Create a hash map (content_map) with the content as the key and the list of corresponding file paths as the value.
2. Iterate through the paths list.
3. For each path, split it into components (directory and files).
4. Iterate through the files, and for each file, find the content between the parentheses and the file path.
5. Add the file path to the corresponding content entry in the content_map.
6. After processing all the paths, iterate through the content_map entries and add the lists with more than 1 file path to the result.

This algorithm has a time complexity of O(N), where N is the total number of files, as it processes each file once.


# Valid Triangle Number

- slug: valid-triangle-number
- difficulty: Medium

Given an integer array `nums`, return _the number of triplets chosen from the array that can make triangles if we take them as side lengths of a triangle_.

**Example 1:**

**Input:** nums = \[2,2,3,4\]
**Output:** 3
**Explanation:** Valid combinations are:
2,3,4 (using the first 2)
2,3,4 (using the second 2)
2,2,3

**Example 2:**

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

**Constraints:**

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

## A solution in Java

```java
public int triangleNumber(int[] nums) {
    Arrays.sort(nums);
    int count = 0;
    for (int i = 0; i < nums.length; ++i) {
        for (int j = i + 1; j < nums.length; ++j) {
            for (int k = j + 1; k < nums.length; ++k) {
                if (nums[i] + nums[j] > nums[k]) {
                    count++;
                }
                else {
                    break;
                }
            }
        }
    }
    return count;
}
```
1. Sort the given array in ascending order.
2. Iterate through the sorted array using three nested loops i, j, and k, where i < j < k. The loops go through possible triplet candidates (nums[i], nums[j], nums[k]).
3. For each triplet, check if nums[i] + nums[j] > nums[k]. If true, it satisfies the triangle inequality property, and we increase the count.
4. If nums[i] + nums[j] is not greater than nums[k], it means no other k value will satisfy the triangle inequality with the current i and j values. So, we break the innermost loop.
5. Return the count, which is the number of valid triplets.

## A solution in C++

```cpp
int triangleNumber(vector<int>& nums) {
    sort(nums.begin(), nums.end());
    int count = 0;
    for (int i = 0; i < nums.size(); ++i) {
        for (int j = i + 1; j < nums.size(); ++j) {
            for (int k = j + 1; k < nums.size(); ++k) {
                if (nums[i] + nums[j] > nums[k]) {
                    ++count;
                }
                else {
                    break;
                }
            }
        }
    }
    return count;
}
```
1. Sort the given array in ascending order.
2. Iterate through the sorted array using three nested loops i, j, and k, where i < j < k. The loops go through possible triplet candidates (nums[i], nums[j], nums[k]).
3. For each triplet, check if nums[i] + nums[j] > nums[k]. If true, it satisfies the triangle inequality property, and we increase the count.
4. If nums[i] + nums[j] is not greater than nums[k], it means no other k value will satisfy the triangle inequality with the current i and j values. So, we break the innermost loop.
5. Return the count, which is the number of valid triplets.

## A solution in Python

```python
def triangleNumber(nums: list) -> int:
    nums.sort()
    count = 0
    for i in range(len(nums)):
        for j in range(i + 1, len(nums)):
            for k in range(j + 1, len(nums)):
                if nums[i] + nums[j] > nums[k]:
                    count += 1
                else:
                    break
    return count
```
1. Sort the given array in ascending order.
2. Iterate through the sorted array using three nested loops i, j, and k, where i < j < k. The loops go through possible triplet candidates (nums[i], nums[j], nums[k]).
3. For each triplet, check if nums[i] + nums[j] > nums[k]. If true, it satisfies the triangle inequality property, and we increase the count.
4. If nums[i] + nums[j] is not greater than nums[k], it means no other k value will satisfy the triangle inequality with the current i and j values. So, we break the innermost loop.
5. Return the count, which is the number of valid triplets.

## A solution in Javascript

```javascript
function triangleNumber(nums) {
    nums.sort((a, b) => a - b);
    let count = 0;
    for (let i = 0; i < nums.length; ++i) {
        for (let j = i + 1; j < nums.length; ++j) {
            for (let k = j + 1; k < nums.length; ++k) {
                if (nums[i] + nums[j] > nums[k]) {
                    count++;
                }
                else {
                    break;
                }
            }
        }
    }
    return count;
}
```
1. Sort the given array in ascending order.
2. Iterate through the sorted array using three nested loops i, j, and k, where i < j < k. The loops go through possible triplet candidates (nums[i], nums[j], nums[k]).
3. For each triplet, check if nums[i] + nums[j] > nums[k]. If true, it satisfies the triangle inequality property, and we increase the count.
4. If nums[i] + nums[j] is not greater than nums[k], it means no other k value will satisfy the triangle inequality with the current i and j values. So, we break the innermost loop.
5. Return the count, which is the number of valid triplets.


# Add Bold Tag in String

- slug: add-bold-tag-in-string
- difficulty: Medium

You are given a string `s` and an array of strings `words`.

You should add a closed pair of bold tag **and** to wrap the substrings in `s` that exist in `words`.

*   If two such substrings overlap, you should wrap them together with only one pair of closed bold-tag.
*   If two substrings wrapped by bold tags are consecutive, you should combine them.

Return `s` _after adding the bold tags_.

**Example 1:**

**Input:** s =  "abcxyz123 ", words = \[ "abc ", "123 "\]
**Output:**  "**abc**xyz**123** "
**Explanation:** The two strings of words are substrings of s as following:  "abcxyz123 ".
We add ** before each substring and ** after each substring.

**Example 2:**

**Input:** s =  "aaabbb ", words = \[ "aa ", "b "\]
**Output:**  "**aaabbb** "
**Explanation:**
 "aa " appears as a substring two times:  "aaabbb " and  "aaabbb ".
 "b " appears as a substring three times:  "aaabbb ",  "aaabbb ", and  "aaabbb ".
We add ** before each substring and ** after each substring:  "**a**a**a****b****b****b** ".
Since the first two **'s overlap, we merge them:  "**aaa****b****b****b** ".
Since now the four **'s are consecuutive, we merge them:  "**aaabbb** ".****

****

**Constraints:**

*   `1 <= s.length <= 1000`
*   `0 <= words.length <= 100`
*   `1 <= words[i].length <= 1000`
*   `s` and `words[i]` consist of English letters and digits.
*   All the values of `words` are **unique**.

**Note:** This question is the same as 758: [https://leetcode.com/problems/bold-words-in-string/](https://leetcode.com/problems/bold-words-in-string/)

****

## A solution in Java

```java
import java.util.ArrayList;
import java.util.Arrays;

public String addBoldTag(String s, String[] words) {
    int n = s.length();
    boolean[] marked = new boolean[n];
    for (String word : words) {
        int pos = s.indexOf(word, 0);
        while (pos != -1) {
            Arrays.fill(marked, pos, pos + word.length(), true);
            pos = s.indexOf(word, pos + 1);
        }
    }
    StringBuilder result = new StringBuilder();
    for (int i = 0; i < n; i++) {
        if (marked[i] && (i == 0 || !marked[i - 1])) {
            result.append("<b>");
        }
        result.append(s.charAt(i));
        if (marked[i] && (i == n - 1 || !marked[i + 1])) {
            result.append("</b>");
        }
    }
    return result.toString();
}
```
1. Create an array `marked` of the same length as the string `s`, initialized with boolean value `false`.
2. Iterate through the words and, for each word, find its position in string `s` and mark each character, from the position till the end of the word, as `true` in the `marked` array. Repeat this process for all occurrences of the word in the string.
3. Initialize an empty result string.
4. Iterate through the string `s`. If the current character is marked and it is the first character or the previous one is not marked, add the opening tag `<b>` to the result string. Always append the current character to the result string. If the current character is marked and it is the last character or the next one is not marked, add the closing tag `</b>` to the result string.
5. Return the result string.

## A solution in C++

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

std::string addBoldTag(std::string s, std::vector<std::string>& words) {
    int n = s.size();
    std::vector<bool> marked(n, false);
    for (const auto& word : words) {
        int pos = s.find(word, 0);
        while (pos != std::string::npos) {
            std::fill(marked.begin() + pos, marked.begin() + pos + word.size(), true);
            pos = s.find(word, pos + 1);
        }
    }
    std::string result;
    for (int i = 0; i < n; ++i) {
        if (marked[i] && (i == 0 || !marked[i - 1])) {
            result += "<b>";
        }
        result += s[i];
        if (marked[i] && (i == n - 1 || !marked[i + 1])) {
            result += "</b>";
        }
    }
    return result;
}
```
1. Create an array `marked` of the same length as the string `s`, initialized with boolean value `false`.
2. Iterate through the words and, for each word, find its position in string `s` and mark each character, from the position till the end of the word, as `true` in the `marked` array. Repeat this process for all occurrences of the word in the string.
3. Initialize an empty result string.
4. Iterate through the string `s`. If the current character is marked and it is the first character or the previous one is not marked, add the opening tag `<b>` to the result string. Always append the current character to the result string. If the current character is marked and it is the last character or the next one is not marked, add the closing tag `</b>` to the result string.
5. Return the result string.

## A solution in Python

```python
def addBoldTag(s: str, words: list) -> str:
    n = len(s)
    marked = [False] * n
    for word in words:
        pos = s.find(word)
        while pos != -1:
            for i in range(pos, pos + len(word)):
                marked[i] = True
            pos = s.find(word, pos + 1)
    result = []
    i = 0
    while i < n:
        if marked[i]:
            result.append("<b>")
            while i < n and marked[i]:
                result.append(s[i])
                i += 1
            result.append("</b>")
        else:
            result.append(s[i])
            i += 1
    return "".join(result)
```
1. Create an array `marked` of the same length as the string `s`, initialized with boolean value `false`.
2. Iterate through the words and, for each word, find its position in string `s` and mark each character, from the position till the end of the word, as `true` in the `marked` array. Repeat this process for all occurrences of the word in the string.
3. Initialize an empty result string.
4. Iterate through the string `s`. If the current character is marked and it is the first character or the previous one is not marked, add the opening tag `<b>` to the result string. Always append the current character to the result string. If the current character is marked and it is the last character or the next one is not marked, add the closing tag `</b>` to the result string.
5. Return the result string.

## A solution in Javascript

```javascript
function addBoldTag(s, words) {
    const n = s.length;
    const marked = new Array(n).fill(false);
    for (const word of words) {
        let pos = s.indexOf(word, 0);
        while (pos !== -1) {
            marked.fill(true, pos, pos + word.length);
            pos = s.indexOf(word, pos + 1);
        }
    }
    let result = "";
    for (let i = 0; i < n; i++) {
        if (marked[i] && (i === 0 || !marked[i - 1])) {
            result += "<b>";
        }
        result += s[i];
        if (marked[i] && (i === n - 1 || !marked[i + 1])) {
            result += "</b>";
        }
    }
    return result;
}
```
1. Create an array `marked` of the same length as the string `s`, initialized with boolean value `false`.
2. Iterate through the words and, for each word, find its position in string `s` and mark each character, from the position till the end of the word, as `true` in the `marked` array. Repeat this process for all occurrences of the word in the string.
3. Initialize an empty result string.
4. Iterate through the string `s`. If the current character is marked and it is the first character or the previous one is not marked, add the opening tag `<b>` to the result string. Always append the current character to the result string. If the current character is marked and it is the last character or the next one is not marked, add the closing tag `</b>` to the result string.
5. Return the result string.


# Merge Two Binary Trees

- slug: merge-two-binary-trees
- difficulty: Easy

You are given two binary trees `root1` and `root2`.

Imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not. You need to merge the two trees into a new binary tree. The merge rule is that if two nodes overlap, then sum node values up as the new value of the merged node. Otherwise, the NOT null node will be used as the node of the new tree.

Return _the merged tree_.

**Note:** The merging process must start from the root nodes of both trees.

**Example 1:**

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

**Example 2:**

**Input:** root1 = \[1\], root2 = \[1,2\]
**Output:** \[2,2\]

**Constraints:**

*   The number of nodes in both trees is in the range `[0, 2000]`.
*   `-104 <= Node.val <= 104`

## A solution in Java

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

public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
    if (root1 == null) return root2;
    if (root2 == null) return root1;

    root1.val += root2.val;
    root1.left = mergeTrees(root1.left, root2.left);
    root1.right = mergeTrees(root1.right, root2.right);
    return root1;
}
```
The algorithm uses a recursive approach to merge the two given binary trees. We define a base case: If one of the tree nodes is null, we return the other tree node. For the overlapping nodes, we add the values of the two nodes and update the value of the first node. Then, we call the function recursively for the left and right child nodes of both trees. Finally, we return the first tree as a merged tree.

Here is a step-by-step explanation of the algorithm:

1. If `root1` is null, return `root2`, and vice versa.
2. Add the value of `root2` to the value of `root1`.
3. Call the function recursively for the left child nodes of both trees and store the result in `root1`'s left node.
4. Call the function recursively for the right child nodes of both trees and store the result in `root1`'st right node.
5. Return `root1` as the merged tree.

The algorithm ensures that the trees are merged according to the given conditions in the question.

## A solution in C++

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

TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
    if (root1 == nullptr) return root2;
    if (root2 == nullptr) return root1;

    root1->val += root2->val;
    root1->left = mergeTrees(root1->left, root2->left);
    root1->right = mergeTrees(root1->right, root2->right);
    return root1;
}
```
The algorithm uses a recursive approach to merge the two given binary trees. We define a base case: If one of the tree nodes is null, we return the other tree node. For the overlapping nodes, we add the values of the two nodes and update the value of the first node. Then, we call the function recursively for the left and right child nodes of both trees. Finally, we return the first tree as a merged tree.

Here is a step-by-step explanation of the algorithm:

1. If `root1` is null, return `root2`, and vice versa.
2. Add the value of `root2` to the value of `root1`.
3. Call the function recursively for the left child nodes of both trees and store the result in `root1`'s left node.
4. Call the function recursively for the right child nodes of both trees and store the result in `root1`'st right node.
5. Return `root1` as the merged tree.

The algorithm ensures that the trees are merged according to the given conditions in the question.

## A solution in Python

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

def merge_trees(root1: TreeNode, root2: TreeNode) -> TreeNode:
    if root1 is None: return root2
    if root2 is None: return root1

    root1.val += root2.val
    root1.left = merge_trees(root1.left, root2.left)
    root1.right = merge_trees(root1.right, root2.right)
    return root1
```
The algorithm uses a recursive approach to merge the two given binary trees. We define a base case: If one of the tree nodes is null, we return the other tree node. For the overlapping nodes, we add the values of the two nodes and update the value of the first node. Then, we call the function recursively for the left and right child nodes of both trees. Finally, we return the first tree as a merged tree.

Here is a step-by-step explanation of the algorithm:

1. If `root1` is null, return `root2`, and vice versa.
2. Add the value of `root2` to the value of `root1`.
3. Call the function recursively for the left child nodes of both trees and store the result in `root1`'s left node.
4. Call the function recursively for the right child nodes of both trees and store the result in `root1`'st right node.
5. Return `root1` as the merged tree.

The algorithm ensures that the trees are merged according to the given conditions in the question.

## A solution in Javascript

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

function mergeTrees(root1, root2) {
    if (root1 === null) return root2;
    if (root2 === null) return root1;

    root1.val += root2.val;
    root1.left = mergeTrees(root1.left, root2.left);
    root1.right = mergeTrees(root1.right, root2.right);
    return root1;
}
```
The algorithm uses a recursive approach to merge the two given binary trees. We define a base case: If one of the tree nodes is null, we return the other tree node. For the overlapping nodes, we add the values of the two nodes and update the value of the first node. Then, we call the function recursively for the left and right child nodes of both trees. Finally, we return the first tree as a merged tree.

Here is a step-by-step explanation of the algorithm:

1. If `root1` is null, return `root2`, and vice versa.
2. Add the value of `root2` to the value of `root1`.
3. Call the function recursively for the left child nodes of both trees and store the result in `root1`'s left node.
4. Call the function recursively for the right child nodes of both trees and store the result in `root1`'st right node.
5. Return `root1` as the merged tree.

The algorithm ensures that the trees are merged according to the given conditions in the question.


# Task Scheduler

- slug: task-scheduler
- difficulty: Medium

Given a characters array `tasks`, representing the tasks a CPU needs to do, where each letter represents a different task. Tasks could be done in any order. Each task is done in one unit of time. For each unit of time, the CPU could complete either one task or just be idle.

However, there is a non-negative integer `n` that represents the cooldown period between two **same tasks** (the same letter in the array), that is that there must be at least `n` units of time between any two same tasks.

Return _the least number of units of times that the CPU will take to finish all the given tasks_.

**Example 1:**

**Input:** tasks = \[ "A ", "A ", "A ", "B ", "B ", "B "\], n = 2
**Output:** 8
**Explanation:**
A -> B -> idle -> A -> B -> idle -> A -> B
There is at least 2 units of time between any two same tasks.

**Example 2:**

**Input:** tasks = \[ "A ", "A ", "A ", "B ", "B ", "B "\], n = 0
**Output:** 6
**Explanation:** On this case any permutation of size 6 would work since n = 0.
\[ "A ", "A ", "A ", "B ", "B ", "B "\]
\[ "A ", "B ", "A ", "B ", "A ", "B "\]
\[ "B ", "B ", "B ", "A ", "A ", "A "\]
...
And so on.

**Example 3:**

**Input:** tasks = \[ "A ", "A ", "A ", "A ", "A ", "A ", "B ", "C ", "D ", "E ", "F ", "G "\], n = 2
**Output:** 16
**Explanation:**
One possible solution is
A -> B -> C -> A -> D -> E -> A -> F -> G -> A -> idle -> idle -> A -> idle -> idle -> A

**Constraints:**

*   `1 <= task.length <= 104`
*   `tasks[i]` is upper-case English letter.
*   The integer `n` is in the range `[0, 100]`.

## A solution in Java

```java
import java.util.HashMap;
import java.util.PriorityQueue;

public int leastInterval(char[] tasks, int n) {
    HashMap<Character, Integer> taskFreq = new HashMap<>();
    for (char task : tasks) {
        taskFreq.put(task, taskFreq.getOrDefault(task, 0) + 1);
    }

    PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);
    maxHeap.addAll(taskFreq.values());

    int cycles = 0;

    while (!maxHeap.isEmpty()) {
        List<Integer> temp = new ArrayList<>();
        for (int i = 0; i < n + 1; i++) {
            if (!maxHeap.isEmpty()) {
                temp.add(maxHeap.remove());
            }
        }

        for (int freq : temp) {
            if (--freq > 0) {
                maxHeap.add(freq);
            }
        }

        cycles += maxHeap.isEmpty() ? temp.size() : n + 1;
    }

    return cycles;
}
```
1. Count the frequency of each task using a HashMap, and store these frequencies in a sorted array or list (sorted in descending order).
2. Calculate the maximum frequency (max_f) of a task, and the total number of idle slots required between tasks with this frequency. This is done by multiplying (max_f - 1) by the cooldown time (n).
3. Iterate through the remaining task frequencies, decrementing the idle slots by the minimum of the current task frequency and max_f.
4. If there are remaining idle slots, add this value to the total number of tasks to get the least number of units of time needed to complete all tasks. Otherwise, just return the total number of tasks, as there is no need for any idle time.

## A solution in C++

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

int leastInterval(std::vector<char>& tasks, int n) {
    std::unordered_map<char, int> task_freq;
    for (char task : tasks) {
        task_freq[task]++;
    }

    std::vector<int> frequencies;
    for (auto entry : task_freq) {
        frequencies.push_back(entry.second);
    }

    std::sort(frequencies.rbegin(), frequencies.rend());

    int max_f = frequencies[0] - 1;
    int idle_slots = max_f * n;

    for (int i = 1; i < frequencies.size(); i++) {
        idle_slots -= std::min(frequencies[i], max_f);
    }

    return idle_slots > 0 ? idle_slots + tasks.size() : tasks.size();
}
```
1. Count the frequency of each task using a HashMap, and store these frequencies in a sorted array or list (sorted in descending order).
2. Calculate the maximum frequency (max_f) of a task, and the total number of idle slots required between tasks with this frequency. This is done by multiplying (max_f - 1) by the cooldown time (n).
3. Iterate through the remaining task frequencies, decrementing the idle slots by the minimum of the current task frequency and max_f.
4. If there are remaining idle slots, add this value to the total number of tasks to get the least number of units of time needed to complete all tasks. Otherwise, just return the total number of tasks, as there is no need for any idle time.

## A solution in Python

```python
from collections import Counter

def least_interval(tasks, n):
    task_freq = Counter(tasks)

    max_f = max(task_freq.values())
    max_count = sum(1 for count in task_freq.values() if count == max_f)

    return max(len(tasks), (max_f - 1) * (n + 1) + max_count)
```
1. Count the frequency of each task using a HashMap, and store these frequencies in a sorted array or list (sorted in descending order).
2. Calculate the maximum frequency (max_f) of a task, and the total number of idle slots required between tasks with this frequency. This is done by multiplying (max_f - 1) by the cooldown time (n).
3. Iterate through the remaining task frequencies, decrementing the idle slots by the minimum of the current task frequency and max_f.
4. If there are remaining idle slots, add this value to the total number of tasks to get the least number of units of time needed to complete all tasks. Otherwise, just return the total number of tasks, as there is no need for any idle time.

## A solution in Javascript

```javascript
function leastInterval(tasks, n) {
    const taskFreq = {};
    tasks.forEach(task => {
        taskFreq[task] = (taskFreq[task] || 0) + 1;
    });

    const frequencies = Object.values(taskFreq).sort((a, b) => b - a);

    const maxF = frequencies[0] - 1;
    let idleSlots = maxF * n;

    for (let i = 1; i < frequencies.length; i++) {
        idleSlots -= Math.min(frequencies[i], maxF);
    }

    return idleSlots > 0 ? idleSlots + tasks.length : tasks.length;
}
```
1. Count the frequency of each task using a HashMap, and store these frequencies in a sorted array or list (sorted in descending order).
2. Calculate the maximum frequency (max_f) of a task, and the total number of idle slots required between tasks with this frequency. This is done by multiplying (max_f - 1) by the cooldown time (n).
3. Iterate through the remaining task frequencies, decrementing the idle slots by the minimum of the current task frequency and max_f.
4. If there are remaining idle slots, add this value to the total number of tasks to get the least number of units of time needed to complete all tasks. Otherwise, just return the total number of tasks, as there is no need for any idle time.


# Design Circular Queue

- slug: design-circular-queue
- difficulty: Medium

Design your implementation of the circular queue. The circular queue is a linear data structure in which the operations are performed based on FIFO (First In First Out) principle, and the last position is connected back to the first position to make a circle. It is also called "Ring Buffer ".

One of the benefits of the circular queue is that we can make use of the spaces in front of the queue. In a normal queue, once the queue becomes full, we cannot insert the next element even if there is a space in front of the queue. But using the circular queue, we can use the space to store new values.

Implement the `MyCircularQueue` class:

*   `MyCircularQueue(k)` Initializes the object with the size of the queue to be `k`.
*   `int Front()` Gets the front item from the queue. If the queue is empty, return `-1`.
*   `int Rear()` Gets the last item from the queue. If the queue is empty, return `-1`.
*   `boolean enQueue(int value)` Inserts an element into the circular queue. Return `true` if the operation is successful.
*   `boolean deQueue()` Deletes an element from the circular queue. Return `true` if the operation is successful.
*   `boolean isEmpty()` Checks whether the circular queue is empty or not.
*   `boolean isFull()` Checks whether the circular queue is full or not.

You must solve the problem without using the built-in queue data structure in your programming language.

**Example 1:**

**Input**
\[ "MyCircularQueue ",  "enQueue ",  "enQueue ",  "enQueue ",  "enQueue ",  "Rear ",  "isFull ",  "deQueue ",  "enQueue ",  "Rear "\]
\[\[3\], \[1\], \[2\], \[3\], \[4\], \[\], \[\], \[\], \[4\], \[\]\]
**Output**
\[null, true, true, true, false, 3, true, true, true, 4\]

**Explanation**
MyCircularQueue myCircularQueue = new MyCircularQueue(3);
myCircularQueue.enQueue(1); // return True
myCircularQueue.enQueue(2); // return True
myCircularQueue.enQueue(3); // return True
myCircularQueue.enQueue(4); // return False
myCircularQueue.Rear();     // return 3
myCircularQueue.isFull();   // return True
myCircularQueue.deQueue();  // return True
myCircularQueue.enQueue(4); // return True
myCircularQueue.Rear();     // return 4

**Constraints:**

*   `1 <= k <= 1000`
*   `0 <= value <= 1000`
*   At most `3000` calls will be made to `enQueue`, `deQueue`, `Front`, `Rear`, `isEmpty`, and `isFull`.

## A solution in Java

```java
class MyCircularQueue {
    private int[] data;
    private int front;
    private int rear;
    private int size;

    public MyCircularQueue(int k) {
        size = k;
        data = new int[k];
        front = -1;
        rear = -1;
    }

    public boolean enQueue(int value) {
        if (isFull()) return false;
        if (isEmpty()) front = 0;
        rear = (rear + 1) % size;
        data[rear] = value;
        return true;
    }

    public boolean deQueue() {
        if (isEmpty()) return false;
        if (front == rear) {
            front = -1;
            rear = -1;
        } else {
            front = (front + 1) % size;
        }
        return true;
    }

    public int Front() {
        if (isEmpty()) return -1;
        return data[front];
    }

    public int Rear() {
        if (isEmpty()) return -1;
        return data[rear];
    }

    public boolean isEmpty() {
        return front == -1;
    }

    public boolean isFull() {
        return (rear + 1) % size == front;
    }
}
```
To implement a circular queue, we use an array of fixed size, and two pointers, `front` and `rear`, to keep track of the queue's current state:

- Initialize the queue by setting its size `k`, the array with size `k`, and both pointers to -1.
- Check whether the queue is empty by checking if the `front` pointer is -1.
- Check whether the queue is full by checking whether the next available spot after the `rear` pointer is equal to the `front` pointer. Calculate it as `(rear + 1) % size == front`.
- To insert an element, move the `rear` pointer (modulo the queue size) and set the new value at `rear`.
- To delete an element, move the `front` pointer (modulo the queue size).
- To get the item at the front, return the value at the `front` pointer in the array.
- To get the item at the rear, return the value at the `rear` pointer in the array.

## A solution in C++

```cpp
class MyCircularQueue {
public:
    MyCircularQueue(int k) {
        size = k;
        data.resize(k);
        front = -1;
        rear = -1;
    }

    bool enQueue(int value) {
        if (isFull()) return false;
        if (isEmpty()) front = 0;
        rear = (rear + 1) % size;
        data[rear] = value;
        return true;
    }

    bool deQueue() {
        if (isEmpty()) return false;
        if (front == rear) {
            front = -1;
            rear = -1;
        } else {
            front = (front + 1) % size;
        }
        return true;
    }

    int Front() {
        if (isEmpty()) return -1;
        return data[front];
    }

    int Rear() {
        if (isEmpty()) return -1;
        return data[rear];
    }

    bool isEmpty() {
        return front == -1;
    }

    bool isFull() {
        return (rear + 1) % size == front;
    }

private:
    vector<int> data;
    int front;
    int rear;
    int size;
};
```
To implement a circular queue, we use an array of fixed size, and two pointers, `front` and `rear`, to keep track of the queue's current state:

- Initialize the queue by setting its size `k`, the array with size `k`, and both pointers to -1.
- Check whether the queue is empty by checking if the `front` pointer is -1.
- Check whether the queue is full by checking whether the next available spot after the `rear` pointer is equal to the `front` pointer. Calculate it as `(rear + 1) % size == front`.
- To insert an element, move the `rear` pointer (modulo the queue size) and set the new value at `rear`.
- To delete an element, move the `front` pointer (modulo the queue size).
- To get the item at the front, return the value at the `front` pointer in the array.
- To get the item at the rear, return the value at the `rear` pointer in the array.

## A solution in Python

```python
class MyCircularQueue:

    def __init__(self, k: int):
        self.size = k
        self.data = [0]*k
        self.front = -1
        self.rear = -1

    def enQueue(self, value: int) -> bool:
        if self.isFull():
            return False
        if self.isEmpty():
            self.front = 0
        self.rear = (self.rear + 1) % self.size
        self.data[self.rear] = value
        return True

    def deQueue(self) -> bool:
        if self.isEmpty():
            return False
        if self.front == self.rear:
            self.front = -1
            self.rear = -1
        else:
            self.front = (self.front + 1) % self.size
        return True

    def Front(self) -> int:
        if self.isEmpty():
            return -1
        return self.data[self.front]

    def Rear(self) -> int:
        if self.isEmpty():
            return -1
        return self.data[self.rear]

    def isEmpty(self) -> bool:
        return self.front == -1

    def isFull(self) -> bool:
        return (self.rear + 1) % self.size == self.front
```
To implement a circular queue, we use an array of fixed size, and two pointers, `front` and `rear`, to keep track of the queue's current state:

- Initialize the queue by setting its size `k`, the array with size `k`, and both pointers to -1.
- Check whether the queue is empty by checking if the `front` pointer is -1.
- Check whether the queue is full by checking whether the next available spot after the `rear` pointer is equal to the `front` pointer. Calculate it as `(rear + 1) % size == front`.
- To insert an element, move the `rear` pointer (modulo the queue size) and set the new value at `rear`.
- To delete an element, move the `front` pointer (modulo the queue size).
- To get the item at the front, return the value at the `front` pointer in the array.
- To get the item at the rear, return the value at the `rear` pointer in the array.

## A solution in Javascript

```javascript
class MyCircularQueue {
    constructor(k) {
        this.size = k;
        this.data = new Array(k);
        this.front = -1;
        this.rear = -1;
    }

    enQueue(value) {
        if (this.isFull()) return false;
        if (this.isEmpty()) this.front = 0;
        this.rear = (this.rear + 1) % this.size;
        this.data[this.rear] = value;
        return true;
    }

    deQueue() {
        if (this.isEmpty()) return false;
        if (this.front === this.rear) {
            this.front = -1;
            this.rear = -1;
        } else {
            this.front = (this.front + 1) % this.size;
        }
        return true;
    }

    Front() {
        if (this.isEmpty()) return -1;
        return this.data[this.front];
    }

    Rear() {
        if (this.isEmpty()) return -1;
        return this.data[this.rear];
    }

    isEmpty() {
        return this.front === -1;
    }

    isFull() {
        return (this.rear + 1) % this.size === this.front;
    }
}
```
To implement a circular queue, we use an array of fixed size, and two pointers, `front` and `rear`, to keep track of the queue's current state:

- Initialize the queue by setting its size `k`, the array with size `k`, and both pointers to -1.
- Check whether the queue is empty by checking if the `front` pointer is -1.
- Check whether the queue is full by checking whether the next available spot after the `rear` pointer is equal to the `front` pointer. Calculate it as `(rear + 1) % size == front`.
- To insert an element, move the `rear` pointer (modulo the queue size) and set the new value at `rear`.
- To delete an element, move the `front` pointer (modulo the queue size).
- To get the item at the front, return the value at the `front` pointer in the array.
- To get the item at the rear, return the value at the `rear` pointer in the array.


# Add One Row to Tree

- slug: add-one-row-to-tree
- difficulty: Medium

Given the `root` of a binary tree and two integers `val` and `depth`, add a row of nodes with value `val` at the given depth `depth`.

Note that the `root` node is at depth `1`.

The adding rule is:

*   Given the integer `depth`, for each not null tree node `cur` at the depth `depth - 1`, create two tree nodes with value `val` as `cur`'s left subtree root and right subtree root.
*   `cur`'s original left subtree should be the left subtree of the new left subtree root.
*   `cur`'s original right subtree should be the right subtree of the new right subtree root.
*   If `depth == 1` that means there is no depth `depth - 1` at all, then create a tree node with value `val` as the new root of the whole original tree, and the original tree is the new root's left subtree.

**Example 1:**

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

**Example 2:**

**Input:** root = \[4,2,null,3,1\], val = 1, depth = 3
**Output:** \[4,2,null,1,1,3,null,null,1\]

**Constraints:**

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

## A solution in Java

```java
public void addOneRowHelper(TreeNode node, int val, int depth, int currentDepth) {
    if (node == null) return;
    if (currentDepth == depth - 1) {
        TreeNode left = node.left;
        TreeNode right = node.right;
        node.left = new TreeNode(val);
        node.left.left = left;
        node.right = new TreeNode(val);
        node.right.right = right;
    } else {
        addOneRowHelper(node.left, val, depth, currentDepth + 1);
        addOneRowHelper(node.right, val, depth, currentDepth + 1);
    }
}

public TreeNode addOneRow(TreeNode root, int val, int depth) {
    if (depth == 1) {
        TreeNode newRoot = new TreeNode(val);
        newRoot.left = root;
        return newRoot;
    }
    addOneRowHelper(root, val, depth, 1);
    return root;
}
```
1. If the given depth is 1, create a new root with the given value and make the left child of the new root be the original root, then return the new root.
2. Otherwise, create a helper function to traverse the tree and handle the addition of the new row of nodes. This function takes the current node, the value, the target depth, and the current depth as arguments.
3. For each node in the tree, if the current depth is equal to the target depth minus 1, it means that we need to add the new row of nodes below this node. So, we create two new nodes with the given value, and make their corresponding children be the original children of the current node. Then set the new nodes as the children of the current node.
4. If the current depth is not equal to the target depth minus 1, continue recursively visiting the left and right children with an incremented current depth.
5. Finally, call the helper function starting at the root with a current depth of 1, and then return the root of the modified tree.

## A solution in C++

```cpp
void addOneRowHelper(TreeNode* node, int val, int depth, int currentDepth) {
    if (node == nullptr) return;
    if (currentDepth == depth - 1) {
        TreeNode* left = node->left;
        TreeNode* right = node->right;
        node->left = new TreeNode(val);
        node->left->left = left;
        node->right = new TreeNode(val);
        node->right->right = right;
    } else {
        addOneRowHelper(node->left, val, depth, currentDepth + 1);
        addOneRowHelper(node->right, val, depth, currentDepth + 1);
    }
}

TreeNode* addOneRow(TreeNode* root, int val, int depth) {
    if (depth == 1) {
        TreeNode* newRoot = new TreeNode(val);
        newRoot->left = root;
        return newRoot;
    }
    addOneRowHelper(root, val, depth, 1);
    return root;
}
```
1. If the given depth is 1, create a new root with the given value and make the left child of the new root be the original root, then return the new root.
2. Otherwise, create a helper function to traverse the tree and handle the addition of the new row of nodes. This function takes the current node, the value, the target depth, and the current depth as arguments.
3. For each node in the tree, if the current depth is equal to the target depth minus 1, it means that we need to add the new row of nodes below this node. So, we create two new nodes with the given value, and make their corresponding children be the original children of the current node. Then set the new nodes as the children of the current node.
4. If the current depth is not equal to the target depth minus 1, continue recursively visiting the left and right children with an incremented current depth.
5. Finally, call the helper function starting at the root with a current depth of 1, and then return the root of the modified tree.

## A solution in Python

```python
def add_one_row_helper(node, val, depth, current_depth):
    if not node:
        return
    if current_depth == depth - 1:
        left = node.left
        right = node.right
        node.left = TreeNode(val)
        node.left.left = left
        node.right = TreeNode(val)
        node.right.right = right
    else:
        add_one_row_helper(node.left, val, depth, current_depth + 1)
        add_one_row_helper(node.right, val, depth, current_depth + 1)

def add_one_row(root, val, depth):
    if depth == 1:
        new_root = TreeNode(val)
        new_root.left = root
        return new_root
    add_one_row_helper(root, val, depth, 1)
    return root
```
1. If the given depth is 1, create a new root with the given value and make the left child of the new root be the original root, then return the new root.
2. Otherwise, create a helper function to traverse the tree and handle the addition of the new row of nodes. This function takes the current node, the value, the target depth, and the current depth as arguments.
3. For each node in the tree, if the current depth is equal to the target depth minus 1, it means that we need to add the new row of nodes below this node. So, we create two new nodes with the given value, and make their corresponding children be the original children of the current node. Then set the new nodes as the children of the current node.
4. If the current depth is not equal to the target depth minus 1, continue recursively visiting the left and right children with an incremented current depth.
5. Finally, call the helper function starting at the root with a current depth of 1, and then return the root of the modified tree.

## A solution in Javascript

```javascript
function addOneRowHelper(node, val, depth, currentDepth) {
    if (!node) return;
    if (currentDepth === depth - 1) {
        let left = node.left;
        let right = node.right;
        node.left = new TreeNode(val);
        node.left.left = left;
        node.right = new TreeNode(val);
        node.right.right = right;
    } else {
        addOneRowHelper(node.left, val, depth, currentDepth + 1);
        addOneRowHelper(node.right, val, depth, currentDepth + 1);
    }
}

function addOneRow(root, val, depth) {
    if (depth === 1) {
        let newRoot = new TreeNode(val);
        newRoot.left = root;
        return newRoot;
    }
    addOneRowHelper(root, val, depth, 1);
    return root;
}
```
1. If the given depth is 1, create a new root with the given value and make the left child of the new root be the original root, then return the new root.
2. Otherwise, create a helper function to traverse the tree and handle the addition of the new row of nodes. This function takes the current node, the value, the target depth, and the current depth as arguments.
3. For each node in the tree, if the current depth is equal to the target depth minus 1, it means that we need to add the new row of nodes below this node. So, we create two new nodes with the given value, and make their corresponding children be the original children of the current node. Then set the new nodes as the children of the current node.
4. If the current depth is not equal to the target depth minus 1, continue recursively visiting the left and right children with an incremented current depth.
5. Finally, call the helper function starting at the root with a current depth of 1, and then return the root of the modified tree.


# Maximum Distance in Arrays

- slug: maximum-distance-in-arrays
- difficulty: Medium

You are given `m` `arrays`, where each array is sorted in **ascending order**.

You can pick up two integers from two different arrays (each array picks one) and calculate the distance. We define the distance between two integers `a` and `b` to be their absolute difference `|a - b|`.

Return _the maximum distance_.

**Example 1:**

**Input:** arrays = \[\[1,2,3\],\[4,5\],\[1,2,3\]\]
**Output:** 4
**Explanation:** One way to reach the maximum distance 4 is to pick 1 in the first or third array and pick 5 in the second array.

**Example 2:**

**Input:** arrays = \[\[1\],\[1\]\]
**Output:** 0

**Constraints:**

*   `m == arrays.length`
*   `2 <= m <= 105`
*   `1 <= arrays[i].length <= 500`
*   `-104 <= arrays[i][j] <= 104`
*   `arrays[i]` is sorted in **ascending order**.
*   There will be at most `105` integers in all the arrays.

## A solution in Java

```java
public int maxDistance(List<List<Integer>> arrays) {
    int max_dist = 0, min_val = arrays.get(0).get(0), max_val = arrays.get(0).get(arrays.get(0).size() - 1);
    for (int i = 1; i < arrays.size(); i++) {
        max_dist = Math.max(max_dist, Math.max(
                Math.abs(arrays.get(i).get(arrays.get(i).size() - 1) - min_val),
                Math.abs(max_val - arrays.get(i).get(0))
        ));
        min_val = Math.min(min_val, arrays.get(i).get(0));
        max_val = Math.max(max_val, arrays.get(i).get(arrays.get(i).size() - 1));
    }
    return max_dist;
}
```
We start by initializing the `max_dist` as 0, and get the minimum and maximum values from the first array in the list. Then, we iterate through the other arrays starting from index 1. For each array, we calculate the maximum distance between the current minimum value and the last element of that array, or the current maximum value and the first element of the current array. Using the calculated maximum distance, we update the maximum distance `max_dist` if it exceeds the current value. Finally, we update the minimum and maximum values with the minimum and maximum of the current array. This approach ensures that we are considering the possible array combinations without calculating every possible pair.

## A solution in C++

```cpp
int maxDistance(vector<vector<int>>& arrays) {
    int max_dist = 0, min_val = arrays[0][0], max_val = arrays[0].back();
    for(int i = 1; i < arrays.size(); i++) {
        max_dist = max(max_dist, max(abs(arrays[i].back() - min_val), abs(max_val - arrays[i][0])));
        min_val = min(min_val, arrays[i][0]);
        max_val = max(max_val, arrays[i].back());
    }
    return max_dist;
}
```
We start by initializing the `max_dist` as 0, and get the minimum and maximum values from the first array in the list. Then, we iterate through the other arrays starting from index 1. For each array, we calculate the maximum distance between the current minimum value and the last element of that array, or the current maximum value and the first element of the current array. Using the calculated maximum distance, we update the maximum distance `max_dist` if it exceeds the current value. Finally, we update the minimum and maximum values with the minimum and maximum of the current array. This approach ensures that we are considering the possible array combinations without calculating every possible pair.

## A solution in Python

```python
def maxDistance(arrays: List[List[int]]) -> int:
    max_dist = 0
    min_val = arrays[0][0]
    max_val = arrays[0][-1]

    for arr in arrays[1:]:
        max_dist = max(max_dist, max(abs(arr[-1] - min_val), abs(max_val - arr[0])))
        min_val = min(min_val, arr[0])
        max_val = max(max_val, arr[-1])

    return max_dist
```
We start by initializing the `max_dist` as 0, and get the minimum and maximum values from the first array in the list. Then, we iterate through the other arrays starting from index 1. For each array, we calculate the maximum distance between the current minimum value and the last element of that array, or the current maximum value and the first element of the current array. Using the calculated maximum distance, we update the maximum distance `max_dist` if it exceeds the current value. Finally, we update the minimum and maximum values with the minimum and maximum of the current array. This approach ensures that we are considering the possible array combinations without calculating every possible pair.

## A solution in Javascript

```javascript
var maxDistance = function(arrays) {
    let max_dist = 0;
    let min_val = arrays[0][0];
    let max_val = arrays[0][arrays[0].length - 1];

    for (let i = 1; i < arrays.length; i++) {
        max_dist = Math.max(max_dist, Math.max(
            Math.abs(arrays[i][arrays[i].length - 1] - min_val),
            Math.abs(max_val - arrays[i][0])
        ));
        min_val = Math.min(min_val, arrays[i][0]);
        max_val = Math.max(max_val, arrays[i][arrays[i].length - 1]);
    }
    return max_dist;
};
```
We start by initializing the `max_dist` as 0, and get the minimum and maximum values from the first array in the list. Then, we iterate through the other arrays starting from index 1. For each array, we calculate the maximum distance between the current minimum value and the last element of that array, or the current maximum value and the first element of the current array. Using the calculated maximum distance, we update the maximum distance `max_dist` if it exceeds the current value. Finally, we update the minimum and maximum values with the minimum and maximum of the current array. This approach ensures that we are considering the possible array combinations without calculating every possible pair.


# Minimum Factorization

- slug: minimum-factorization
- difficulty: Medium

Given a positive integer num, return _the smallest positive integer_ `x` _whose multiplication of each digit equals_ `num`. If there is no answer or the answer is not fit in **32-bit** signed integer, return `0`.

**Example 1:**

**Input:** num = 48
**Output:** 68

**Example 2:**

**Input:** num = 15
**Output:** 35

**Constraints:**

*   `1 <= num <= 231 - 1`

## A solution in Java

```java
public int smallestFactorization(int num) {
    if (num == 1) return 1;
    long result = 0, factor = 1;
    for (int i = 9; i > 1; --i) {
        while (num % i == 0) {
            num /= i;
            result += i * factor;
            factor *= 10;
            if (result > Integer.MAX_VALUE) return 0;
        }
    }
    return num == 1 ? (int) result : 0;
}
```
The algorithm iterates from 9 to 2 (in reverse order) and divides the input number `num` by the current iterating value `i`. If `num` is completely divisible by `i`, the loop updates `result` by adding the current `i * factor` and updating the `factor` by multiplying it by 10. If `result` ever goes beyond the 32-bit signed integer limit, the function returns 0. The loop continues to iterate and divide `num` until `num` becomes 1 (i.e., all factors have been found) or there are no more appropriate dividers. If `num` is 1, i.e., all factors are found, the result is returned; otherwise, the function returns 0.

## A solution in C++

```cpp
int smallestFactorization(int num) {
    if (num == 1) return 1;
    long result = 0, factor = 1;
    for (int i = 9; i > 1; --i) {
        while (num % i == 0) {
            num /= i;
            result += i * factor;
            factor *= 10;
            if (result > INT_MAX) return 0;
        }
    }
    return num == 1 ? result : 0;
}
```
The algorithm iterates from 9 to 2 (in reverse order) and divides the input number `num` by the current iterating value `i`. If `num` is completely divisible by `i`, the loop updates `result` by adding the current `i * factor` and updating the `factor` by multiplying it by 10. If `result` ever goes beyond the 32-bit signed integer limit, the function returns 0. The loop continues to iterate and divide `num` until `num` becomes 1 (i.e., all factors have been found) or there are no more appropriate dividers. If `num` is 1, i.e., all factors are found, the result is returned; otherwise, the function returns 0.

## A solution in Python

```python
def smallestFactorization(num: int) -> int:
    if num == 1:
        return 1
    result = 0
    factor = 1
    for i in range(9, 1, -1):
        while num % i == 0:
            num //= i
            result += i * factor
            factor *= 10
            if result > 2**31 - 1:
                return 0
    return result if num == 1 else 0
```
The algorithm iterates from 9 to 2 (in reverse order) and divides the input number `num` by the current iterating value `i`. If `num` is completely divisible by `i`, the loop updates `result` by adding the current `i * factor` and updating the `factor` by multiplying it by 10. If `result` ever goes beyond the 32-bit signed integer limit, the function returns 0. The loop continues to iterate and divide `num` until `num` becomes 1 (i.e., all factors have been found) or there are no more appropriate dividers. If `num` is 1, i.e., all factors are found, the result is returned; otherwise, the function returns 0.

## A solution in Javascript

```javascript
function smallestFactorization(num) {
    if (num === 1) return 1;
    let result = 0, factor = 1;
    for (let i = 9; i > 1; --i) {
        while (num % i === 0) {
            num /= i;
            result += i * factor;
            factor *= 10;
            if (result > (2**31 - 1)) return 0;
        }
    }
    return num === 1 ? result : 0;
}
```
The algorithm iterates from 9 to 2 (in reverse order) and divides the input number `num` by the current iterating value `i`. If `num` is completely divisible by `i`, the loop updates `result` by adding the current `i * factor` and updating the `factor` by multiplying it by 10. If `result` ever goes beyond the 32-bit signed integer limit, the function returns 0. The loop continues to iterate and divide `num` until `num` becomes 1 (i.e., all factors have been found) or there are no more appropriate dividers. If `num` is 1, i.e., all factors are found, the result is returned; otherwise, the function returns 0.


# Maximum Product of Three Numbers

- slug: maximum-product-of-three-numbers
- difficulty: Easy

Given an integer array `nums`, _find three numbers whose product is maximum and return the maximum product_.

**Example 1:**

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

**Example 2:**

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

**Example 3:**

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

**Constraints:**

*   `3 <= nums.length <= 104`
*   `-1000 <= nums[i] <= 1000`

## A solution in Java

```java
public int maximumProduct(int[] nums) {
    Arrays.sort(nums);
    int n = nums.length;
    return Math.max(nums[0] * nums[1] * nums[n-1], nums[n-1] * nums[n-2] * nums[n-3]);
}
```
First, we sort the input array in non-decreasing order. After sorting, we can determine the maximum product using two possible scenarios.

1. The maximum product is formed by the product of the three highest numbers in the array. We can get this by multiplying the last three elements of the sorted array.

2. The maximum product is formed by the product of the two lowest (most negative) numbers and the highest number in the array. We can get this by multiplying the first two elements and the last element of the sorted array.

We take the maximum of these two results to get the final answer.

## A solution in C++

```cpp
int maximumProduct(vector<int>& nums) {
    sort(nums.begin(), nums.end());
    int n = nums.size();
    return max(nums[0] * nums[1] * nums[n-1], nums[n-1] * nums[n-2] * nums[n-3]);
}
```
First, we sort the input array in non-decreasing order. After sorting, we can determine the maximum product using two possible scenarios.

1. The maximum product is formed by the product of the three highest numbers in the array. We can get this by multiplying the last three elements of the sorted array.

2. The maximum product is formed by the product of the two lowest (most negative) numbers and the highest number in the array. We can get this by multiplying the first two elements and the last element of the sorted array.

We take the maximum of these two results to get the final answer.

## A solution in Python

```python
def maximumProduct(nums):
    nums.sort()
    n = len(nums)
    return max(nums[0] * nums[1] * nums[-1], nums[-1] * nums[-2] * nums[-3])
```
First, we sort the input array in non-decreasing order. After sorting, we can determine the maximum product using two possible scenarios.

1. The maximum product is formed by the product of the three highest numbers in the array. We can get this by multiplying the last three elements of the sorted array.

2. The maximum product is formed by the product of the two lowest (most negative) numbers and the highest number in the array. We can get this by multiplying the first two elements and the last element of the sorted array.

We take the maximum of these two results to get the final answer.

## A solution in Javascript

```javascript
function maximumProduct(nums) {
    nums.sort((a, b) => a - b);
    const n = nums.length;
    return Math.max(nums[0] * nums[1] * nums[n-1], nums[n-1] * nums[n-2] * nums[n-3]);
}
```
First, we sort the input array in non-decreasing order. After sorting, we can determine the maximum product using two possible scenarios.

1. The maximum product is formed by the product of the three highest numbers in the array. We can get this by multiplying the last three elements of the sorted array.

2. The maximum product is formed by the product of the two lowest (most negative) numbers and the highest number in the array. We can get this by multiplying the first two elements and the last element of the sorted array.

We take the maximum of these two results to get the final answer.