# Binary Tree Vertical Order Traversal

- slug: binary-tree-vertical-order-traversal
- difficulty: Medium

Given the `root` of a binary tree, return _**the vertical order traversal** of its nodes' values_. (i.e., from top to bottom, column by column).

If two nodes are in the same row and column, the order should be from **left to right**.

**Example 1:**

**Input:** root = \[3,9,20,null,null,15,7\]
**Output:** \[\[9\],\[3,15\],\[20\],\[7\]\]

**Example 2:**

**Input:** root = \[3,9,8,4,0,1,7\]
**Output:** \[\[4\],\[9\],\[3,0,1\],\[8\],\[7\]\]

**Example 3:**

**Input:** root = \[3,9,8,4,0,1,7,null,null,null,2,5\]
**Output:** \[\[4\],\[9,5\],\[3,0,1\],\[8,2\],\[7\]\]

**Constraints:**

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

## A solution in Java

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

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

class Solution {
    public List<List<Integer>> verticalOrder(TreeNode root) {
        if (root == null) return new ArrayList<>();

        HashMap<Integer, List<Integer>> columnTable = new HashMap<>();
        Queue<Pair<TreeNode, Integer>> q = new LinkedList<>();
        q.offer(new Pair<>(root, 0));

        while (!q.isEmpty()) {
            TreeNode curNode = q.peek().getKey();
            int column = q.peek().getValue();
            q.poll();

            if (curNode != null) {
                columnTable.putIfAbsent(column, new ArrayList<>());
                columnTable.get(column).add(curNode.val);
                q.offer(new Pair<>(curNode.left, column - 1));
                q.offer(new Pair<>(curNode.right, column + 1));
            }
        }

        return new ArrayList<>(columnTable.values());
    }
}
```
The algorithm for vertical order traversal works as follows:
1. Create a mapping of columns to their corresponding node values. Initialize a queue to store nodes and their columns, starting with the root at column 0.
2. While the queue is not empty, dequeue the node and column. Add the node's value to the corresponding column in the mapping.
3. Enqueue the node's left and right children with their respective column values (left child gets column -1, right child gets column +1).
4. After the queue is empty, collect the node values for each column in order and put them into the result array.

The algorithm works for each language implementation.

## A solution in C++

```cpp
#include <vector>
#include <map>
#include <queue>

class TreeNode {
public:
    int val;
    TreeNode* left;
    TreeNode* right;

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

std::vector<std::vector<int>> verticalOrder(TreeNode* root) {
    if (!root) return {};

    std::map<int, std::vector<int>> columnTable;
    std::queue<std::pair<TreeNode*, int>> q;
    q.push({root, 0});

    while (!q.empty()) {
        TreeNode* curNode = q.front().first;
        int column = q.front().second;
        q.pop();

        if (curNode) {
            columnTable[column].push_back(curNode->val);
            q.push({curNode->left, column - 1});
            q.push({curNode->right, column + 1});
        }
    }

    std::vector<std::vector<int>> result;
    for (auto& [_, values] : columnTable) {
        result.push_back(std::move(values));
    }

    return result;
}
```
The algorithm for vertical order traversal works as follows:
1. Create a mapping of columns to their corresponding node values. Initialize a queue to store nodes and their columns, starting with the root at column 0.
2. While the queue is not empty, dequeue the node and column. Add the node's value to the corresponding column in the mapping.
3. Enqueue the node's left and right children with their respective column values (left child gets column -1, right child gets column +1).
4. After the queue is empty, collect the node values for each column in order and put them into the result array.

The algorithm works for each language implementation.

## A solution in Python

```python
from collections import defaultdict, deque
from typing import List, Optional

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

def verticalOrder(root: Optional[TreeNode]) -> List[List[int]]:
    if not root: return []

    column_table = defaultdict(list)
    q = deque([(root, 0)])

    while q:
        cur_node, column = q.popleft()

        if cur_node:
            column_table[column].append(cur_node.val)
            q.append((cur_node.left, column - 1))
            q.append((cur_node.right, column + 1))

    return [column_table[key] for key in sorted(column_table)]
```
The algorithm for vertical order traversal works as follows:
1. Create a mapping of columns to their corresponding node values. Initialize a queue to store nodes and their columns, starting with the root at column 0.
2. While the queue is not empty, dequeue the node and column. Add the node's value to the corresponding column in the mapping.
3. Enqueue the node's left and right children with their respective column values (left child gets column -1, right child gets column +1).
4. After the queue is empty, collect the node values for each column in order and put them into the result array.

The algorithm works for each language implementation.

## A solution in Javascript

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

var verticalOrder = function(root) {
    if (!root) return [];

    const columnTable = new Map();
    const q = [[root, 0]];

    while (q.length) {
        const [curNode, column] = q.shift();

        if (curNode) {
            if (!columnTable.has(column)) columnTable.set(column, []);
            columnTable.get(column).push(curNode.val);
            q.push([curNode.left, column - 1]);
            q.push([curNode.right, column + 1]);
        }
    }

    return Array.from(columnTable.entries()).sort((a, b) => a[0] - b[0]).map(entry => entry[1]);
};
```
The algorithm for vertical order traversal works as follows:
1. Create a mapping of columns to their corresponding node values. Initialize a queue to store nodes and their columns, starting with the root at column 0.
2. While the queue is not empty, dequeue the node and column. Add the node's value to the corresponding column in the mapping.
3. Enqueue the node's left and right children with their respective column values (left child gets column -1, right child gets column +1).
4. After the queue is empty, collect the node values for each column in order and put them into the result array.

The algorithm works for each language implementation.


# Count of Smaller Numbers After Self

- slug: count-of-smaller-numbers-after-self
- difficulty: Hard

Given an integer array `nums`, return _an integer array_ `counts` _where_ `counts[i]` _is the number of smaller elements to the right of_ `nums[i]`.

**Example 1:**

**Input:** nums = \[5,2,6,1\]
**Output:** \[2,1,1,0\]
**Explanation:**
To the right of 5 there are **2** smaller elements (2 and 1).
To the right of 2 there is only **1** smaller element (1).
To the right of 6 there is **1** smaller element (1).
To the right of 1 there is **0** smaller element.

**Example 2:**

**Input:** nums = \[-1\]
**Output:** \[0\]

**Example 3:**

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

**Constraints:**

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

## A solution in Java

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

public List<Integer> countSmaller(int[] nums) {
    int n = nums.length;
    int[] indices = new int[n];
    int[] counts = new int[n];

    for (int i = 0; i < n; i++) {
        indices[i] = i;
    }

    mergeSort(nums, indices, counts, 0, n - 1);
    List<Integer> result = new ArrayList<>();
    for (int count : counts) {
        result.add(count);
    }
    return result;
}

private void mergeSort(int[] nums, int[] indices, int[] counts, int left, int right) {
    if (left >= right) {
        return;
    }

    int mid = left + (right - left) / 2;
    mergeSort(nums, indices, counts, left, mid);
    mergeSort(nums, indices, counts, mid + 1, right);

    int[] temp = new int[right - left + 1];
    int i = left, j = mid + 1, k = 0;
    while (i <= mid && j <= right) {
        if (nums[indices[i]] <= nums[indices[j]]) {
            counts[indices[i]] += j - mid - 1;
            temp[k++] = indices[i++];
        } else {
            temp[k++] = indices[j++];
        }
    }

    while (i <= mid) {
        counts[indices[i]] += j - mid - 1;
        temp[k++] = indices[i++];
    }

    while (j <= right) {
        temp[k++] = indices[j++];
    }

    System.arraycopy(temp, 0, indices, left, right - left + 1);
}
```
The algorithm uses a modified merge sort to track the count of smaller elements to the right of each element in the array. The modification is made to merge function. During the merge process, whenever an element from the right side of the array is merged into the sorted subarray (meaning it's smaller than some elements), the count for those elements from the left side of the array is updated by adding the number of elements in the left subarray processed so far. The time complexity of this algorithm is O(n log n) due to the merge sort, and space complexity is O(n) for the auxiliary arrays used.

## A solution in C++

```cpp
#include <vector>
#include <iostream>

using namespace std;

vector<int> countSmaller(vector<int>& nums) {
    vector<int> result(nums.size(), 0);
    vector<int> indices(nums.size(), 0);

    for (int i = 0; i < nums.size(); ++i) {
        indices[i] = i;
    }

    mergeSort(nums, indices, result, 0, nums.size() - 1);
    return result;
}

void mergeSort(vector<int>& nums, vector<int>& indices, vector<int>& result, int left, int right) {
    if (left >= right) {
        return;
    }

    int mid = left + (right - left) / 2;
    mergeSort(nums, indices, result, left, mid);
    mergeSort(nums, indices, result, mid + 1, right);

    int I = left;
    int J = mid + 1;
    int K = 0;
    vector<int> temp(right - left + 1);
    while (I <= mid && J <= right) {
        if (nums[indices[I]] <= nums[indices[J]]) {
            result[indices[I]] += (J - mid - 1);
            temp[K++] = indices[I++];
        } else {
            temp[K++] = indices[J++];
        }
    }

    while (I <= mid) {
        result[indices[I]] += (J - mid - 1);
        temp[K++] = indices[I++];
    }

    while (J <= right) {
        temp[K++] = indices[J++];
    }

    for (int i = left, k = 0; i <= right; ++i, ++k) {
        indices[i] = temp[k];
    }
}
```
The algorithm uses a modified merge sort to track the count of smaller elements to the right of each element in the array. The modification is made to merge function. During the merge process, whenever an element from the right side of the array is merged into the sorted subarray (meaning it's smaller than some elements), the count for those elements from the left side of the array is updated by adding the number of elements in the left subarray processed so far. The time complexity of this algorithm is O(n log n) due to the merge sort, and space complexity is O(n) for the auxiliary arrays used.

## A solution in Python

```python
def countSmaller(nums):
    def merge_sort(indices):
        if len(indices) <= 1:
            return indices
        mid = len(indices) // 2
        left = merge_sort(indices[:mid])
        right = merge_sort(indices[mid:])
        return merge(left, right)

    def merge(left, right):
        merged, count = [], 0
        while left and right:
            if nums[left[0]] <= nums[right[0]]:
                counts[left[0]] += count
                merged.append(left.pop(0))
            else:
                count += len(left)
                merged.append(right.pop(0))
        for i in left:
            counts[i] += count
        return merged + left + right

    counts = [0] * len(nums)
    merge_sort(list(range(len(nums))))
    return counts
```
The algorithm uses a modified merge sort to track the count of smaller elements to the right of each element in the array. The modification is made to merge function. During the merge process, whenever an element from the right side of the array is merged into the sorted subarray (meaning it's smaller than some elements), the count for those elements from the left side of the array is updated by adding the number of elements in the left subarray processed so far. The time complexity of this algorithm is O(n log n) due to the merge sort, and space complexity is O(n) for the auxiliary arrays used.

## A solution in Javascript

```javascript
function countSmaller(nums) {
    function mergeSort(indices, start, end) {
        if (start >= end) {
            return;
        }

        let mid = start + ((end - start) >> 1);
        mergeSort(indices, start, mid);
        mergeSort(indices, mid + 1, end);

        let i = start, j = mid + 1, k = 0, cnt = 0;
        let temp = [];
        while (i <= mid || j <= end) {
            if (j > end || (i <= mid && nums[indices[i]] <= nums[indices[j]])) {
                cnt += j - mid - 1;
                counts[indices[i]] = cnt;
                temp[k++] = indices[i++];
            } else {
                temp[k++] = indices[j++];
            }
        }

        for (let i = 0; i < k; i++) {
            indices[start + i] = temp[i];
        }
    }

    let counts = Array(nums.length).fill(0);
    let indices = Array.from({length: nums.length}, (_, i) => i);
    mergeSort(indices, 0, nums.length - 1);
    return counts;
}
```
The algorithm uses a modified merge sort to track the count of smaller elements to the right of each element in the array. The modification is made to merge function. During the merge process, whenever an element from the right side of the array is merged into the sorted subarray (meaning it's smaller than some elements), the count for those elements from the left side of the array is updated by adding the number of elements in the left subarray processed so far. The time complexity of this algorithm is O(n log n) due to the merge sort, and space complexity is O(n) for the auxiliary arrays used.


# Remove Duplicate Letters

- slug: remove-duplicate-letters
- difficulty: Medium

Given a string `s`, remove duplicate letters so that every letter appears once and only once. You must make sure your result is **the smallest in lexicographical order** among all possible results.

**Example 1:**

**Input:** s =  "bcabc "
**Output:**  "abc "

**Example 2:**

**Input:** s =  "cbacdcbc "
**Output:**  "acdb "

**Constraints:**

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

**Note:** This question is the same as 1081: [https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/](https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/)

## A solution in Java

```java
import java.util.*;

public class Solution {
    public String removeDuplicateLetters(String s) {
        int[] count = new int[256];
        boolean[] visited = new boolean[256];
        Stack<Character> st = new Stack<>();

        for (char ch : s.toCharArray()) {
            count[ch]++;
        }

        for (char ch : s.toCharArray()) {
            count[ch]--;
            if (visited[ch]) continue;
            while (!st.isEmpty() && ch < st.peek() && count[st.peek()] > 0) {
                visited[st.pop()] = false;
            }
            st.push(ch);
            visited[ch] = true;
        }

        StringBuilder result = new StringBuilder();
        while (!st.empty()) {
            result.append(st.pop());
        }
        return result.reverse().toString();
    }
}
```
1. Initialize count and visited arrays. We will use count to track the occurrences of each character in the string and visited to mark if a character has been pushed into the result.
2. Iterate through the string, count the occurrences of each character.
3. Iterate through the string again, decrease the count of the current character.
4. If the current character is visited, continue.
5. While the stack is not empty, the current character is smaller than the top character on stack, and the count of the top character is greater than 0, set the visited of the top character to false and pop the character from the stack.
6. Push the current character onto the stack, and set visited to true.
7. Build the result string from the stack.
8. Return the result string.

## A solution in C++

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

string removeDuplicateLetters(string s) {
    vector<int> count(256, 0);
    vector<bool> visited(256, false);
    stack<char> st;

    for (char ch : s) {
        count[ch]++;
    }

    for (char ch : s) {
        count[ch]--;
        if (visited[ch]) continue;
        while (!st.empty() && ch < st.top() && count[st.top()] > 0) {
            visited[st.top()] = false;
            st.pop();
        }
        st.push(ch);
        visited[ch] = true;
    }

    string result = "";
    while (!st.empty()) {
        result = st.top() + result;
        st.pop();
    }
    return result;
}
```
1. Initialize count and visited arrays. We will use count to track the occurrences of each character in the string and visited to mark if a character has been pushed into the result.
2. Iterate through the string, count the occurrences of each character.
3. Iterate through the string again, decrease the count of the current character.
4. If the current character is visited, continue.
5. While the stack is not empty, the current character is smaller than the top character on stack, and the count of the top character is greater than 0, set the visited of the top character to false and pop the character from the stack.
6. Push the current character onto the stack, and set visited to true.
7. Build the result string from the stack.
8. Return the result string.

## A solution in Python

```python
def removeDuplicateLetters(s):
    count = [0] * 256
    visited = [False] * 256
    st = []

    for ch in s:
        count[ord(ch)] += 1

    for ch in s:
        count[ord(ch)] -= 1
        if visited[ord(ch)]:
            continue
        while st and ch < st[-1] and count[ord(st[-1])] > 0:
            visited[ord(st.pop())] = False
        st.append(ch)
        visited[ord(ch)] = True

    return "".join(st)
```
1. Initialize count and visited arrays. We will use count to track the occurrences of each character in the string and visited to mark if a character has been pushed into the result.
2. Iterate through the string, count the occurrences of each character.
3. Iterate through the string again, decrease the count of the current character.
4. If the current character is visited, continue.
5. While the stack is not empty, the current character is smaller than the top character on stack, and the count of the top character is greater than 0, set the visited of the top character to false and pop the character from the stack.
6. Push the current character onto the stack, and set visited to true.
7. Build the result string from the stack.
8. Return the result string.

## A solution in Javascript

```javascript
function removeDuplicateLetters(s) {
    let count = new Array(256).fill(0);
    let visited = new Array(256).fill(false);
    let st = [];

    for (let ch of s) {
        count[ch.charCodeAt(0)]++;
    }

    for (let ch of s) {
        count[ch.charCodeAt(0)]--;
        if (visited[ch.charCodeAt(0)]) continue;
        while (st.length > 0 && ch < st[st.length - 1] && count[st[st.length - 1].charCodeAt(0)] > 0) {
            visited[st.pop().charCodeAt(0)] = false;
        }
        st.push(ch);
        visited[ch.charCodeAt(0)] = true;
    }

    return st.join("");
}
```
1. Initialize count and visited arrays. We will use count to track the occurrences of each character in the string and visited to mark if a character has been pushed into the result.
2. Iterate through the string, count the occurrences of each character.
3. Iterate through the string again, decrease the count of the current character.
4. If the current character is visited, continue.
5. While the stack is not empty, the current character is smaller than the top character on stack, and the count of the top character is greater than 0, set the visited of the top character to false and pop the character from the stack.
6. Push the current character onto the stack, and set visited to true.
7. Build the result string from the stack.
8. Return the result string.


# Shortest Distance from All Buildings

- slug: shortest-distance-from-all-buildings
- difficulty: Hard

You are given an `m x n` grid `grid` of values `0`, `1`, or `2`, where:

*   each `0` marks **an empty land** that you can pass by freely,
*   each `1` marks **a building** that you cannot pass through, and
*   each `2` marks **an obstacle** that you cannot pass through.

You want to build a house on an empty land that reaches all buildings in the **shortest total travel** distance. You can only move up, down, left, and right.

Return _the **shortest travel distance** for such a house_. If it is not possible to build such a house according to the above rules, return `-1`.

The **total travel distance** is the sum of the distances between the houses of the friends and the meeting point.

The distance is calculated using [Manhattan Distance](http://en.wikipedia.org/wiki/Taxicab_geometry), where `distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|`.

**Example 1:**

**Input:** grid = \[\[1,0,2,0,1\],\[0,0,0,0,0\],\[0,0,1,0,0\]\]
**Output:** 7
**Explanation:** Given three buildings at (0,0), (0,4), (2,2), and an obstacle at (0,2).
The point (1,2) is an ideal empty land to build a house, as the total travel distance of 3+3+1=7 is minimal.
So return 7.

**Example 2:**

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

**Example 3:**

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

**Constraints:**

*   `m == grid.length`
*   `n == grid[i].length`
*   `1 <= m, n <= 50`
*   `grid[i][j]` is either `0`, `1`, or `2`.
*   There will be **at least one** building in the `grid`.

## A solution in Java

```java
import java.util.LinkedList;
import java.util.Queue;

public int shortestDistance(int[][] grid) {
    int m = grid.length;
    int n = grid[0].length;

    int[][] total_count = new int[m][n];
    int[][] dist_sum = new int[m][n];
    int house_count = 0;

    int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (grid[i][j] == 1) {
                house_count++;
                Queue<int[]> q = new LinkedList<>();
                q.offer(new int[]{i, j});
                boolean[][] visited = new boolean[m][n];
                int level = 1;
                while (!q.isEmpty()) {
                    int sz = q.size();
                    for (int q_i = 0; q_i < sz; q_i++) {
                        int[] cur = q.poll();
                        int x = cur[0];
                        int y = cur[1];
                        for (int[] dir : dirs) {
                            int x_new = x + dir[0];
                            int y_new = y + dir[1];
                            if (x_new >= 0 && x_new < m && y_new >= 0 && y_new < n && !visited[x_new][y_new] && grid[x_new][y_new] == 0) {
                                visited[x_new][y_new] = true;
                                q.offer(new int[]{x_new, y_new});
                                dist_sum[x_new][y_new] += level;
                                total_count[x_new][y_new]++;
                            }
                        }
                    }
                    level++;
                }
            }
        }
    }

    int min_dist = Integer.MAX_VALUE;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (total_count[i][j] == house_count) {
                min_dist = Math.min(min_dist, dist_sum[i][j]);
            }
        }
    }

    return min_dist == Integer.MAX_VALUE ? -1 : min_dist;
}
```
The problem can be solved using repeated Breadth-First Search (BFS) algorithm.

1. Initialize two `m x n` matrices `total_count` and `dist_sum` initialized to all 0s, where `total_count` stores the total number of houses reached from each cell and `dist_sum` stores the sum of the distances from each cell to every house reachable from that cell.

2. Count the total number of houses in `grid`.

3. Iterate through the matrix and for each house, perform a BFS to fill the `total_count` matrix with +1 for each empty cell reachable from the current house and add the corresponding level (distance) to the `dist_sum` matrix for reachable empty cells.

4. To find the minimum distance, iterate through the `total_count` matrix and find the cell with the same count as the total number of houses (i.e., cell reachable from all houses) and has the minimum corresponding value in the `dist_sum` matrix.

5. If such cell does not exist, return -1.

## A solution in C++

```cpp
#include <vector>
#include <queue>

using namespace std;

int shortestDistance(vector<vector<int>>& grid) {
    int m = grid.size();
    int n = grid[0].size();

    vector<vector<int>> total_count(m, vector<int>(n, 0));
    vector<vector<int>> dist_sum(m, vector<int>(n, 0));
    int house_count = 0;

    int dirs[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (grid[i][j] == 1) {
                house_count++;
                queue<pair<int, int>> q;
                q.push({i, j});
                vector<vector<bool>> visited(m, vector<bool>(n, false));
                int level = 1;
                while (!q.empty()) {
                    int sz = q.size();
                    for (int q_i = 0; q_i < sz; q_i++) {
                        int x = q.front().first;
                        int y = q.front().second;
                        q.pop();
                        for (auto &dir : dirs) {
                            int x_new = x + dir[0];
                            int y_new = y + dir[1];
                            if (x_new >= 0 && x_new < m && y_new >= 0 && y_new < n && !visited[x_new][y_new] && grid[x_new][y_new] == 0) {
                                visited[x_new][y_new] = true;
                                q.push({x_new, y_new});
                                dist_sum[x_new][y_new] += level;
                                total_count[x_new][y_new]++;
                            }
                        }
                    }
                    level++;
                }
            }
        }
    }

    int min_dist = INT_MAX;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (total_count[i][j] == house_count) {
                min_dist = min(min_dist, dist_sum[i][j]);
            }
        }
    }

    return min_dist == INT_MAX ? -1 : min_dist;
}
```
The problem can be solved using repeated Breadth-First Search (BFS) algorithm.

1. Initialize two `m x n` matrices `total_count` and `dist_sum` initialized to all 0s, where `total_count` stores the total number of houses reached from each cell and `dist_sum` stores the sum of the distances from each cell to every house reachable from that cell.

2. Count the total number of houses in `grid`.

3. Iterate through the matrix and for each house, perform a BFS to fill the `total_count` matrix with +1 for each empty cell reachable from the current house and add the corresponding level (distance) to the `dist_sum` matrix for reachable empty cells.

4. To find the minimum distance, iterate through the `total_count` matrix and find the cell with the same count as the total number of houses (i.e., cell reachable from all houses) and has the minimum corresponding value in the `dist_sum` matrix.

5. If such cell does not exist, return -1.

## A solution in Python

```python
from collections import deque

def shortestDistance(grid: list[list[int]]) -> int:
    m, n = len(grid), len(grid[0])

    total_count = [[0] * n for _ in range(m)]
    dist_sum = [[0] * n for _ in range(m)]
    house_count = 0

    dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)]

    for i in range(m):
        for j in range(n):
            if grid[i][j] == 1:
                house_count += 1
                q = deque([(i, j)])
                visited = [[False] * n for _ in range(m)]
                level = 1
                while q:
                    for _ in range(len(q)):
                        x, y = q.popleft()
                        for dx, dy in dirs:
                            x_new, y_new = x + dx, y + dy
                            if 0 <= x_new < m and 0 <= y_new < n and not visited[x_new][y_new] and grid[x_new][y_new] == 0:
                                visited[x_new][y_new] = True
                                q.append((x_new, y_new))
                                dist_sum[x_new][y_new] += level
                                total_count[x_new][y_new] += 1
                    level += 1

    min_dist = float("inf")
    for i in range(m):
        for j in range(n):
            if total_count[i][j] == house_count:
                min_dist = min(min_dist, dist_sum[i][j])

    return -1 if min_dist == float("inf") else min_dist
```
The problem can be solved using repeated Breadth-First Search (BFS) algorithm.

1. Initialize two `m x n` matrices `total_count` and `dist_sum` initialized to all 0s, where `total_count` stores the total number of houses reached from each cell and `dist_sum` stores the sum of the distances from each cell to every house reachable from that cell.

2. Count the total number of houses in `grid`.

3. Iterate through the matrix and for each house, perform a BFS to fill the `total_count` matrix with +1 for each empty cell reachable from the current house and add the corresponding level (distance) to the `dist_sum` matrix for reachable empty cells.

4. To find the minimum distance, iterate through the `total_count` matrix and find the cell with the same count as the total number of houses (i.e., cell reachable from all houses) and has the minimum corresponding value in the `dist_sum` matrix.

5. If such cell does not exist, return -1.

## A solution in Javascript

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

    let total_count = Array.from({length: m}, () => Array(n).fill(0));
    let dist_sum = Array.from({length: m}, () => Array(n).fill(0));
    let house_count = 0;

    let dirs = [[1, 0], [-1, 0], [0, 1], [0, -1]];

    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            if (grid[i][j] === 1) {
                house_count++;
                let q = [{x: i, y: j}];
                let visited = Array.from({length: m}, () => Array(n).fill(false));
                let level = 1;
                while (q.length) {
                    let sz = q.length;
                    for (let q_i = 0; q_i < sz; q_i++) {
                        let { x, y } = q.shift();
                        dirs.forEach(([dx, dy]) => {
                            let x_new = x + dx;
                            let y_new = y + dy;
                            if (x_new >= 0 && x_new < m && y_new >= 0 && y_new < n && !visited[x_new][y_new] && grid[x_new][y_new] === 0) {
                                visited[x_new][y_new] = true;
                                q.push({ x: x_new, y: y_new });
                                dist_sum[x_new][y_new] += level;
                                total_count[x_new][y_new]++;
                            }
                        });
                    }
                    level++;
                }
            }
        }
    }

    let min_dist = Infinity;
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            if (total_count[i][j] === house_count) {
                min_dist = Math.min(min_dist, dist_sum[i][j]);
            }
        }
    }

    return min_dist === Infinity ? -1 : min_dist;
}
```
The problem can be solved using repeated Breadth-First Search (BFS) algorithm.

1. Initialize two `m x n` matrices `total_count` and `dist_sum` initialized to all 0s, where `total_count` stores the total number of houses reached from each cell and `dist_sum` stores the sum of the distances from each cell to every house reachable from that cell.

2. Count the total number of houses in `grid`.

3. Iterate through the matrix and for each house, perform a BFS to fill the `total_count` matrix with +1 for each empty cell reachable from the current house and add the corresponding level (distance) to the `dist_sum` matrix for reachable empty cells.

4. To find the minimum distance, iterate through the `total_count` matrix and find the cell with the same count as the total number of houses (i.e., cell reachable from all houses) and has the minimum corresponding value in the `dist_sum` matrix.

5. If such cell does not exist, return -1.


# Maximum Product of Word Lengths

- slug: maximum-product-of-word-lengths
- difficulty: Medium

Given a string array `words`, return _the maximum value of_ `length(word[i]) * length(word[j])` _where the two words do not share common letters_. If no such two words exist, return `0`.

**Example 1:**

**Input:** words = \[ "abcw ", "baz ", "foo ", "bar ", "xtfn ", "abcdef "\]
**Output:** 16
**Explanation:** The two words can be  "abcw ",  "xtfn ".

**Example 2:**

**Input:** words = \[ "a ", "ab ", "abc ", "d ", "cd ", "bcd ", "abcd "\]
**Output:** 4
**Explanation:** The two words can be  "ab ",  "cd ".

**Example 3:**

**Input:** words = \[ "a ", "aa ", "aaa ", "aaaa "\]
**Output:** 0
**Explanation:** No such pair of words.

**Constraints:**

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

## A solution in Java

```java
import java.util.*;

class Solution {
    public int maxProduct(String[] words) {
        int n = words.length;
        int[] mask = new int[n];
        for (int i = 0; i < n; i++) {
            for (char c : words[i].toCharArray()) {
                mask[i] |= (1 << (c - 'a'));
            }
        }

        int maxProduct = 0;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if ((mask[i] & mask[j]) == 0) {
                    maxProduct = Math.max(maxProduct, words[i].length() * words[j].length());
                }
            }
        }

        return maxProduct;
    }
}
```
The algorithm first calculates a binary representation of each word, where each character is represented by a bit '1' in the corresponding position. For example, for the words "abc" and "xyz", the representation would be: "abc" = 0000..0111 and "xyz" = 111..0000.

Then, for each pair of words, the algorithm checks if there are common characters by applying the 'and' bitwise operation. If there are no common characters, the 'and' operation will result in 0, meaning that the condition is met. In this case, the product of the lengths of the words is calculated, and the maximum product is updated if needed.

The algorithm runs in O(n^2) where 'n' is the number of words, since it checks each pair of words.

## A solution in C++

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

int maxProduct(std::vector<std::string>& words) {
    int n = words.size();
    std::vector<int> mask(n, 0);
    for (int i = 0; i < n; ++i) {
        for (char c : words[i]) {
            mask[i] |= (1 << (c - 'a'));
        }
    }

    int max_product = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            if ((mask[i] & mask[j]) == 0) {
                max_product = std::max(max_product, int(words[i].length() * words[j].length()));
            }
        }
    }

    return max_product;
}
```
The algorithm first calculates a binary representation of each word, where each character is represented by a bit '1' in the corresponding position. For example, for the words "abc" and "xyz", the representation would be: "abc" = 0000..0111 and "xyz" = 111..0000.

Then, for each pair of words, the algorithm checks if there are common characters by applying the 'and' bitwise operation. If there are no common characters, the 'and' operation will result in 0, meaning that the condition is met. In this case, the product of the lengths of the words is calculated, and the maximum product is updated if needed.

The algorithm runs in O(n^2) where 'n' is the number of words, since it checks each pair of words.

## A solution in Python

```python
def maxProduct(words):
    n = len(words)
    mask = [0] * n
    for i, word in enumerate(words):
        for c in word:
            mask[i] |= (1 << (ord(c) - ord('a')))

    max_product = 0
    for i in range(n):
        for j in range(i + 1, n):
            if (mask[i] & mask[j]) == 0:
                max_product = max(max_product, len(words[i]) * len(words[j]))

    return max_product
```
The algorithm first calculates a binary representation of each word, where each character is represented by a bit '1' in the corresponding position. For example, for the words "abc" and "xyz", the representation would be: "abc" = 0000..0111 and "xyz" = 111..0000.

Then, for each pair of words, the algorithm checks if there are common characters by applying the 'and' bitwise operation. If there are no common characters, the 'and' operation will result in 0, meaning that the condition is met. In this case, the product of the lengths of the words is calculated, and the maximum product is updated if needed.

The algorithm runs in O(n^2) where 'n' is the number of words, since it checks each pair of words.

## A solution in Javascript

```javascript
function maxProduct(words) {
    const n = words.length;
    const mask = new Array(n).fill(0);
    for (let i = 0; i < n; i++) {
        for (const c of words[i]) {
            mask[i] |= (1 << (c.charCodeAt(0) - 'a'.charCodeAt(0)));
        }
    }

    let maxProduct = 0;
    for (let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++) {
            if ((mask[i] & mask[j]) === 0) {
                maxProduct = Math.max(maxProduct, words[i].length * words[j].length);
            }
        }
    }

    return maxProduct;
}
```
The algorithm first calculates a binary representation of each word, where each character is represented by a bit '1' in the corresponding position. For example, for the words "abc" and "xyz", the representation would be: "abc" = 0000..0111 and "xyz" = 111..0000.

Then, for each pair of words, the algorithm checks if there are common characters by applying the 'and' bitwise operation. If there are no common characters, the 'and' operation will result in 0, meaning that the condition is met. In this case, the product of the lengths of the words is calculated, and the maximum product is updated if needed.

The algorithm runs in O(n^2) where 'n' is the number of words, since it checks each pair of words.


# Bulb Switcher

- slug: bulb-switcher
- difficulty: Medium

There are `n` bulbs that are initially off. You first turn on all the bulbs, then you turn off every second bulb.

On the third round, you toggle every third bulb (turning on if it's off or turning off if it's on). For the `ith` round, you toggle every `i` bulb. For the `nth` round, you only toggle the last bulb.

Return _the number of bulbs that are on after `n` rounds_.

**Example 1:**

**Input:** n = 3
**Output:** 1
**Explanation:** At first, the three bulbs are \[off, off, off\].
After the first round, the three bulbs are \[on, on, on\].
After the second round, the three bulbs are \[on, off, on\].
After the third round, the three bulbs are \[on, off, off\].
So you should return 1 because there is only one bulb is on.

**Example 2:**

**Input:** n = 0
**Output:** 0

**Example 3:**

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

**Constraints:**

*   `0 <= n <= 109`

## A solution in Java

```java
public int bulbSwitch(int n) {
    return (int)Math.sqrt(n);
}
```
Initially, all the bulbs are off. When a bulb is toggled odd number of times, it remains on; otherwise, it remains off. So, we need to figure out how many bulbs have an odd number of toggles after N rounds.

A bulb has a toggle every time one of its divisors is encountered during the rounds. For example, bulb 6 will have toggles during round 1, round 2, round 3, and round 6. Its divisors are 1, 2, 3, and 6. In general, numbers have an even number of divisors. However, square numbers have an odd number of divisors, because their square root divisor gets counted only once. For example, for number 9, there are divisors 1, 3, and 9, and the square root divisor 3 is counted only once.

Since only square numbers have an odd number of divisors (and therefore odd number of toggles), we only need to count the number of square numbers less than or equal to n. In order to do this, we can simply take the square root of n and round it down to the nearest integer, as the function does in each language.

## A solution in C++

```cpp
int bulbSwitch(int n) {
    return sqrt(n);
}
```
Initially, all the bulbs are off. When a bulb is toggled odd number of times, it remains on; otherwise, it remains off. So, we need to figure out how many bulbs have an odd number of toggles after N rounds.

A bulb has a toggle every time one of its divisors is encountered during the rounds. For example, bulb 6 will have toggles during round 1, round 2, round 3, and round 6. Its divisors are 1, 2, 3, and 6. In general, numbers have an even number of divisors. However, square numbers have an odd number of divisors, because their square root divisor gets counted only once. For example, for number 9, there are divisors 1, 3, and 9, and the square root divisor 3 is counted only once.

Since only square numbers have an odd number of divisors (and therefore odd number of toggles), we only need to count the number of square numbers less than or equal to n. In order to do this, we can simply take the square root of n and round it down to the nearest integer, as the function does in each language.

## A solution in Python

```python
def bulbSwitch(n):
    return int(n**0.5)
```
Initially, all the bulbs are off. When a bulb is toggled odd number of times, it remains on; otherwise, it remains off. So, we need to figure out how many bulbs have an odd number of toggles after N rounds.

A bulb has a toggle every time one of its divisors is encountered during the rounds. For example, bulb 6 will have toggles during round 1, round 2, round 3, and round 6. Its divisors are 1, 2, 3, and 6. In general, numbers have an even number of divisors. However, square numbers have an odd number of divisors, because their square root divisor gets counted only once. For example, for number 9, there are divisors 1, 3, and 9, and the square root divisor 3 is counted only once.

Since only square numbers have an odd number of divisors (and therefore odd number of toggles), we only need to count the number of square numbers less than or equal to n. In order to do this, we can simply take the square root of n and round it down to the nearest integer, as the function does in each language.

## A solution in Javascript

```javascript
function bulbSwitch(n) {
    return Math.floor(Math.sqrt(n));
}
```
Initially, all the bulbs are off. When a bulb is toggled odd number of times, it remains on; otherwise, it remains off. So, we need to figure out how many bulbs have an odd number of toggles after N rounds.

A bulb has a toggle every time one of its divisors is encountered during the rounds. For example, bulb 6 will have toggles during round 1, round 2, round 3, and round 6. Its divisors are 1, 2, 3, and 6. In general, numbers have an even number of divisors. However, square numbers have an odd number of divisors, because their square root divisor gets counted only once. For example, for number 9, there are divisors 1, 3, and 9, and the square root divisor 3 is counted only once.

Since only square numbers have an odd number of divisors (and therefore odd number of toggles), we only need to count the number of square numbers less than or equal to n. In order to do this, we can simply take the square root of n and round it down to the nearest integer, as the function does in each language.


# Generalized Abbreviation

- slug: generalized-abbreviation
- difficulty: Medium

A word's **generalized abbreviation** can be constructed by taking any number of **non-overlapping** and **non-adjacent** substrings and replacing them with their respective lengths.

*   For example, `"abcde "` can be abbreviated into:
    *   `"a3e "` ( `"bcd "` turned into `"3 "`)
    *   `"1bcd1 "` ( `"a "` and `"e "` both turned into `"1 "`)
    *   `"5 "` ( `"abcde "` turned into `"5 "`)
    *   `"abcde "` (no substrings replaced)
*   However, these abbreviations are **invalid**:
    *   `"23 "` ( `"ab "` turned into `"2 "` and `"cde "` turned into `"3 "`) is invalid as the substrings chosen are adjacent.
    *   `"22de "` ( `"ab "` turned into `"2 "` and `"bc "` turned into `"2 "`) is invalid as the substring chosen overlap.

Given a string `word`, return _a list of all the possible **generalized abbreviations** of_ `word`. Return the answer in **any order**.

**Example 1:**

**Input:** word = "word"
**Output:** \["4","3d","2r1","2rd","1o2","1o1d","1or1","1ord","w3","w2d","w1r1","w1rd","wo2","wo1d","wor1","word"\]

**Example 2:**

**Input:** word = "a"
**Output:** \["1","a"\]

**Constraints:**

*   `1 <= word.length <= 15`
*   `word` consists of only lowercase English letters.

## A solution in Java

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

public List<String> generateAbbreviations(String word) {
    List<String> res = new ArrayList<>();
    res.add(word.isEmpty() ? "" : Integer.toString(word.length()));
    for (int i = 0; i < word.length(); ++i) {
        String pre = word.substring(0, i);
        for (String abbr : generateAbbreviations(word.substring(i + 1))) {
            int num = abbr.chars().findFirst_NEG_INT().getAsInt();
            if (abbr.isEmpty() || num > 0) {
                res.add(pre + '1' + abbr);
            }
            if (i == 0 || abbr.isEmpty() || abbr.charAt(0) > '9') {
                res.add(word.substring(0, i + 1) + abbr);
            }
        }
    }
    return res;
}
```
The algorithm to generate generalized abbreviations works as follows:
1. If the input word is empty, return an empty abbreviation.
2. Initialize an empty result list.
3. Iterate over the length of the word, performing the following steps:
   a. Recursively generate abbreviations for subsequences.
   b. Check if it's the first iteration or if the item is not a number.
      If true, append the word slice and item to the result list.
   c. Check if the item is a number.
      If true, append the word slice and item with '1' between them to the result list.
4. Return the result list containing all possible generalized abbreviations.

This method ensures non-overlapping and non-adjacent substrings because, at each recursive call, we add only one digit or a character. Hence, there will always be either a digit or a character between two digit substrings. Since we do not combine multiple adjacent characters into a single multi-digit substring, we comply with the constraints mentioned in the problem statement.

## A solution in C++

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

std::vector<std::string> generateAbbreviations(std::string word) {
    std::vector<std::string> res;
    res.push_back(word.empty() ? "" : std::to_string(word.size()));
    for (size_t i = 0; i < word.size(); ++i)
        for (const std::string &abbr : generateAbbreviations(word.substr(i + 1))) {
            size_t num;
            if (abbr.empty() || (num = abbr.find_first_not_of('123456789')) > 0)
                res.push_back(word.substr(0, i) + '1' + abbr);
            if (i == 0 || abbr.empty() || abbr[0] > '9')
                res.push_back(word.substr(0, i + 1) + abbr);
        }
    return res;
}
```
The algorithm to generate generalized abbreviations works as follows:
1. If the input word is empty, return an empty abbreviation.
2. Initialize an empty result list.
3. Iterate over the length of the word, performing the following steps:
   a. Recursively generate abbreviations for subsequences.
   b. Check if it's the first iteration or if the item is not a number.
      If true, append the word slice and item to the result list.
   c. Check if the item is a number.
      If true, append the word slice and item with '1' between them to the result list.
4. Return the result list containing all possible generalized abbreviations.

This method ensures non-overlapping and non-adjacent substrings because, at each recursive call, we add only one digit or a character. Hence, there will always be either a digit or a character between two digit substrings. Since we do not combine multiple adjacent characters into a single multi-digit substring, we comply with the constraints mentioned in the problem statement.

## A solution in Python

```python
def generateAbbreviations(word):
    if not word:
        return [""]
    res = []
    for i in range(len(word) + 1):
        for item in generateAbbreviations(word[i+1:]):
            if i == 0 or not item or not item[0].isdigit():
                res.append(word[:i+1] + item)
            if item and item[0].isdigit():
                res.append(word[:i] + '1' + item)
    return res
```
The algorithm to generate generalized abbreviations works as follows:
1. If the input word is empty, return an empty abbreviation.
2. Initialize an empty result list.
3. Iterate over the length of the word, performing the following steps:
   a. Recursively generate abbreviations for subsequences.
   b. Check if it's the first iteration or if the item is not a number.
      If true, append the word slice and item to the result list.
   c. Check if the item is a number.
      If true, append the word slice and item with '1' between them to the result list.
4. Return the result list containing all possible generalized abbreviations.

This method ensures non-overlapping and non-adjacent substrings because, at each recursive call, we add only one digit or a character. Hence, there will always be either a digit or a character between two digit substrings. Since we do not combine multiple adjacent characters into a single multi-digit substring, we comply with the constraints mentioned in the problem statement.

## A solution in Javascript

```javascript
function generateAbbreviations(word) {
    if (word === '') {
        return ['']
    }
    const res = []
    for (let i = 0; i < word.length + 1; i++) {
        for (const item of generateAbbreviations(word.slice(i + 1))) {
            if (i === 0 || !item || isNaN(item[0])) {
                res.push(word.slice(0, i + 1) + item)
            }
            if (item && !isNaN(item[0])) {
                res.push(word.slice(0, i) + '1' + item)
            }
        }
    }
    return res
}
```
The algorithm to generate generalized abbreviations works as follows:
1. If the input word is empty, return an empty abbreviation.
2. Initialize an empty result list.
3. Iterate over the length of the word, performing the following steps:
   a. Recursively generate abbreviations for subsequences.
   b. Check if it's the first iteration or if the item is not a number.
      If true, append the word slice and item to the result list.
   c. Check if the item is a number.
      If true, append the word slice and item with '1' between them to the result list.
4. Return the result list containing all possible generalized abbreviations.

This method ensures non-overlapping and non-adjacent substrings because, at each recursive call, we add only one digit or a character. Hence, there will always be either a digit or a character between two digit substrings. Since we do not combine multiple adjacent characters into a single multi-digit substring, we comply with the constraints mentioned in the problem statement.


# Create Maximum Number

- slug: create-maximum-number
- difficulty: Hard

You are given two integer arrays `nums1` and `nums2` of lengths `m` and `n` respectively. `nums1` and `nums2` represent the digits of two numbers. You are also given an integer `k`.

Create the maximum number of length `k <= m + n` from digits of the two numbers. The relative order of the digits from the same array must be preserved.

Return an array of the `k` digits representing the answer.

**Example 1:**

**Input:** nums1 = \[3,4,6,5\], nums2 = \[9,1,2,5,8,3\], k = 5
**Output:** \[9,8,6,5,3\]

**Example 2:**

**Input:** nums1 = \[6,7\], nums2 = \[6,0,4\], k = 5
**Output:** \[6,7,6,0,4\]

**Example 3:**

**Input:** nums1 = \[3,9\], nums2 = \[8,9\], k = 3
**Output:** \[9,8,9\]

**Constraints:**

*   `m == nums1.length`
*   `n == nums2.length`
*   `1 <= m, n <= 500`
*   `0 <= nums1[i], nums2[i] <= 9`
*   `1 <= k <= m + n`

## A solution in Java

```java
public int[] maxNumber(int[] nums1, int[] nums2, int k) {
    int[] ans = new int[k];
    int m = nums1.length, n = nums2.length;

    for (int i = Math.max(0, k - n); i <= k && i <= m; i++) {
        int[] candidate = merge(maxArray(nums1, i), maxArray(nums2, k - i), k);
        if (greater(candidate, 0, ans, 0)) ans = candidate;
    }
    return ans;
}

private int[] maxArray(int[] nums, int k) {
    int n = nums.length;
    int[] ans = new int[k];
    for (int i = 0, j = 0; i < n; i++) {
        while (n - i > k - j && j > 0 && ans[j - 1] < nums[i]) j--;
        if (j < k) ans[j++] = nums[i];
    }
    return ans;
}

private int[] merge(int[] nums1, int[] nums2, int k) {
    int[] ans = new int[k];
    for (int i = 0, j = 0, r = 0; r < k; r++)
        ans[r] = greater(nums1, i, nums2, j) ? nums1[i++] : nums2[j++];
    return ans;
}

private boolean greater(int[] nums1, int i, int[] nums2, int j) {
    while (i < nums1.length && j < nums2.length && nums1[i] == nums2[j]) {
        i++;
        j++;
    }
    return j == nums2.length || (i < nums1.length && nums1[i] > nums2[j]);
}
```
The algorithm works by first finding the maximum subsequence of the required length from each input array while retaining their relative order. It then iterates through all possible combinations of subsequences of the two arrays (nums1 and nums2) with lengths summing to k, and merges them while preserving their element's relative order. During the merge, the algorithm always selects the maximum elements from the two arrays, giving preference to the first array if both elements are equal. Finally, the maximum array of length k is returned.

## A solution in C++

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

std::vector<int> maxNumber(std::vector<int>& nums1, std::vector<int>& nums2, int k) {
    int m = nums1.size(), n = nums2.size();
    std::vector<int> ans(k, 0);
    for (int i = std::max(0, k - n); i <= k && i <= m; ++i) {
        std::vector<int> candidate = merge(maxArray(nums1, i), maxArray(nums2, k - i), k);
        if (greater(candidate, 0, ans, 0)) ans = candidate;
    }
    return ans;
}

std::vector<int> maxArray(std::vector<int>& nums, int k) {
    int n = nums.size();
    std::vector<int> ans(k, 0);
    for (int i = 0, j = 0; i < n; ++i) {
        while (n - i > k - j && j > 0 && ans[j - 1] < nums[i]) j--;
        if (j < k) ans[j++] = nums[i];
    }
    return ans;
}

std::vector<int> merge(std::vector<int>& nums1, std::vector<int>& nums2, int k) {
    std::vector<int> ans(k, 0);
    for (int i = 0, j = 0, r = 0; r < k; ++r)
        ans[r] = greater(nums1, i, nums2, j) ? nums1[i++] : nums2[j++];
    return ans;
}

bool greater(std::vector<int>& nums1, int i, std::vector<int>& nums2, int j) {
    while (i < nums1.size() && j < nums2.size() && nums1[i] == nums2[j]) {
        i++;
        j++;
    }
    return j == nums2.size() || (i < nums1.size() && nums1[i] > nums2[j]);
}
```
The algorithm works by first finding the maximum subsequence of the required length from each input array while retaining their relative order. It then iterates through all possible combinations of subsequences of the two arrays (nums1 and nums2) with lengths summing to k, and merges them while preserving their element's relative order. During the merge, the algorithm always selects the maximum elements from the two arrays, giving preference to the first array if both elements are equal. Finally, the maximum array of length k is returned.

## A solution in Python

```javascript
function maxNumber(nums1, nums2, k) {
    function maxArray(nums, k) {
        let ans = [];
        for (let i = 0; i < nums.length; i++) {
            while (nums.length - i > k - ans.length && ans.length && ans[ans.length - 1] < nums[i])
                ans.pop();
            if (ans.length < k) ans.push(nums[i]);
        }
        return ans;
    }

    function merge(nums1, nums2) {
        let ans = [], i = 0, j = 0;
        while (i < nums1.length || j < nums2.length)
            ans.push((nums1.slice(i).join('') >= nums2.slice(j).join('') ? nums1[i++] : nums2[j++]));
        return ans;
    }

    let result = [];
    for (let i = Math.max(0, k - nums2.length); i <= k && i <= nums1.length; i++) {
        const candidate = merge(maxArray(nums1, i), maxArray(nums2, k - i));
        if (candidate.join('') > result.join('')) result = candidate;
    }
    return result;
}
```
The algorithm works by first finding the maximum subsequence of the required length from each input array while retaining their relative order. It then iterates through all possible combinations of subsequences of the two arrays (nums1 and nums2) with lengths summing to k, and merges them while preserving their element's relative order. During the merge, the algorithm always selects the maximum elements from the two arrays, giving preference to the first array if both elements are equal. Finally, the maximum array of length k is returned.

## A solution in Javascript

```python
def maxNumber(nums1, nums2, k):
    def maxArray(nums, k):
        ans = []
        for i, num in enumerate(nums):
            while len(ans) + len(nums) - i > k and ans and ans[-1] < num:
                ans.pop()
            if len(ans) < k:
                ans.append(num)
        return ans

    def merge(nums1, nums2):
        return [max(nums1, nums2).pop(0) for _ in nums1 + nums2]

    return max(merge(maxArray(nums1, i), maxArray(nums2, k - i))
               for i in range(k + 1)
               if i <= len(nums1) and k - i <= len(nums2))
```
The algorithm works by first finding the maximum subsequence of the required length from each input array while retaining their relative order. It then iterates through all possible combinations of subsequences of the two arrays (nums1 and nums2) with lengths summing to k, and merges them while preserving their element's relative order. During the merge, the algorithm always selects the maximum elements from the two arrays, giving preference to the first array if both elements are equal. Finally, the maximum array of length k is returned.


# Coin Change

- slug: coin-change
- difficulty: Medium

You are given an integer array `coins` representing coins of different denominations and an integer `amount` representing a total amount of money.

Return _the fewest number of coins that you need to make up that amount_. If that amount of money cannot be made up by any combination of the coins, return `-1`.

You may assume that you have an infinite number of each kind of coin.

**Example 1:**

**Input:** coins = \[1,2,5\], amount = 11
**Output:** 3
**Explanation:** 11 = 5 + 5 + 1

**Example 2:**

**Input:** coins = \[2\], amount = 3
**Output:** -1

**Example 3:**

**Input:** coins = \[1\], amount = 0
**Output:** 0

**Constraints:**

*   `1 <= coins.length <= 12`
*   `1 <= coins[i] <= 231 - 1`
*   `0 <= amount <= 104`

## A solution in Java

```java
public int coinChange(int[] coins, int amount) {
    int[] dp = new int[amount + 1];
    Arrays.fill(dp, amount + 1);
    dp[0] = 0;

    for (int coin : coins) {
        for (int i = coin; i <= amount; i++) {
            dp[i] = Math.min(dp[i], dp[i - coin] + 1);
        }
    }

    return dp[amount] <= amount ? dp[amount] : -1;
}
```
The algorithm here is based on dynamic programming. We create a `dp` array with indices from 0 to the total `amount` we need to target. We initialize the `dp` array with a value greater than the amount (amount + 1). This is because this value can never be achieved using the coins, and the initialization ensures that we always get a valid minimum number of coins.

We start by initializing `dp[0]` to 0 as there will be 0 coins needed to make a sum of 0.

Then, we iterate through the given coins array and for each coin, we start another iteration from the value of the coin to the total amount. For each index `i` in this inner loop, we update `dp[i]` as the minimum of its current value `dp[i]` and `dp[i - coins[j]] + 1`. This ensures that we get the minimum number of coins required to create the total amount.

After this iteration, if the value at `dp[amount]` is less than or equal to the target amount, we return the value as the minimum number of coins required. Otherwise, if it's greater than the amount, it means we couldn't find a combination of coins to make up the total amount, so we return -1.

## A solution in C++

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

int coinChange(std::vector<int>& coins, int amount) {
    std::vector<int> dp(amount + 1, amount + 1);
    dp[0] = 0;

    for (int i = 0; i < coins.size(); i++) {
        for (int j = coins[i]; j <= amount; j++) {
            dp[j] = std::min(dp[j], dp[j - coins[i]] + 1);
        }
    }

    return dp[amount] <= amount ? dp[amount] : -1;
}
```
The algorithm here is based on dynamic programming. We create a `dp` array with indices from 0 to the total `amount` we need to target. We initialize the `dp` array with a value greater than the amount (amount + 1). This is because this value can never be achieved using the coins, and the initialization ensures that we always get a valid minimum number of coins.

We start by initializing `dp[0]` to 0 as there will be 0 coins needed to make a sum of 0.

Then, we iterate through the given coins array and for each coin, we start another iteration from the value of the coin to the total amount. For each index `i` in this inner loop, we update `dp[i]` as the minimum of its current value `dp[i]` and `dp[i - coins[j]] + 1`. This ensures that we get the minimum number of coins required to create the total amount.

After this iteration, if the value at `dp[amount]` is less than or equal to the target amount, we return the value as the minimum number of coins required. Otherwise, if it's greater than the amount, it means we couldn't find a combination of coins to make up the total amount, so we return -1.

## A solution in Python

```python
def coinChange(coins, amount):
    dp = [amount + 1] * (amount + 1)
    dp[0] = 0

    for coin in coins:
        for i in range(coin, amount + 1):
            dp[i] = min(dp[i], dp[i - coin] + 1)

    return dp[amount] if dp[amount] <= amount else -1
```
The algorithm here is based on dynamic programming. We create a `dp` array with indices from 0 to the total `amount` we need to target. We initialize the `dp` array with a value greater than the amount (amount + 1). This is because this value can never be achieved using the coins, and the initialization ensures that we always get a valid minimum number of coins.

We start by initializing `dp[0]` to 0 as there will be 0 coins needed to make a sum of 0.

Then, we iterate through the given coins array and for each coin, we start another iteration from the value of the coin to the total amount. For each index `i` in this inner loop, we update `dp[i]` as the minimum of its current value `dp[i]` and `dp[i - coins[j]] + 1`. This ensures that we get the minimum number of coins required to create the total amount.

After this iteration, if the value at `dp[amount]` is less than or equal to the target amount, we return the value as the minimum number of coins required. Otherwise, if it's greater than the amount, it means we couldn't find a combination of coins to make up the total amount, so we return -1.

## A solution in Javascript

```javascript
function coinChange(coins, amount) {
    const dp = new Array(amount + 1).fill(amount + 1);
    dp[0] = 0;

    for (const coin of coins) {
        for (let i = coin; i <= amount; i++) {
            dp[i] = Math.min(dp[i], dp[i - coin] + 1);
        }
    }

    return dp[amount] <= amount ? dp[amount] : -1;
}
```
The algorithm here is based on dynamic programming. We create a `dp` array with indices from 0 to the total `amount` we need to target. We initialize the `dp` array with a value greater than the amount (amount + 1). This is because this value can never be achieved using the coins, and the initialization ensures that we always get a valid minimum number of coins.

We start by initializing `dp[0]` to 0 as there will be 0 coins needed to make a sum of 0.

Then, we iterate through the given coins array and for each coin, we start another iteration from the value of the coin to the total amount. For each index `i` in this inner loop, we update `dp[i]` as the minimum of its current value `dp[i]` and `dp[i - coins[j]] + 1`. This ensures that we get the minimum number of coins required to create the total amount.

After this iteration, if the value at `dp[amount]` is less than or equal to the target amount, we return the value as the minimum number of coins required. Otherwise, if it's greater than the amount, it means we couldn't find a combination of coins to make up the total amount, so we return -1.


# Number of Connected Components in an Undirected Graph

- slug: number-of-connected-components-in-an-undirected-graph
- difficulty: Medium

You have a graph of `n` nodes. You are given an integer `n` and an array `edges` where `edges[i] = [ai, bi]` indicates that there is an edge between `ai` and `bi` in the graph.

Return _the number of connected components in the graph_.

**Example 1:**

**Input:** n = 5, edges = \[\[0,1\],\[1,2\],\[3,4\]\]
**Output:** 2

**Example 2:**

**Input:** n = 5, edges = \[\[0,1\],\[1,2\],\[2,3\],\[3,4\]\]
**Output:** 1

**Constraints:**

*   `1 <= n <= 2000`
*   `1 <= edges.length <= 5000`
*   `edges[i].length == 2`
*   `0 <= ai <= bi < n`
*   `ai != bi`
*   There are no repeated edges.

## A solution in Java

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

public int countComponents(int n, int[][] edges) {
    List<List<Integer>> adjList = new ArrayList<>();
    for (int i = 0; i < n; i++) {
        adjList.add(new ArrayList<>());
    }
    for (int[] edge : edges) {
        adjList.get(edge[0]).add(edge[1]);
        adjList.get(edge[1]).add(edge[0]);
    }

    boolean[] visited = new boolean[n];
    int connectedComponents = 0;

    for (int i = 0; i < n; i++) {
        if (!visited[i]) {
            dfs(i, visited, adjList);
            connectedComponents++;
        }
    }
    return connectedComponents;
}

void dfs(int node, boolean[] visited, List<List<Integer>> adjList) {
    visited[node] = true;
    for (int neighbor : adjList.get(node)) {
        if (!visited[neighbor]) {
            dfs(neighbor, visited, adjList);
        }
    }
}
```
The algorithm used to solve this problem is the standard Depth First Search (DFS) on an undirected graph. The number of connected components is incremented each time a new unvisited node is found. The algorithm performs the following steps:

1. Create an adjacency list representation of the graph.
2. Initialize a visited array to mark visited nodes.
3. Initialize a count variable for connected components.
4. Iterate over all the nodes in the graph:
   a. If a node is not visited, perform DFS on the node and increment the count of connected components.
   b. In DFS, mark the node as visited and recursively perform DFS on its adjacent nodes if they have not been visited.
5. Return the count of connected components.

## A solution in C++

```cpp
#include <vector>

int countComponents(int n, std::vector<std::vector<int>>& edges) {
    std::vector<std::vector<int>> adjList(n);
    for (const auto& edge : edges) {
        adjList[edge[0]].push_back(edge[1]);
        adjList[edge[1]].push_back(edge[0]);
    }

    std::vector<bool> visited(n, false);
    int connectedComponents = 0;

    for (int i = 0; i < n; ++i) {
        if (!visited[i]) {
            std::function<void(int)> dfs = [&](int node) {
                visited[node] = true;
                for (int neighbor : adjList[node]) {
                    if (!visited[neighbor]) {
                        dfs(neighbor);
                    }
                }
            };
            dfs(i);
            connectedComponents++;
        }
    }
    return connectedComponents;
}
```
The algorithm used to solve this problem is the standard Depth First Search (DFS) on an undirected graph. The number of connected components is incremented each time a new unvisited node is found. The algorithm performs the following steps:

1. Create an adjacency list representation of the graph.
2. Initialize a visited array to mark visited nodes.
3. Initialize a count variable for connected components.
4. Iterate over all the nodes in the graph:
   a. If a node is not visited, perform DFS on the node and increment the count of connected components.
   b. In DFS, mark the node as visited and recursively perform DFS on its adjacent nodes if they have not been visited.
5. Return the count of connected components.

## A solution in Python

```python
def countComponents(n, edges):
    adj_list = [[] for _ in range(n)]
    for edge in edges:
        adj_list[edge[0]].append(edge[1])
        adj_list[edge[1]].append(edge[0])

    visited = [False] * n
    connected_components = 0

    def dfs(node):
        visited[node] = True
        for neighbor in adj_list[node]:
            if not visited[neighbor]:
                dfs(neighbor)

    for i in range(n):
        if not visited[i]:
            dfs(i)
            connected_components += 1

    return connected_components
```
The algorithm used to solve this problem is the standard Depth First Search (DFS) on an undirected graph. The number of connected components is incremented each time a new unvisited node is found. The algorithm performs the following steps:

1. Create an adjacency list representation of the graph.
2. Initialize a visited array to mark visited nodes.
3. Initialize a count variable for connected components.
4. Iterate over all the nodes in the graph:
   a. If a node is not visited, perform DFS on the node and increment the count of connected components.
   b. In DFS, mark the node as visited and recursively perform DFS on its adjacent nodes if they have not been visited.
5. Return the count of connected components.

## A solution in Javascript

```javascript
function countComponents(n, edges) {
    const adjList = new Array(n).fill(0).map(() => []);
    for (const edge of edges) {
        adjList[edge[0]].push(edge[1]);
        adjList[edge[1]].push(edge[0]);
    }

    const visited = new Array(n).fill(false);
    let connectedComponents = 0;

    function dfs(node) {
        visited[node] = true;
        for (const neighbor of adjList[node]) {
            if (!visited[neighbor]) {
                dfs(neighbor);
            }
        }
    }

    for (let i = 0; i < n; i++) {
        if (!visited[i]) {
            dfs(i);
            connectedComponents++;
        }
    }
    return connectedComponents;
}
```
The algorithm used to solve this problem is the standard Depth First Search (DFS) on an undirected graph. The number of connected components is incremented each time a new unvisited node is found. The algorithm performs the following steps:

1. Create an adjacency list representation of the graph.
2. Initialize a visited array to mark visited nodes.
3. Initialize a count variable for connected components.
4. Iterate over all the nodes in the graph:
   a. If a node is not visited, perform DFS on the node and increment the count of connected components.
   b. In DFS, mark the node as visited and recursively perform DFS on its adjacent nodes if they have not been visited.
5. Return the count of connected components.


# Wiggle Sort II

- slug: wiggle-sort-ii
- difficulty: Medium

Given an integer array `nums`, reorder it such that `nums[0] < nums[1] > nums[2] < nums[3]...`.

You may assume the input array always has a valid answer.

**Example 1:**

**Input:** nums = \[1,5,1,1,6,4\]
**Output:** \[1,6,1,5,1,4\]
**Explanation:** \[1,4,1,5,1,6\] is also accepted.

**Example 2:**

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

**Constraints:**

*   `1 <= nums.length <= 5 * 104`
*   `0 <= nums[i] <= 5000`
*   It is guaranteed that there will be an answer for the given input `nums`.

**Follow Up:** Can you do it in `O(n)` time and/or **in-place** with `O(1)` extra space?

## A solution in Java

```java
import java.util.Arrays;
public void wiggleSort(int[] nums) {
    Arrays.sort(nums);
    for (int i = 1; i < nums.length - 1; i += 2) {
        int temp = nums[i];
        nums[i] = nums[i + 1];
        nums[i + 1] = temp;
    }
}
```
1. First, sort the array in ascending order. This step ensures that the smaller element is always before the larger element in the sorted array.
2. Iterate through the sorted array, starting from the second element (index 1) and incrementing by 2 so that the iteration only impacts every other element.
3. Swap the current element with the next element in the array during the iteration. This will make the current element greater than its neighbors, fulfilling the requirements of the wiggle sort.

## A solution in C++

```cpp
#include <algorithm>
void wiggleSort(vector<int>& nums) {
    sort(nums.begin(), nums.end());
    for (int i = 1; i < nums.size() - 1; i += 2) {
        swap(nums[i], nums[i + 1]);
    }
}
```
1. First, sort the array in ascending order. This step ensures that the smaller element is always before the larger element in the sorted array.
2. Iterate through the sorted array, starting from the second element (index 1) and incrementing by 2 so that the iteration only impacts every other element.
3. Swap the current element with the next element in the array during the iteration. This will make the current element greater than its neighbors, fulfilling the requirements of the wiggle sort.

## A solution in Python

```python
def wiggleSort(nums):
    nums.sort()
    for i in range(1, len(nums) - 1, 2):
        nums[i], nums[i + 1] = nums[i + 1], nums[i]
```
1. First, sort the array in ascending order. This step ensures that the smaller element is always before the larger element in the sorted array.
2. Iterate through the sorted array, starting from the second element (index 1) and incrementing by 2 so that the iteration only impacts every other element.
3. Swap the current element with the next element in the array during the iteration. This will make the current element greater than its neighbors, fulfilling the requirements of the wiggle sort.

## A solution in Javascript

```javascript
function wiggleSort(nums) {
    nums.sort((a, b) => a - b);
    for (let i = 1; i < nums.length - 1; i += 2) {
        [nums[i], nums[i + 1]] = [nums[i + 1], nums[i]];
    }
}
```
1. First, sort the array in ascending order. This step ensures that the smaller element is always before the larger element in the sorted array.
2. Iterate through the sorted array, starting from the second element (index 1) and incrementing by 2 so that the iteration only impacts every other element.
3. Swap the current element with the next element in the array during the iteration. This will make the current element greater than its neighbors, fulfilling the requirements of the wiggle sort.


# Maximum Size Subarray Sum Equals k

- slug: maximum-size-subarray-sum-equals-k
- difficulty: Medium

Given an integer array `nums` and an integer `k`, return _the maximum length of a_ _subarray_ _that sums to_ `k`. If there is not one, return `0` instead.

**Example 1:**

**Input:** nums = \[1,-1,5,-2,3\], k = 3
**Output:** 4
**Explanation:** The subarray \[1, -1, 5, -2\] sums to 3 and is the longest.

**Example 2:**

**Input:** nums = \[-2,-1,2,1\], k = 1
**Output:** 2
**Explanation:** The subarray \[-1, 2\] sums to 1 and is the longest.

**Constraints:**

*   `1 <= nums.length <= 2 * 105`
*   `-104 <= nums[i] <= 104`
*   `-109 <= k <= 109`

## A solution in Java

```java
public int maxSubArrayLen(int[] nums, int k) {
    Map<Integer, Integer> sumIndex = new HashMap<>();
    int maxLength = 0, sum = 0;
    for(int i = 0; i < nums.length; i++) {
        sum += nums[i];
        if (sum == k) maxLength = i + 1;
        if (sumIndex.containsKey(sum - k)) maxLength = Math.max(maxLength, i - sumIndex.get(sum - k));
        if (!sumIndex.containsKey(sum)) sumIndex.put(sum, i);
    }
    return maxLength;
}
```
The algorithm uses a HashMap (or dictionary for Python) to store a cumulative sum and its index. The HashMap (called `sumIndex` here) keeps track of the first time a certain sum (up to that index) is encountered in the array. Then, we iterate through the array and maintain a running sum. If the running sum is equal to the given sum `k`, the current maximum length of the subarray is updated as `i + 1`. If the running sum minus `k` exists in `sumIndex`, it means that we've found a subarray that sums to `k`, so we can update the maximum length by comparing with the current subarray length `i - sumIndex[sum - k]`. If the running sum is not present in the `sumIndex`, we can store its index.

The algorithm works in O(n) time complexity, where n is the length of the array because we traverse the entire array once and perform constant time operations for each element.

## A solution in C++

```cpp
int maxSubArrayLen(vector<int>& nums, int k) {
    unordered_map<int, int> sumIndex;
    int maxLength = 0, sum = 0;
    for(int i = 0; i < nums.size(); i++) {
        sum += nums[i];
        if(sum == k) maxLength = i + 1;
        if(sumIndex.count(sum - k)) maxLength = max(maxLength, i - sumIndex[sum - k]);
        if(!sumIndex.count(sum)) sumIndex[sum] = i;
    }
    return maxLength;
}
```
The algorithm uses a HashMap (or dictionary for Python) to store a cumulative sum and its index. The HashMap (called `sumIndex` here) keeps track of the first time a certain sum (up to that index) is encountered in the array. Then, we iterate through the array and maintain a running sum. If the running sum is equal to the given sum `k`, the current maximum length of the subarray is updated as `i + 1`. If the running sum minus `k` exists in `sumIndex`, it means that we've found a subarray that sums to `k`, so we can update the maximum length by comparing with the current subarray length `i - sumIndex[sum - k]`. If the running sum is not present in the `sumIndex`, we can store its index.

The algorithm works in O(n) time complexity, where n is the length of the array because we traverse the entire array once and perform constant time operations for each element.

## A solution in Python

```python
def maxSubArrayLen(nums: List[int], k: int) -> int:
    sum_index = {}
    maxLength = sum = 0
    for i, num in enumerate(nums):
        sum += num
        if sum == k:
            maxLength = i + 1
        if sum - k in sum_index:
            maxLength = max(maxLength, i - sum_index[sum - k])
        if sum not in sum_index:
            sum_index[sum] = i
    return maxLength
```
The algorithm uses a HashMap (or dictionary for Python) to store a cumulative sum and its index. The HashMap (called `sumIndex` here) keeps track of the first time a certain sum (up to that index) is encountered in the array. Then, we iterate through the array and maintain a running sum. If the running sum is equal to the given sum `k`, the current maximum length of the subarray is updated as `i + 1`. If the running sum minus `k` exists in `sumIndex`, it means that we've found a subarray that sums to `k`, so we can update the maximum length by comparing with the current subarray length `i - sumIndex[sum - k]`. If the running sum is not present in the `sumIndex`, we can store its index.

The algorithm works in O(n) time complexity, where n is the length of the array because we traverse the entire array once and perform constant time operations for each element.

## A solution in Javascript

```javascript
function maxSubArrayLen(nums, k) {
    let sumIndex = new Map();
    let maxLength = 0, sum = 0;
    for (let i = 0; i < nums.length; i++) {
        sum += nums[i];
        if (sum === k) maxLength = i + 1;
        if (sumIndex.has(sum - k)) maxLength = Math.max(maxLength, i - sumIndex.get(sum - k));
        if (!sumIndex.has(sum)) sumIndex.set(sum, i);
    }
    return maxLength;
}
```
The algorithm uses a HashMap (or dictionary for Python) to store a cumulative sum and its index. The HashMap (called `sumIndex` here) keeps track of the first time a certain sum (up to that index) is encountered in the array. Then, we iterate through the array and maintain a running sum. If the running sum is equal to the given sum `k`, the current maximum length of the subarray is updated as `i + 1`. If the running sum minus `k` exists in `sumIndex`, it means that we've found a subarray that sums to `k`, so we can update the maximum length by comparing with the current subarray length `i - sumIndex[sum - k]`. If the running sum is not present in the `sumIndex`, we can store its index.

The algorithm works in O(n) time complexity, where n is the length of the array because we traverse the entire array once and perform constant time operations for each element.


# Power of Three

- slug: power-of-three
- difficulty: Easy

Given an integer `n`, return _`true` if it is a power of three. Otherwise, return `false`_.

An integer `n` is a power of three, if there exists an integer `x` such that `n == 3x`.

**Example 1:**

**Input:** n = 27
**Output:** true
**Explanation:** 27 = 33

**Example 2:**

**Input:** n = 0
**Output:** false
**Explanation:** There is no x where 3x = 0.

**Example 3:**

**Input:** n = -1
**Output:** false
**Explanation:** There is no x where 3x = (-1).

**Constraints:**

*   `-231 <= n <= 231 - 1`

**Follow up:** Could you solve it without loops/recursion?

## A solution in Java

```java
public boolean isPowerOfThree(int n) {
    if (n < 1) {
        return false;
    }

    while (n % 3 == 0) {
        n /= 3;
    }

    return n == 1;
}
```
The solution checks if the given number, n, is a power of three as follows:

1. If n is less than 1, return false because powers of 3 are positive integers.
2. Use a while loop, and keep dividing n by 3 while n is divisible by 3 without a remainder.
3. After the loop, check if n is equal to 1. If n is 1, it means the original n was a power of 3; otherwise, it was not a power of 3. Return the result accordingly.

## A solution in C++

```cpp
bool isPowerOfThree(int n) {
    if (n < 1) {
        return false;
    }

    while (n % 3 == 0) {
        n /= 3;
    }

    return n == 1;
}
```
The solution checks if the given number, n, is a power of three as follows:

1. If n is less than 1, return false because powers of 3 are positive integers.
2. Use a while loop, and keep dividing n by 3 while n is divisible by 3 without a remainder.
3. After the loop, check if n is equal to 1. If n is 1, it means the original n was a power of 3; otherwise, it was not a power of 3. Return the result accordingly.

## A solution in Python

```python
def is_power_of_three(n: int) -> bool:
    if n < 1:
        return False

    while n % 3 == 0:
        n //= 3

    return n == 1
```
The solution checks if the given number, n, is a power of three as follows:

1. If n is less than 1, return false because powers of 3 are positive integers.
2. Use a while loop, and keep dividing n by 3 while n is divisible by 3 without a remainder.
3. After the loop, check if n is equal to 1. If n is 1, it means the original n was a power of 3; otherwise, it was not a power of 3. Return the result accordingly.

## A solution in Javascript

```javascript
function isPowerOfThree(n) {
    if (n < 1) {
        return false;
    }

    while (n % 3 === 0) {
        n /= 3;
    }

    return n === 1;
}
```
The solution checks if the given number, n, is a power of three as follows:

1. If n is less than 1, return false because powers of 3 are positive integers.
2. Use a while loop, and keep dividing n by 3 while n is divisible by 3 without a remainder.
3. After the loop, check if n is equal to 1. If n is 1, it means the original n was a power of 3; otherwise, it was not a power of 3. Return the result accordingly.


# Count of Range Sum

- slug: count-of-range-sum
- difficulty: Hard

Given an integer array `nums` and two integers `lower` and `upper`, return _the number of range sums that lie in_ `[lower, upper]` _inclusive_.

Range sum `S(i, j)` is defined as the sum of the elements in `nums` between indices `i` and `j` inclusive, where `i <= j`.

**Example 1:**

**Input:** nums = \[-2,5,-1\], lower = -2, upper = 2
**Output:** 3
**Explanation:** The three ranges are: \[0,0\], \[2,2\], and \[0,2\] and their respective sums are: -2, -1, 2.

**Example 2:**

**Input:** nums = \[0\], lower = 0, upper = 0
**Output:** 1

**Constraints:**

*   `1 <= nums.length <= 105`
*   `-231 <= nums[i] <= 231 - 1`
*   `-105 <= lower <= upper <= 105`
*   The answer is **guaranteed** to fit in a **32-bit** integer.

## A solution in Java

```java
public int countRangeSum(int[] nums, int lower, int upper) {
    long[] sums = new long[nums.length + 1];
    for (int i = 0; i < nums.length; ++i)
        sums[i + 1] = sums[i] + nums[i];

    return countWhileMergeSort(sums, lower, upper, 0, nums.length);
}

private int countWhileMergeSort(long[] sums, int lower, int upper, int start, int end) {
    if (start >= end)
        return 0;

    int mid = start + (end - start) / 2;
    int count = countWhileMergeSort(sums, lower, upper, start, mid) + countWhileMergeSort(sums, lower, upper, mid + 1, end);

    int j = mid + 1, k = mid + 1;
    for (int i = start; i <= mid; ++i) {
        while (j <= end && sums[j] - sums[i] < lower) ++j;
        while (k <= end && sums[k] - sums[i] <= upper) ++k;
        count += k - j;
    }

    Arrays.sort(sums, start, end + 1);
    return count;
}
```
The algorithm is based on the divide-and-conquer strategy. First, we calculate the cumulative sums of the input array. Then, we apply a modified merge-sort function to count the number of range sums that lie in the [lower, upper] interval.

During the merge-sort, for each subarray from index i to mid, we find the first `j` and the first `k` that meet the following conditions:
- `sums[j] - sums[i] >= lower`, and
- `sums[k] - sums[i] > upper`.

The number of range sums in this subarray that lie in the [lower, upper] interval is `k - j`. We add this count to the result.

Finally, we merge the sorted partitions of the subarray.

This process is repeated recursively for all subarrays until only one element remains. At the end, the function should return the total count of range sums that lie in the [lower, upper] interval.

## A solution in C++

```cpp
int countRangeSum(vector<int>& nums, int lower, int upper) {
    int n = nums.size();
    vector<long> sums(n + 1, 0);
    for (int i = 0; i < n; ++i)
        sums[i + 1] = sums[i] + nums[i];

    function<int(int, int)> mergeSort = [&](int start, int end) {
        if (start == end)
            return 0;
        int mid = start + (end - start) / 2;
        int count = mergeSort(start, mid) + mergeSort(mid + 1, end);

        int j = mid + 1, k = mid + 1;
        for (int i = start; i <= mid; ++i) {
            while (j <= end && sums[j] - sums[i] < lower) ++j;
            while (k <= end && sums[k] - sums[i] <= upper) ++k;
            count += k - j;
        }

        inplace_merge(sums.begin() + start, sums.begin() + mid + 1, sums.begin() + end + 1);
        return count;
    };

    return mergeSort(0, n);
}
```
The algorithm is based on the divide-and-conquer strategy. First, we calculate the cumulative sums of the input array. Then, we apply a modified merge-sort function to count the number of range sums that lie in the [lower, upper] interval.

During the merge-sort, for each subarray from index i to mid, we find the first `j` and the first `k` that meet the following conditions:
- `sums[j] - sums[i] >= lower`, and
- `sums[k] - sums[i] > upper`.

The number of range sums in this subarray that lie in the [lower, upper] interval is `k - j`. We add this count to the result.

Finally, we merge the sorted partitions of the subarray.

This process is repeated recursively for all subarrays until only one element remains. At the end, the function should return the total count of range sums that lie in the [lower, upper] interval.

## A solution in Python

```python
def countRangeSum(nums, lower, upper):
    sums = [0] * (len(nums) + 1)
    for i in range(len(nums)):
        sums[i + 1] = sums[i] + nums[i]

    def mergeSort(start, end):
        if start == end:
            return 0
        mid = start + (end - start) // 2
        count = mergeSort(start, mid) + mergeSort(mid + 1, end)

        j, k = mid + 1, mid + 1
        for i in range(start, mid + 1):
            while j <= end and sums[j] - sums[i] < lower: j += 1
            while k <= end and sums[k] - sums[i] <= upper: k += 1
            count += k - j

        sums[start:end + 1] = sorted(sums[start:end + 1])
        return count

    return mergeSort(0, len(nums))
```
The algorithm is based on the divide-and-conquer strategy. First, we calculate the cumulative sums of the input array. Then, we apply a modified merge-sort function to count the number of range sums that lie in the [lower, upper] interval.

During the merge-sort, for each subarray from index i to mid, we find the first `j` and the first `k` that meet the following conditions:
- `sums[j] - sums[i] >= lower`, and
- `sums[k] - sums[i] > upper`.

The number of range sums in this subarray that lie in the [lower, upper] interval is `k - j`. We add this count to the result.

Finally, we merge the sorted partitions of the subarray.

This process is repeated recursively for all subarrays until only one element remains. At the end, the function should return the total count of range sums that lie in the [lower, upper] interval.

## A solution in Javascript

```javascript
function countRangeSum(nums, lower, upper) {
    let sums = new Array(nums.length + 1).fill(0);
    for (let i = 0; i < nums.length; ++i)
        sums[i + 1] = sums[i] + nums[i];

    function mergeSort(start, end) {
        if (start === end)
            return 0;
        let mid = start + Math.floor((end - start) / 2);
        let count = mergeSort(start, mid) + mergeSort(mid + 1, end);

        let j = mid + 1, k = mid + 1;
        for (let i = start; i <= mid; ++i) {
            while (j <= end && sums[j] - sums[i] < lower) ++j;
            while (k <= end && sums[k] - sums[i] <= upper) ++k;
            count += k - j;
        }

        let sortedPart = sums.slice(start, end + 1).sort((a, b) => a - b);
        for (let i = start; i <= end; ++i) {
            sums[i] = sortedPart[i - start];
        }

        return count;
    };

    return mergeSort(0, nums.length);
}
```
The algorithm is based on the divide-and-conquer strategy. First, we calculate the cumulative sums of the input array. Then, we apply a modified merge-sort function to count the number of range sums that lie in the [lower, upper] interval.

During the merge-sort, for each subarray from index i to mid, we find the first `j` and the first `k` that meet the following conditions:
- `sums[j] - sums[i] >= lower`, and
- `sums[k] - sums[i] > upper`.

The number of range sums in this subarray that lie in the [lower, upper] interval is `k - j`. We add this count to the result.

Finally, we merge the sorted partitions of the subarray.

This process is repeated recursively for all subarrays until only one element remains. At the end, the function should return the total count of range sums that lie in the [lower, upper] interval.


# Odd Even Linked List

- slug: odd-even-linked-list
- difficulty: Medium

Given the `head` of a singly linked list, group all the nodes with odd indices together followed by the nodes with even indices, and return _the reordered list_.

The **first** node is considered **odd**, and the **second** node is **even**, and so on.

Note that the relative order inside both the even and odd groups should remain as it was in the input.

You must solve the problem in `O(1)` extra space complexity and `O(n)` time complexity.

**Example 1:**

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

**Example 2:**

**Input:** head = \[2,1,3,5,6,4,7\]
**Output:** \[2,3,6,7,1,5,4\]

**Constraints:**

*   The number of nodes in the linked list is in the range `[0, 104]`.
*   `-106 <= Node.val <= 106`

## A solution in Java

```java
public class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) { this.val = val; }
    ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}

public ListNode oddEvenList(ListNode head) {
    if (head == null) return null;
    ListNode odd = head, even = head.next, evenHead = even;
    while (even != null && even.next != null) {
        odd.next = even.next;
        odd = odd.next;
        even.next = odd.next;
        even = even.next;
    }
    odd.next = evenHead;
    return head;
}
```
The algorithm works by maintaining two pointers: `odd` and `even`. Initially, `odd` is set to the head of the list (first node) and `even` is set to the second node. We also store the head of the even list in a separate variable `even_head`.

We start traversing the list using a while loop, checking if `even` and `even.next` are not null. Inside the loop, we update the `next` pointers of both the odd and even nodes as we go, effectively reordering the nodes.

Finally, after the loop, we connect the end of the odd list with the head of the even list and return the head of the merged list.

## A solution in C++

```cpp
struct ListNode {
     int val;
     ListNode *next;
     ListNode() : val(0), next(nullptr) {}
     ListNode(int x) : val(x), next(nullptr) {}
     ListNode(int x, ListNode *next) : val(x), next(next) {}
};

ListNode* oddEvenList(ListNode* head) {
    if (!head) return nullptr;
    ListNode *odd = head, *even = head->next, *even_head = even;
    while (even && even->next) {
        odd->next = even->next;
        odd = odd->next;
        even->next = odd->next;
        even = even->next;
    }
    odd->next = even_head;
    return head;
}
```
The algorithm works by maintaining two pointers: `odd` and `even`. Initially, `odd` is set to the head of the list (first node) and `even` is set to the second node. We also store the head of the even list in a separate variable `even_head`.

We start traversing the list using a while loop, checking if `even` and `even.next` are not null. Inside the loop, we update the `next` pointers of both the odd and even nodes as we go, effectively reordering the nodes.

Finally, after the loop, we connect the end of the odd list with the head of the even list and return the head of the merged list.

## A solution in Python

```python
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def odd_even_list(head: ListNode) -> ListNode:
    if not head:
        return None
    odd, even, even_head = head, head.next, head.next
    while even and even.next:
        odd.next = even.next
        odd = odd.next
        even.next = odd.next
        even = even.next
    odd.next = even_head
    return head
```
The algorithm works by maintaining two pointers: `odd` and `even`. Initially, `odd` is set to the head of the list (first node) and `even` is set to the second node. We also store the head of the even list in a separate variable `even_head`.

We start traversing the list using a while loop, checking if `even` and `even.next` are not null. Inside the loop, we update the `next` pointers of both the odd and even nodes as we go, effectively reordering the nodes.

Finally, after the loop, we connect the end of the odd list with the head of the even list and return the head of the merged list.

## A solution in Javascript

```javascript
class ListNode {
    constructor(val, next = null) {
        this.val = val;
        this.next = next;
    }
}

function oddEvenList(head) {
    if (!head) return null;
    let odd = head,
        even = head.next,
        evenHead = even;
    while (even && even.next) {
        odd.next = even.next;
        odd = odd.next;
        even.next = odd.next;
        even = even.next;
    }
    odd.next = evenHead;
    return head;
}
```
The algorithm works by maintaining two pointers: `odd` and `even`. Initially, `odd` is set to the head of the list (first node) and `even` is set to the second node. We also store the head of the even list in a separate variable `even_head`.

We start traversing the list using a while loop, checking if `even` and `even.next` are not null. Inside the loop, we update the `next` pointers of both the odd and even nodes as we go, effectively reordering the nodes.

Finally, after the loop, we connect the end of the odd list with the head of the even list and return the head of the merged list.