# Design a Todo List

- slug: design-a-todo-list
- difficulty: Medium

Design a Todo List Where users can add **tasks**, mark them as **complete**, or get a list of pending tasks. Users can also add **tags** to tasks and can filter the tasks by certain tags.

Implement the `TodoList` class:

*   `TodoList()` Initializes the object.
*   `int addTask(int userId, String taskDescription, int dueDate, List tags)` Adds a task for the user with the ID `userId` with a due date equal to `dueDate` and a list of tags attached to the task. The return value is the ID of the task. This ID starts at `1` and is **sequentially** increasing. That is, the first task's id should be `1`, the second task's id should be `2`, and so on.
*   `List getAllTasks(int userId)` Returns a list of all the tasks not marked as complete for the user with ID `userId`, ordered by the due date. You should return an empty list if the user has no uncompleted tasks.
*   `List getTasksForTag(int userId, String tag)` Returns a list of all the tasks that are not marked as complete for the user with the ID `userId` and have `tag` as one of their tags, ordered by their due date. Return an empty list if no such task exists.
*   `void completeTask(int userId, int taskId)` Marks the task with the ID `taskId` as completed only if the task exists and the user with the ID `userId` has this task, and it is uncompleted.

**Example 1:**

**Input**
\[ "TodoList ",  "addTask ",  "addTask ",  "getAllTasks ",  "getAllTasks ",  "addTask ",  "getTasksForTag ",  "completeTask ",  "completeTask ",  "getTasksForTag ",  "getAllTasks "\]
\[\[\], \[1,  "Task1 ", 50, \[\]\], \[1,  "Task2 ", 100, \[ "P1 "\]\], \[1\], \[5\], \[1,  "Task3 ", 30, \[ "P1 "\]\], \[1,  "P1 "\], \[5, 1\], \[1, 2\], \[1,  "P1 "\], \[1\]\]
**Output**
\[null, 1, 2, \[ "Task1 ",  "Task2 "\], \[\], 3, \[ "Task3 ",  "Task2 "\], null, null, \[ "Task3 "\], \[ "Task3 ",  "Task1 "\]\]

**Explanation**
TodoList todoList = new TodoList();
todoList.addTask(1,  "Task1 ", 50, \[\]); // return 1. This adds a new task for the user with id 1.
todoList.addTask(1,  "Task2 ", 100, \[ "P1 "\]); // return 2. This adds another task for the user with id 1.
todoList.getAllTasks(1); // return \[ "Task1 ",  "Task2 "\]. User 1 has two uncompleted tasks so far.
todoList.getAllTasks(5); // return \[\]. User 5 does not have any tasks so far.
todoList.addTask(1,  "Task3 ", 30, \[ "P1 "\]); // return 3. This adds another task for the user with id 1.
todoList.getTasksForTag(1,  "P1 "); // return \[ "Task3 ",  "Task2 "\]. This returns the uncompleted tasks that have the tag  "P1 " for the user with id 1.
todoList.completeTask(5, 1); // This does nothing, since task 1 does not belong to user 5.
todoList.completeTask(1, 2); // This marks task 2 as completed.
todoList.getTasksForTag(1,  "P1 "); // return \[ "Task3 "\]. This returns the uncompleted tasks that have the tag  "P1 " for the user with id 1.
                                  // Notice that we did not include  "Task2 " because it is completed now.
todoList.getAllTasks(1); // return \[ "Task3 ",  "Task1 "\]. User 1 now has 2 uncompleted tasks.

**Constraints:**

*   `1 <= userId, taskId, dueDate <= 100`
*   `0 <= tags.length <= 100`
*   `1 <= taskDescription.length <= 50`
*   `1 <= tags[i].length, tag.length <= 20`
*   All `dueDate` values are unique.
*   All the strings consist of lowercase and uppercase English letters and digits.
*   At most `100` calls will be made for each method.

## A solution in Java

```java
import java.util.*;

class TodoList {
    private static class Task {
        int id;
        String description;
        int dueDate;
        List<String> tags;
        boolean completed;

        public Task(int id, String description, int dueDate, List<String> tags) {
            this.id = id;
            this.description = description;
            this.dueDate = dueDate;
            this.tags = tags;
            this.completed = false;
        }
    }

    private int taskId;
    private Map<Integer, List<Task>> tasks;

    public TodoList() {
        taskId = 1;
        tasks = new HashMap<>();
    }

    public int addTask(int userId, String taskDescription, int dueDate, List<String> tags) {
        tasks.computeIfAbsent(userId, k -> new ArrayList<>());
        tasks.get(userId).add(new Task(taskId, taskDescription, dueDate, tags));
        return taskId++;
    }

    public List<String> getAllTasks(int userId){
        List<String> res = new ArrayList<>();
        List<Task> userTasks = tasks.getOrDefault(userId, new ArrayList<>());

        Collections.sort(userTasks, Comparator.comparingInt(a -> a.dueDate));

        for (Task task : userTasks) {
            if (!task.completed) {
                res.add(task.description);
            }
        }

        return res;
    }

    public List<String> getTasksForTag(int userId, String tag){
        List<String> res = new ArrayList<>();
        List<Task> userTasks = tasks.getOrDefault(userId, new ArrayList<>());

        Collections.sort(userTasks, Comparator.comparingInt(a -> a.dueDate));

        for (Task task : userTasks) {
            if (!task.completed && task.tags.contains(tag)) {
                res.add(task.description);
            }
        }

        return res;
    }

    public void completeTask(int userId, int taskId){
        List<Task> userTasks = tasks.getOrDefault(userId, new ArrayList<>());
        for (Task task : userTasks) {
            if (task.id == taskId) {
                task.completed = true;
                break;
            }
        }
    }
}
```
We define a `Task` class that keeps the task information such as `id`, `description`, `dueDate`, `tags`, and its completion status (`completed` field).

The `TodoList` class contains a map, `tasks`, that stores the tasks of each user as a list. Then, we implement the methods `addTask`, `getAllTasks`, `getTasksForTag`, and `completeTask`, using the map and Task objects.

1. `addTask()` creates a new Task object with the provided `taskDescription`, `dueDate`, and `tags`, and then adds the task to the corresponding user's task list. It increments the `taskId` by 1.
2. `getAllTasks()` retrieves the user's task list, sorts the tasks by the due date, and creates a list of uncompleted task descriptions to return.
3. `getTasksForTag()` retrieves the user's task list, sorts the tasks by the due date, and creates a list of uncompleted task descriptions that have the specified tag.
4. `completeTask()` finds the task with the given task ID for the specified user and sets the `completed` field of the task to `true`.

ForEach function is implemented using the standard library functions (`std::sort()` for C++, `Collections.sort()` for Java, `sorted()` for Python, and `Array.prototype.sort()` for JavaScript) and loops/iterators as required by each language.

## A solution in C++

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

class TodoList {
public:
    struct Task {
        int id;
        std::string description;
        int dueDate;
        std::vector<std::string> tags;
        bool completed;

        Task(int _id, const std::string& _desc, int _dueDate, const std::vector<std::string>& _tags)
            : id(_id), description(_desc), dueDate(_dueDate), tags(_tags), completed(false) {}
    };

    TodoList() : taskId(1) {}

    int addTask(int userId, std::string taskDescription, int dueDate, std::vector<std::string> tags) {
        tasks[userId].emplace_back(taskId, taskDescription, dueDate, tags);
        return taskId++;
    }

    std::vector<std::string> getAllTasks(int userId) {

        std::vector<std::string> res;
        std::vector<Task>& userTasks = tasks[userId];

        std::sort(userTasks.begin(), userTasks.end(), [](const Task& a, const Task& b) {
            return a.dueDate < b.dueDate;
        });

        for (const auto& task : userTasks) {
            if (!task.completed) {
                res.push_back(task.description);
            }
        }

        return res;
    }

    std::vector<std::string> getTasksForTag(int userId, std::string tag) {
        std::vector<std::string> res;
        std::vector<Task>& userTasks = tasks[userId];

        std::sort(userTasks.begin(), userTasks.end(), [](const Task& a, const Task& b) {
            return a.dueDate < b.dueDate;
        });

        for (const auto& task : userTasks) {
            if (!task.completed && std::find(task.tags.begin(), task.tags.end(), tag) != task.tags.end()) {
                res.push_back(task.description);
            }
        }

        return res;
    }

    void completeTask(int userId, int taskId) {
        std::vector<Task>& userTasks = tasks[userId];
        for (auto& task : userTasks) {
            if (task.id == taskId) {
                task.completed = true;
                break;
            }
        }
    }

private:
    int taskId;
    std::map<int, std::vector<Task>> tasks;
};
```
We define a `Task` class that keeps the task information such as `id`, `description`, `dueDate`, `tags`, and its completion status (`completed` field).

The `TodoList` class contains a map, `tasks`, that stores the tasks of each user as a list. Then, we implement the methods `addTask`, `getAllTasks`, `getTasksForTag`, and `completeTask`, using the map and Task objects.

1. `addTask()` creates a new Task object with the provided `taskDescription`, `dueDate`, and `tags`, and then adds the task to the corresponding user's task list. It increments the `taskId` by 1.
2. `getAllTasks()` retrieves the user's task list, sorts the tasks by the due date, and creates a list of uncompleted task descriptions to return.
3. `getTasksForTag()` retrieves the user's task list, sorts the tasks by the due date, and creates a list of uncompleted task descriptions that have the specified tag.
4. `completeTask()` finds the task with the given task ID for the specified user and sets the `completed` field of the task to `true`.

ForEach function is implemented using the standard library functions (`std::sort()` for C++, `Collections.sort()` for Java, `sorted()` for Python, and `Array.prototype.sort()` for JavaScript) and loops/iterators as required by each language.

## A solution in Python

```python
from typing import List

class Task:
    def __init__(self, id: int, description: str, due_date: int, tags: List[str]):
        self.id = id
        self.description = description
        self.due_date = due_date
        self.tags = tags
        self.completed = False

class TodoList:

    def __init__(self):
        self.task_id = 1
        self.tasks = {}

    def addTask(self, userId: int, taskDescription: str, dueDate: int, tags: List[str]) -> int:
        if userId not in self.tasks:
            self.tasks[userId] = []
        self.tasks[userId].append(Task(self.task_id, taskDescription, dueDate, tags))
        self.task_id += 1
        return self.task_id - 1

    def getAllTasks(self, userId: int) -> List[str]:
        if userId not in self.tasks:
            return []
        user_tasks = sorted(self.tasks[userId], key=lambda task: task.due_date)
        res = [task.description for task in user_tasks if not task.completed]
        return res

    def getTasksForTag(self, userId: int, tag: str) -> List[str]:
        if userId not in self.tasks:
            return []
        user_tasks = sorted(self.tasks[userId], key=lambda task: task.due_date)
        res = [task.description for task in user_tasks if not task.completed and tag in task.tags]
        return res

    def completeTask(self, userId: int, taskId: int) -> None:
        if userId not in self.tasks:
            return
        for task in self.tasks[userId]:
            if task.id == taskId:
                task.completed = True
                break
```
We define a `Task` class that keeps the task information such as `id`, `description`, `dueDate`, `tags`, and its completion status (`completed` field).

The `TodoList` class contains a map, `tasks`, that stores the tasks of each user as a list. Then, we implement the methods `addTask`, `getAllTasks`, `getTasksForTag`, and `completeTask`, using the map and Task objects.

1. `addTask()` creates a new Task object with the provided `taskDescription`, `dueDate`, and `tags`, and then adds the task to the corresponding user's task list. It increments the `taskId` by 1.
2. `getAllTasks()` retrieves the user's task list, sorts the tasks by the due date, and creates a list of uncompleted task descriptions to return.
3. `getTasksForTag()` retrieves the user's task list, sorts the tasks by the due date, and creates a list of uncompleted task descriptions that have the specified tag.
4. `completeTask()` finds the task with the given task ID for the specified user and sets the `completed` field of the task to `true`.

ForEach function is implemented using the standard library functions (`std::sort()` for C++, `Collections.sort()` for Java, `sorted()` for Python, and `Array.prototype.sort()` for JavaScript) and loops/iterators as required by each language.

## A solution in Javascript

```javascript
class Task {
    constructor(id, description, dueDate, tags, completed) {
        this.id = id;
        this.description = description;
        this.dueDate = dueDate;
        this.tags = tags;
        this.completed = completed;
    }
}

class TodoList {
    constructor() {
        this.taskId = 1;
        this.tasks = {};
    }

    addTask(userId, taskDescription, dueDate, tags) {
        if (!this.tasks[userId]) {
            this.tasks[userId] = [];
        }
        const task = new Task(this.taskId, taskDescription, dueDate, tags, false);
        this.tasks[userId].push(task);
        this.taskId++;
        return this.taskId - 1;
    }

    getAllTasks(userId) {
        if (!this.tasks[userId]) {
            return [];
        }
        const userTasks = this.tasks[userId].slice().sort((a, b) => a.dueDate - b.dueDate);
        const res = userTasks.filter(task => !task.completed).map(task => task.description);
        return res;
    }

    getTasksForTag(userId, tag) {
        if (!this.tasks[userId]) {
            return [];
        }
        const userTasks = this.tasks[userId].slice().sort((a, b) => a.dueDate - b.dueDate);
        const res = userTasks.filter(task => !task.completed && task.tags.includes(tag)).map(task => task.description);
        return res;
    }

    completeTask(userId, taskId) {
        if (!this.tasks[userId]) {
            return;
        }
        for (let task of this.tasks[userId]) {
            if (task.id === taskId) {
                task.completed = true;
                break;
            }
        }
    }
}
```
We define a `Task` class that keeps the task information such as `id`, `description`, `dueDate`, `tags`, and its completion status (`completed` field).

The `TodoList` class contains a map, `tasks`, that stores the tasks of each user as a list. Then, we implement the methods `addTask`, `getAllTasks`, `getTasksForTag`, and `completeTask`, using the map and Task objects.

1. `addTask()` creates a new Task object with the provided `taskDescription`, `dueDate`, and `tags`, and then adds the task to the corresponding user's task list. It increments the `taskId` by 1.
2. `getAllTasks()` retrieves the user's task list, sorts the tasks by the due date, and creates a list of uncompleted task descriptions to return.
3. `getTasksForTag()` retrieves the user's task list, sorts the tasks by the due date, and creates a list of uncompleted task descriptions that have the specified tag.
4. `completeTask()` finds the task with the given task ID for the specified user and sets the `completed` field of the task to `true`.

ForEach function is implemented using the standard library functions (`std::sort()` for C++, `Collections.sort()` for Java, `sorted()` for Python, and `Array.prototype.sort()` for JavaScript) and loops/iterators as required by each language.


# Distribute Money to Maximum Children

- slug: distribute-money-to-maximum-children
- difficulty: Easy

You are given an integer `money` denoting the amount of money (in dollars) that you have and another integer `children` denoting the number of children that you must distribute the money to.

You have to distribute the money according to the following rules:

*   All money must be distributed.
*   Everyone must receive at least `1` dollar.
*   Nobody receives `4` dollars.

Return _the **maximum** number of children who may receive **exactly**_ `8` _dollars if you distribute the money according to the aforementioned rules_. If there is no way to distribute the money, return `-1`.

**Example 1:**

**Input:** money = 20, children = 3
**Output:** 1
**Explanation:**
The maximum number of children with 8 dollars will be 1. One of the ways to distribute the money is:
- 8 dollars to the first child.
- 9 dollars to the second child.
- 3 dollars to the third child.
It can be proven that no distribution exists such that number of children getting 8 dollars is greater than 1.

**Example 2:**

**Input:** money = 16, children = 2
**Output:** 2
**Explanation:** Each child can be given 8 dollars.

**Constraints:**

*   `1 <= money <= 200`
*   `2 <= children <= 30`

## A solution in Java

```java
public int maximumChildrenWithEightDollars(int money, int children) {
    if (money < children * 1 || money > children * 8) return -1;
    int max_eights = (money - children) / 7;
    return max_eights >= children ? children : max_eights;
}
```
In this problem, we calculate the maximum number of children who get exactly 8 dollars by making sure that we follow the given rules. We first check if it's possible to distribute money with these constraints. If the amount of money is less than the product of the number of children and 1 or greater than the product of the number of children and 8, return -1 as it's not possible.

Then, find the maximum number of eights by subtracting the number of children from the amount of money and dividing the result by 7. We divide the result by 7, as we're trying to maximize the children getting exactly 8 dollars, and the other amounts could range from 1 to 3 or 5 to 7.

Finally, if the maximum number of eights is greater than or equal to the number of children, return the number of children. Otherwise, return the maximum number of eights. This calculation ensures that we're getting the maximum number of children who get exactly 8 dollars.

## A solution in C++

```cpp
int maximumChildrenWithEightDollars(int money, int children) {
    if (money < children * 1 || money > children * 8) return -1;
    int max_eights = (money - children) / 7;
    return max_eights >= children ? children : max_eights;
}
```
In this problem, we calculate the maximum number of children who get exactly 8 dollars by making sure that we follow the given rules. We first check if it's possible to distribute money with these constraints. If the amount of money is less than the product of the number of children and 1 or greater than the product of the number of children and 8, return -1 as it's not possible.

Then, find the maximum number of eights by subtracting the number of children from the amount of money and dividing the result by 7. We divide the result by 7, as we're trying to maximize the children getting exactly 8 dollars, and the other amounts could range from 1 to 3 or 5 to 7.

Finally, if the maximum number of eights is greater than or equal to the number of children, return the number of children. Otherwise, return the maximum number of eights. This calculation ensures that we're getting the maximum number of children who get exactly 8 dollars.

## A solution in Python

```python
def maximum_children_with_eight_dollars(money, children):
    if money < children * 1 or money > children * 8:
        return -1
    max_eights = (money - children) // 7
    return children if max_eights >= children else max_eights
```
In this problem, we calculate the maximum number of children who get exactly 8 dollars by making sure that we follow the given rules. We first check if it's possible to distribute money with these constraints. If the amount of money is less than the product of the number of children and 1 or greater than the product of the number of children and 8, return -1 as it's not possible.

Then, find the maximum number of eights by subtracting the number of children from the amount of money and dividing the result by 7. We divide the result by 7, as we're trying to maximize the children getting exactly 8 dollars, and the other amounts could range from 1 to 3 or 5 to 7.

Finally, if the maximum number of eights is greater than or equal to the number of children, return the number of children. Otherwise, return the maximum number of eights. This calculation ensures that we're getting the maximum number of children who get exactly 8 dollars.

## A solution in Javascript

```javascript
function maximumChildrenWithEightDollars(money, children) {
    if (money < children * 1 || money > children * 8) return -1;
    let max_eights = Math.floor((money - children) / 7);
    return max_eights >= children ? children : max_eights;
}
```
In this problem, we calculate the maximum number of children who get exactly 8 dollars by making sure that we follow the given rules. We first check if it's possible to distribute money with these constraints. If the amount of money is less than the product of the number of children and 1 or greater than the product of the number of children and 8, return -1 as it's not possible.

Then, find the maximum number of eights by subtracting the number of children from the amount of money and dividing the result by 7. We divide the result by 7, as we're trying to maximize the children getting exactly 8 dollars, and the other amounts could range from 1 to 3 or 5 to 7.

Finally, if the maximum number of eights is greater than or equal to the number of children, return the number of children. Otherwise, return the maximum number of eights. This calculation ensures that we're getting the maximum number of children who get exactly 8 dollars.


# Maximize Greatness of an Array

- slug: maximize-greatness-of-an-array
- difficulty: Medium

You are given a 0-indexed integer array `nums`. You are allowed to permute `nums` into a new array `perm` of your choosing.

We define the **greatness** of `nums` be the number of indices `0 <= i < nums.length` for which `perm[i] > nums[i]`.

Return _the **maximum** possible greatness you can achieve after permuting_ `nums`.

**Example 1:**

**Input:** nums = \[1,3,5,2,1,3,1\]
**Output:** 4
**Explanation:** One of the optimal rearrangements is perm = \[2,5,1,3,3,1,1\].
At indices = 0, 1, 3, and 4, perm\[i\] > nums\[i\]. Hence, we return 4.

**Example 2:**

**Input:** nums = \[1,2,3,4\]
**Output:** 3
**Explanation:** We can prove the optimal perm is \[2,3,4,1\].
At indices = 0, 1, and 2, perm\[i\] > nums\[i\]. Hence, we return 3.

**Constraints:**

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

## A solution in Java

```java
public int maxGreatness(int[] nums) {
    Arrays.sort(nums);
    int greatness = 0;
    for (int i = 1; i < nums.length; ++i) {
        if (nums[i - 1] < nums[i]) {
            int temp = nums[i - 1];
            nums[i - 1] = nums[i];
            nums[i] = temp;
            ++greatness;
        }
    }
    return greatness;
}
```
The algorithm consists of sorting the `nums` array in ascending order. Then, we iterate over the array from index 1 to the end. If the current element is greater than the one before it, we swap them and increase the greatness counter. This ensures that at each step, we have the maximum possible greatness for the current element. The algorithm takes advantage of the sorted array to perform permutations in a greedy manner, maximizing greatness at each step. The final result is the maximum greatness possible.

## A solution in C++

```cpp
int maxGreatness(vector<int>& nums) {
    sort(nums.begin(), nums.end());
    int greatness = 0;
    for (int i = 1; i < nums.size(); ++i) {
        if (nums[i - 1] < nums[i]) {
            swap(nums[i - 1], nums[i]);
            ++greatness;
        }
    }
    return greatness;
}
```
The algorithm consists of sorting the `nums` array in ascending order. Then, we iterate over the array from index 1 to the end. If the current element is greater than the one before it, we swap them and increase the greatness counter. This ensures that at each step, we have the maximum possible greatness for the current element. The algorithm takes advantage of the sorted array to perform permutations in a greedy manner, maximizing greatness at each step. The final result is the maximum greatness possible.

## A solution in Python

```python
def max_greatness(nums):
    nums.sort()
    greatness = 0
    for i in range(1, len(nums)):
        if nums[i - 1] < nums[i]:
            nums[i - 1], nums[i] = nums[i], nums[i - 1]
            greatness += 1
    return greatness
```
The algorithm consists of sorting the `nums` array in ascending order. Then, we iterate over the array from index 1 to the end. If the current element is greater than the one before it, we swap them and increase the greatness counter. This ensures that at each step, we have the maximum possible greatness for the current element. The algorithm takes advantage of the sorted array to perform permutations in a greedy manner, maximizing greatness at each step. The final result is the maximum greatness possible.

## A solution in Javascript

```javascript
function maxGreatness(nums) {
    nums.sort((a, b) => a - b);
    let greatness = 0;
    for (let i = 1; i < nums.length; ++i) {
        if (nums[i - 1] < nums[i]) {
            [nums[i - 1], nums[i]] = [nums[i], nums[i - 1]];
            ++greatness;
        }
    }
    return greatness;
}
```
The algorithm consists of sorting the `nums` array in ascending order. Then, we iterate over the array from index 1 to the end. If the current element is greater than the one before it, we swap them and increase the greatness counter. This ensures that at each step, we have the maximum possible greatness for the current element. The algorithm takes advantage of the sorted array to perform permutations in a greedy manner, maximizing greatness at each step. The final result is the maximum greatness possible.


# Find Score of an Array After Marking All Elements

- slug: find-score-of-an-array-after-marking-all-elements
- difficulty: Medium

You are given an array `nums` consisting of positive integers.

Starting with `score = 0`, apply the following algorithm:

*   Choose the smallest integer of the array that is not marked. If there is a tie, choose the one with the smallest index.
*   Add the value of the chosen integer to `score`.
*   Mark **the chosen element and its two adjacent elements if they exist**.
*   Repeat until all the array elements are marked.

Return _the score you get after applying the above algorithm_.

**Example 1:**

**Input:** nums = \[2,1,3,4,5,2\]
**Output:** 7
**Explanation:** We mark the elements as follows:
- 1 is the smallest unmarked element, so we mark it and its two adjacent elements: \[2,1,3,4,5,2\].
- 2 is the smallest unmarked element, so we mark it and its left adjacent element: \[2,1,3,4,5,2\].
- 4 is the only remaining unmarked element, so we mark it: \[2,1,3,4,5,2\].
Our score is 1 + 2 + 4 = 7.

**Example 2:**

**Input:** nums = \[2,3,5,1,3,2\]
**Output:** 5
**Explanation:** We mark the elements as follows:
- 1 is the smallest unmarked element, so we mark it and its two adjacent elements: \[2,3,5,1,3,2\].
- 2 is the smallest unmarked element, since there are two of them, we choose the left-most one, so we mark the one at index 0 and its right adjacent element: \[2,3,5,1,3,2\].
- 2 is the only remaining unmarked element, so we mark it: \[2,3,5,1,3,2\].
Our score is 1 + 2 + 2 = 5.

**Constraints:**

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

## A solution in Java

```java
public int calculateScore(int[] nums) {
    int n = nums.length;
    int[] dp = new int[n + 2];

    for (int i = 0; i < n; ++i) {
        dp[i + 2] = Math.max(dp[i + 1], dp[i] + nums[i]);
    }

    return dp[n + 1];
}
```
This problem can be solved using dynamic programming. We create an array `dp` with length `n+2` (to handle edge cases) initialized with zeros. We iterate through the given `nums` array and for each element, we store in `dp[i+2]` the maximum value between `dp[i+1]` (if we choose not to pick the current element) and `dp[i] + nums[i]` (if we choose to pick the current element and thus mark the adjacent elements as well).

This way, by the end of the iteration, `dp[n+1]` will store the maximum score possible considering all the elements in the array `nums`.

The time complexity of the solution is O(n), where n is the length of the input array, and the space complexity is also O(n), which is used for the `dp` array.

## A solution in C++

```cpp
int calculateScore(vector<int>& nums) {
    int n = nums.size();
    vector<int> dp(n + 2, 0);

    for (int i = 0; i < n; ++i) {
        dp[i + 2] = max(dp[i + 1], dp[i] + nums[i]);
    }

    return dp[n + 1];
}
```
This problem can be solved using dynamic programming. We create an array `dp` with length `n+2` (to handle edge cases) initialized with zeros. We iterate through the given `nums` array and for each element, we store in `dp[i+2]` the maximum value between `dp[i+1]` (if we choose not to pick the current element) and `dp[i] + nums[i]` (if we choose to pick the current element and thus mark the adjacent elements as well).

This way, by the end of the iteration, `dp[n+1]` will store the maximum score possible considering all the elements in the array `nums`.

The time complexity of the solution is O(n), where n is the length of the input array, and the space complexity is also O(n), which is used for the `dp` array.

## A solution in Python

```python
def calculate_score(nums):
    n = len(nums)
    dp = [0] * (n + 2)

    for i in range(n):
        dp[i + 2] = max(dp[i + 1], dp[i] + nums[i])

    return dp[n + 1]
```
This problem can be solved using dynamic programming. We create an array `dp` with length `n+2` (to handle edge cases) initialized with zeros. We iterate through the given `nums` array and for each element, we store in `dp[i+2]` the maximum value between `dp[i+1]` (if we choose not to pick the current element) and `dp[i] + nums[i]` (if we choose to pick the current element and thus mark the adjacent elements as well).

This way, by the end of the iteration, `dp[n+1]` will store the maximum score possible considering all the elements in the array `nums`.

The time complexity of the solution is O(n), where n is the length of the input array, and the space complexity is also O(n), which is used for the `dp` array.

## A solution in Javascript

```javascript
function calculateScore(nums) {
    const n = nums.length;
    const dp = new Array(n + 2).fill(0);

    for (let i = 0; i < n; ++i) {
        dp[i + 2] = Math.max(dp[i + 1], dp[i] + nums[i]);
    }

    return dp[n + 1];
}
```
This problem can be solved using dynamic programming. We create an array `dp` with length `n+2` (to handle edge cases) initialized with zeros. We iterate through the given `nums` array and for each element, we store in `dp[i+2]` the maximum value between `dp[i+1]` (if we choose not to pick the current element) and `dp[i] + nums[i]` (if we choose to pick the current element and thus mark the adjacent elements as well).

This way, by the end of the iteration, `dp[n+1]` will store the maximum score possible considering all the elements in the array `nums`.

The time complexity of the solution is O(n), where n is the length of the input array, and the space complexity is also O(n), which is used for the `dp` array.


# Minimum Time to Repair Cars

- slug: minimum-time-to-repair-cars
- difficulty: Medium

You are given an integer array `ranks` representing the **ranks** of some mechanics. ranksi is the rank of the ith mechanic. A mechanic with a rank `r` can repair n cars in `r * n2` minutes.

You are also given an integer `cars` representing the total number of cars waiting in the garage to be repaired.

Return _the **minimum** time taken to repair all the cars._

**Note:** All the mechanics can repair the cars simultaneously.

**Example 1:**

**Input:** ranks = \[4,2,3,1\], cars = 10
**Output:** 16
**Explanation:**
- The first mechanic will repair two cars. The time required is 4 \* 2 \* 2 = 16 minutes.
- The second mechanic will repair two cars. The time required is 2 \* 2 \* 2 = 8 minutes.
- The third mechanic will repair two cars. The time required is 3 \* 2 \* 2 = 12 minutes.
- The fourth mechanic will repair four cars. The time required is 1 \* 4 \* 4 = 16 minutes.
It can be proved that the cars cannot be repaired in less than 16 minutes.

**Example 2:**

**Input:** ranks = \[5,1,8\], cars = 6
**Output:** 16
**Explanation:**
- The first mechanic will repair one car. The time required is 5 \* 1 \* 1 = 5 minutes.
- The second mechanic will repair four cars. The time required is 1 \* 4 \* 4 = 16 minutes.
- The third mechanic will repair one car. The time required is 8 \* 1 \* 1 = 8 minutes.
It can be proved that the cars cannot be repaired in less than 16 minutes.

**Constraints:**

*   `1 <= ranks.length <= 105`
*   `1 <= ranks[i] <= 100`
*   `1 <= cars <= 106`

## A solution in Java

```java
import java.util.Arrays;

public int minTimeToRepair(int[] ranks, int cars) {
    Arrays.sort(ranks);
    int low = 0, high = 100 * cars * cars;
    while (low < high) {
        int mid = low + (high - low) / 2;
        int total_cars_repaired = 0;
        for (int rank : ranks) {
            int cars_repaired = Math.min(cars, mid / (rank * rank));
            total_cars_repaired += cars_repaired;
            if (total_cars_repaired >= cars) break;
        }
        if (total_cars_repaired >= cars) high = mid;
        else low = mid + 1;
    }
    return low;
}
```
1. Sort mechanics by their ranks.
2. Perform binary search to find the minimum time required to repair all cars:
    a. Initialize the boundaries `low` and `high`.
    b. Calculate the middle value `mid`.
    c. For each mechanic, calculate the number of cars they can repair in `mid` minutes and sum it to `total_cars_repaired`.
    d. Check if `total_cars_repaired` is greater than or equal to the number of cars. If yes, update `high = mid`. Otherwise, update `low = mid + 1`.
3. The answer is in the `low` variable.

## A solution in C++

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

int minTimeToRepair(vector<int>& ranks, int cars) {
    sort(ranks.begin(), ranks.end());
    int low = 0, high = 100 * cars * cars;
    while (low < high) {
        int mid = low + (high - low) / 2;
        int total_cars_repaired = 0;
        for (int rank : ranks) {
            int cars_repaired = min(cars, mid / (rank * rank));
            total_cars_repaired += cars_repaired;
            if (total_cars_repaired >= cars) break;
        }
        if (total_cars_repaired >= cars) high = mid;
        else low = mid + 1;
    }
    return low;
}
```
1. Sort mechanics by their ranks.
2. Perform binary search to find the minimum time required to repair all cars:
    a. Initialize the boundaries `low` and `high`.
    b. Calculate the middle value `mid`.
    c. For each mechanic, calculate the number of cars they can repair in `mid` minutes and sum it to `total_cars_repaired`.
    d. Check if `total_cars_repaired` is greater than or equal to the number of cars. If yes, update `high = mid`. Otherwise, update `low = mid + 1`.
3. The answer is in the `low` variable.

## A solution in Python

```python
def min_time_to_repair(ranks, cars):
    ranks.sort()
    low, high = 0, 100 * cars * cars

    while low < high:
        mid = low + (high - low) // 2
        total_cars_repaired = 0
        for rank in ranks:
            cars_repaired = min(cars, mid // (rank * rank))
            total_cars_repaired += cars_repaired
            if total_cars_repaired >= cars:
                break
        if total_cars_repaired >= cars:
            high = mid
        else:
            low = mid + 1

    return low
```
1. Sort mechanics by their ranks.
2. Perform binary search to find the minimum time required to repair all cars:
    a. Initialize the boundaries `low` and `high`.
    b. Calculate the middle value `mid`.
    c. For each mechanic, calculate the number of cars they can repair in `mid` minutes and sum it to `total_cars_repaired`.
    d. Check if `total_cars_repaired` is greater than or equal to the number of cars. If yes, update `high = mid`. Otherwise, update `low = mid + 1`.
3. The answer is in the `low` variable.

## A solution in Javascript

```javascript
function minTimeToRepair(ranks, cars) {
    ranks.sort((a, b) => a - b);
    let low = 0, high = 100 * cars * cars;
    while (low < high) {
        const mid = low + Math.floor((high - low) / 2);
        let total_cars_repaired = 0;
        for (const rank of ranks) {
            const cars_repaired = Math.min(cars, Math.floor(mid / (rank * rank)));
            total_cars_repaired += cars_repaired;
            if (total_cars_repaired >= cars) break;
        }
        if (total_cars_repaired >= cars) high = mid;
        else low = mid + 1;
    }
    return low;
}
```
1. Sort mechanics by their ranks.
2. Perform binary search to find the minimum time required to repair all cars:
    a. Initialize the boundaries `low` and `high`.
    b. Calculate the middle value `mid`.
    c. For each mechanic, calculate the number of cars they can repair in `mid` minutes and sum it to `total_cars_repaired`.
    d. Check if `total_cars_repaired` is greater than or equal to the number of cars. If yes, update `high = mid`. Otherwise, update `low = mid + 1`.
3. The answer is in the `low` variable.


# Number of Even and Odd Bits

- slug: number-of-even-and-odd-bits
- difficulty: Easy

You are given a **positive** integer `n`.

Let `even` denote the number of even indices in the binary representation of `n` (**0-indexed**) with value `1`.

Let `odd` denote the number of odd indices in the binary representation of `n` (**0-indexed**) with value `1`.

Return _an integer array_ `answer` _where_ `answer = [even, odd]`.

**Example 1:**

**Input:** n = 17
**Output:** \[2,0\]
**Explanation:** The binary representation of 17 is 10001.
It contains 1 on the 0th and 4th indices.
There are 2 even and 0 odd indices.

**Example 2:**

**Input:** n = 2
**Output:** \[0,1\]
**Explanation:** The binary representation of 2 is 10.
It contains 1 on the 1st index.
There are 0 even and 1 odd indices.

**Constraints:**

*   `1 <= n <= 1000`

## A solution in Java

```java
public int[] evenOddIndices(int n) {
    int[] answer = new int[2];
    int index = 0;
    while (n > 0) {
        if (n % 2 == 1)
            answer[index % 2] += 1;
        n /= 2;
        index += 1;
    }
    return answer;
}
```
The algorithm iterates through the bits of the input number `n` one by one. For each bit, it checks whether the bit is set (1) or not. If the bit is set and its index (0-indexed) is even, it increments the `even` count in `answer`. If the bit is set and its index is odd, it increments the `odd` count in `answer`. The algorithm continues until all bits of the number have been processed. Finally, it returns the `answer` array containing the counts of even and odd indices with the value of 1 in the binary representation of `n`.

## A solution in C++

```cpp
#include <vector>

std::vector<int> evenOddIndices(int n) {
    std::vector<int> answer(2, 0);
    int index = 0;
    while (n > 0) {
        if (n % 2)
            answer[index % 2] += 1;
        n /= 2;
        index += 1;
    }
    return answer;
}
```
The algorithm iterates through the bits of the input number `n` one by one. For each bit, it checks whether the bit is set (1) or not. If the bit is set and its index (0-indexed) is even, it increments the `even` count in `answer`. If the bit is set and its index is odd, it increments the `odd` count in `answer`. The algorithm continues until all bits of the number have been processed. Finally, it returns the `answer` array containing the counts of even and odd indices with the value of 1 in the binary representation of `n`.

## A solution in Python

```python
def even_odd_indices(n: int) -> List[int]:
    answer = [0, 0]
    index = 0
    while n > 0:
        if n % 2:
            answer[index % 2] += 1
        n //= 2
        index += 1
    return answer
```
The algorithm iterates through the bits of the input number `n` one by one. For each bit, it checks whether the bit is set (1) or not. If the bit is set and its index (0-indexed) is even, it increments the `even` count in `answer`. If the bit is set and its index is odd, it increments the `odd` count in `answer`. The algorithm continues until all bits of the number have been processed. Finally, it returns the `answer` array containing the counts of even and odd indices with the value of 1 in the binary representation of `n`.

## A solution in Javascript

```javascript
function evenOddIndices(n) {
    let answer = [0, 0];
    let index = 0;
    while (n > 0) {
        if (n % 2)
            answer[index % 2] += 1;
        n = Math.floor(n / 2);
        index += 1;
    }
    return answer;
}
```
The algorithm iterates through the bits of the input number `n` one by one. For each bit, it checks whether the bit is set (1) or not. If the bit is set and its index (0-indexed) is even, it increments the `even` count in `answer`. If the bit is set and its index is odd, it increments the `odd` count in `answer`. The algorithm continues until all bits of the number have been processed. Finally, it returns the `answer` array containing the counts of even and odd indices with the value of 1 in the binary representation of `n`.


# Check Knight Tour Configuration

- slug: check-knight-tour-configuration
- difficulty: Medium

There is a knight on an `n x n` chessboard. In a valid configuration, the knight starts **at the top-left cell** of the board and visits every cell on the board **exactly once**.

You are given an `n x n` integer matrix `grid` consisting of distinct integers from the range `[0, n * n - 1]` where `grid[row][col]` indicates that the cell `(row, col)` is the `grid[row][col]th` cell that the knight visited. The moves are **0-indexed**.

Return `true` _if_ `grid` _represents a valid configuration of the knight's movements or_ `false` _otherwise_.

**Note** that a valid knight move consists of moving two squares vertically and one square horizontally, or two squares horizontally and one square vertically. The figure below illustrates all the possible eight moves of a knight from some cell.

**Example 1:**

**Input:** grid = \[\[0,11,16,5,20\],\[17,4,19,10,15\],\[12,1,8,21,6\],\[3,18,23,14,9\],\[24,13,2,7,22\]\]
**Output:** true
**Explanation:** The above diagram represents the grid. It can be shown that it is a valid configuration.

**Example 2:**

**Input:** grid = \[\[0,3,6\],\[5,8,1\],\[2,7,4\]\]
**Output:** false
**Explanation:** The above diagram represents the grid. The 8th move of the knight is not valid considering its position after the 7th move.

**Constraints:**

*   `n == grid.length == grid[i].length`
*   `3 <= n <= 7`
*   `0 <= grid[row][col] < n * n`
*   All integers in `grid` are **unique**.

## A solution in Java

```java
public boolean isValidMove(int i, int j, int k, int n) {
    return (i + 1 < n && j + 2 < n && k == n * (i + 1) + (j + 2)) ||
           (i + 1 < n && j - 2 >= 0 && k == n * (i + 1) + (j - 2)) ||
           (i + 2 < n && j + 1 < n && k == n * (i + 2) + (j + 1)) ||
           (i + 2 < n && j - 1 >= 0 && k == n * (i + 2) + (j - 1));
}

public boolean validPath(int[][] grid) {
    int n = grid.length;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            int k = grid[i][j];
            if (k != n * n - 1 && !isValidMove(i, j, k + 1, n)) {
                return false;
            }
        }
    }
    return true;
}
```
The problem can be solved by simulating the possible moves of the knight from each cell. We start by traversing the given `grid`. For each cell `(i, j)` with value `k`, we check whether the knight's next move would be valid or not. The next move of the knight can be one of the following four moves, given the knight is at `(i, j)`:
- Move to `(i+1, j+2)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).
- Move to `(i+1, j-2)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).
- Move to `(i+2, j+1)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).
- Move to `(i+2, j-1)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).

The function `isValidMove(i, j, k, n)` checks whether the knight can move to cell with value `k` or not. During the grid traversal, if we find a cell for which the next move is not valid, we return `false`. If we successfully traverse the entire grid, it means the configuration is valid, and we return `true`.

## A solution in C++

```cpp
bool isValidMove(int i, int j, int k, int n) {
    return (i + 1 < n && j + 2 < n && k == n * (i + 1) + (j + 2)) ||
           (i + 1 < n && j - 2 >= 0 && k == n * (i + 1) + (j - 2)) ||
           (i + 2 < n && j + 1 < n && k == n * (i + 2) + (j + 1)) ||
           (i + 2 < n && j - 1 >= 0 && k == n * (i + 2) + (j - 1));
}

bool validPath(vector<vector<int>>& grid) {
    int n = grid.size();
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            int k = grid[i][j];
            if (k != n * n - 1 && !isValidMove(i, j, k + 1, n)) {
                return false;
            }
        }
    }
    return true;
}
```
The problem can be solved by simulating the possible moves of the knight from each cell. We start by traversing the given `grid`. For each cell `(i, j)` with value `k`, we check whether the knight's next move would be valid or not. The next move of the knight can be one of the following four moves, given the knight is at `(i, j)`:
- Move to `(i+1, j+2)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).
- Move to `(i+1, j-2)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).
- Move to `(i+2, j+1)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).
- Move to `(i+2, j-1)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).

The function `isValidMove(i, j, k, n)` checks whether the knight can move to cell with value `k` or not. During the grid traversal, if we find a cell for which the next move is not valid, we return `false`. If we successfully traverse the entire grid, it means the configuration is valid, and we return `true`.

## A solution in Python

```python
def isValidMove(i, j, k, n):
    return (i + 1 < n and j + 2 < n and k == n * (i + 1) + (j + 2)) or \
           (i + 1 < n and j - 2 >= 0 and k == n * (i + 1) + (j - 2)) or \
           (i + 2 < n and j + 1 < n and k == n * (i + 2) + (j + 1)) or \
           (i + 2 < n and j - 1 >= 0 and k == n * (i + 2) + (j - 1))

def validPath(grid):
    n = len(grid)
    for i in range(n):
        for j in range(n):
            k = grid[i][j]
            if k != n * n - 1 and not isValidMove(i, j, k + 1, n):
                return False
    return True
```
The problem can be solved by simulating the possible moves of the knight from each cell. We start by traversing the given `grid`. For each cell `(i, j)` with value `k`, we check whether the knight's next move would be valid or not. The next move of the knight can be one of the following four moves, given the knight is at `(i, j)`:
- Move to `(i+1, j+2)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).
- Move to `(i+1, j-2)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).
- Move to `(i+2, j+1)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).
- Move to `(i+2, j-1)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).

The function `isValidMove(i, j, k, n)` checks whether the knight can move to cell with value `k` or not. During the grid traversal, if we find a cell for which the next move is not valid, we return `false`. If we successfully traverse the entire grid, it means the configuration is valid, and we return `true`.

## A solution in Javascript

```javascript
function isValidMove(i, j, k, n) {
    return (i + 1 < n && j + 2 < n && k === n * (i + 1) + (j + 2)) ||
           (i + 1 < n && j - 2 >= 0 && k === n * (i + 1) + (j - 2)) ||
           (i + 2 < n && j + 1 < n && k === n * (i + 2) + (j + 1)) ||
           (i + 2 < n && j - 1 >= 0 && k === n * (i + 2) + (j - 1));
}

function validPath(grid) {
    const n = grid.length;
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
            const k = grid[i][j];
            if (k !== n * n - 1 && !isValidMove(i, j, k + 1, n)) {
                return false;
            }
        }
    }
    return true;
}
```
The problem can be solved by simulating the possible moves of the knight from each cell. We start by traversing the given `grid`. For each cell `(i, j)` with value `k`, we check whether the knight's next move would be valid or not. The next move of the knight can be one of the following four moves, given the knight is at `(i, j)`:
- Move to `(i+1, j+2)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).
- Move to `(i+1, j-2)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).
- Move to `(i+2, j+1)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).
- Move to `(i+2, j-1)` if it is within the grid boundaries, and it's the next expected cell (`k+1`).

The function `isValidMove(i, j, k, n)` checks whether the knight can move to cell with value `k` or not. During the grid traversal, if we find a cell for which the next move is not valid, we return `false`. If we successfully traverse the entire grid, it means the configuration is valid, and we return `true`.


# The Number of Beautiful Subsets

- slug: the-number-of-beautiful-subsets
- difficulty: Medium

You are given an array `nums` of positive integers and a **positive** integer `k`.

A subset of `nums` is **beautiful** if it does not contain two integers with an absolute difference equal to `k`.

Return _the number of **non-empty beautiful** subsets of the array_ `nums`.

A **subset** of `nums` is an array that can be obtained by deleting some (possibly none) elements from `nums`. Two subsets are different if and only if the chosen indices to delete are different.

**Example 1:**

**Input:** nums = \[2,4,6\], k = 2
**Output:** 4
**Explanation:** The beautiful subsets of the array nums are: \[2\], \[4\], \[6\], \[2, 6\].
It can be proved that there are only 4 beautiful subsets in the array \[2,4,6\].

**Example 2:**

**Input:** nums = \[1\], k = 1
**Output:** 1
**Explanation:** The beautiful subset of the array nums is \[1\].
It can be proved that there is only 1 beautiful subset in the array \[1\].

**Constraints:**

*   `1 <= nums.length <= 20`
*   `1 <= nums[i], k <= 1000`

## A solution in Java

```java
import java.util.Arrays;

public int countBeautifulSubsets(int[] nums, int k) {
    Arrays.sort(nums);
    int ans = 0;
    int[] dp = new int[nums.length];
    Arrays.fill(dp, 1);
    for (int i = 0; i < nums.length; i++) {
        for (int j = 0, l = 0, r = -1; j < i; j++) {
            while (l < j && nums[j] - nums[l] >= k) l++;
            while (r + 1 < j && nums[r + 1] - nums[j] < k) r++;
            if (l <= r) dp[j] -= dp[l - 1];
            dp[j] += dp[j - 1] + 1;
            ans += dp[j];
        }
    }
    return ans;
}
```
The algorithm first sorts the array `nums` in non-descending order. Then, we use dynamic programming to keep track of the number of non-empty beautiful subsets. For each index `i`, we iterate from index `0` to `i - 1`, maintaining pointers `l` and `r`. We move the pointers such that:

1. The difference between `nums[j]` and `nums[l]` is at least `k`.
2. The difference between `nums[r + 1]` and `nums[j]` is less than `k`.

We update the `dp[j]` by subtracting the value in the `dp[l - 1]` if `l <= r` (there is at least one subset satisfying the condition), then adding the value in the `dp[j - 1]`. Finally, we add the current value of `dp[j]` to the answer.

This approach has time complexity of O(n^2) with n being the length of the input array `nums`.

## A solution in C++

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

int countBeautifulSubsets(vector<int>& nums, int k) {
    sort(nums.begin(), nums.end());
    int ans = 0;
    vector<int> dp(nums.size(), 1);
    for (int i = 0; i < nums.size(); i++) {
        for (int j = 0, l = 0, r = -1; j < i; j++) {
            while (l < j && nums[j] - nums[l] >= k) l++;
            while (r + 1 < j && nums[r + 1] - nums[j] < k) r++;
            if (l <= r) dp[j] -= dp[l - 1];
            dp[j] += dp[j - 1] + 1;
            ans += dp[j];
        }
    }
    return ans;
}
```
The algorithm first sorts the array `nums` in non-descending order. Then, we use dynamic programming to keep track of the number of non-empty beautiful subsets. For each index `i`, we iterate from index `0` to `i - 1`, maintaining pointers `l` and `r`. We move the pointers such that:

1. The difference between `nums[j]` and `nums[l]` is at least `k`.
2. The difference between `nums[r + 1]` and `nums[j]` is less than `k`.

We update the `dp[j]` by subtracting the value in the `dp[l - 1]` if `l <= r` (there is at least one subset satisfying the condition), then adding the value in the `dp[j - 1]`. Finally, we add the current value of `dp[j]` to the answer.

This approach has time complexity of O(n^2) with n being the length of the input array `nums`.

## A solution in Python

```python
def countBeautifulSubsets(nums, k):
    nums.sort()
    ans = 0
    dp = [1] * len(nums)
    for i in range(len(nums)):
        l = r = 0
        for j in range(i):
            while l < j and nums[j] - nums[l] >= k:
                l += 1
            while r + 1 < j and nums[r + 1] - nums[j] < k:
                r += 1
            dp[j] -= dp[l - 1] if l <= r else 0
            dp[j] += dp[j - 1] + 1
            ans += dp[j]
    return ans
```
The algorithm first sorts the array `nums` in non-descending order. Then, we use dynamic programming to keep track of the number of non-empty beautiful subsets. For each index `i`, we iterate from index `0` to `i - 1`, maintaining pointers `l` and `r`. We move the pointers such that:

1. The difference between `nums[j]` and `nums[l]` is at least `k`.
2. The difference between `nums[r + 1]` and `nums[j]` is less than `k`.

We update the `dp[j]` by subtracting the value in the `dp[l - 1]` if `l <= r` (there is at least one subset satisfying the condition), then adding the value in the `dp[j - 1]`. Finally, we add the current value of `dp[j]` to the answer.

This approach has time complexity of O(n^2) with n being the length of the input array `nums`.

## A solution in Javascript

```javascript
function countBeautifulSubsets(nums, k) {
    nums.sort((a, b) => a - b);
    let ans = 0;
    const dp = new Array(nums.length).fill(1);
    for (let i = 0; i < nums.length; i++) {
        for (let j = 0, l = 0, r = -1; j < i; j++) {
            while (l < j && nums[j] - nums[l] >= k) l++;
            while (r + 1 < j && nums[r + 1] - nums[j] < k) r++;
            if (l <= r) dp[j] -= dp[l - 1];
            dp[j] += dp[j - 1] + 1;
            ans += dp[j];
        }
    }
    return ans;
}
```
The algorithm first sorts the array `nums` in non-descending order. Then, we use dynamic programming to keep track of the number of non-empty beautiful subsets. For each index `i`, we iterate from index `0` to `i - 1`, maintaining pointers `l` and `r`. We move the pointers such that:

1. The difference between `nums[j]` and `nums[l]` is at least `k`.
2. The difference between `nums[r + 1]` and `nums[j]` is less than `k`.

We update the `dp[j]` by subtracting the value in the `dp[l - 1]` if `l <= r` (there is at least one subset satisfying the condition), then adding the value in the `dp[j - 1]`. Finally, we add the current value of `dp[j]` to the answer.

This approach has time complexity of O(n^2) with n being the length of the input array `nums`.


# Smallest Missing Non-negative Integer After Operations

- slug: smallest-missing-non-negative-integer-after-operations
- difficulty: Medium

You are given a **0-indexed** integer array `nums` and an integer `value`.

In one operation, you can add or subtract `value` from any element of `nums`.

*   For example, if `nums = [1,2,3]` and `value = 2`, you can choose to subtract `value` from `nums[0]` to make `nums = [-1,2,3]`.

The MEX (minimum excluded) of an array is the smallest missing **non-negative** integer in it.

*   For example, the MEX of `[-1,2,3]` is `0` while the MEX of `[1,0,3]` is `2`.

Return _the maximum MEX of_ `nums` _after applying the mentioned operation **any number of times**_.

**Example 1:**

**Input:** nums = \[1,-10,7,13,6,8\], value = 5
**Output:** 4
**Explanation:** One can achieve this result by applying the following operations:
- Add value to nums\[1\] twice to make nums = \[1,**0**,7,13,6,8\]
- Subtract value from nums\[2\] once to make nums = \[1,0,**2**,13,6,8\]
- Subtract value from nums\[3\] twice to make nums = \[1,0,2,**3**,6,8\]
The MEX of nums is 4. It can be shown that 4 is the maximum MEX we can achieve.

**Example 2:**

**Input:** nums = \[1,-10,7,13,6,8\], value = 7
**Output:** 2
**Explanation:** One can achieve this result by applying the following operation:
- subtract value from nums\[2\] once to make nums = \[1,-10,**0**,13,6,8\]
The MEX of nums is 2. It can be shown that 2 is the maximum MEX we can achieve.

**Constraints:**

*   `1 <= nums.length, value <= 105`
*   `-109 <= nums[i] <= 109`

## A solution in Java

```java
int maximum_mex(int[] nums, int value) {
    HashSet<Integer> st = new HashSet<>();

    for (int num : nums)
        st.add(num);

    for (int i = 0; i <= 100000; i++) {
        if (!st.contains(i))
            st.add(i + value);
    }

    int mex = 0;
    while (st.contains(mex))
        mex++;

    return mex;
}
```
The algorithm starts by transforming the input array into a set `st` to remove duplicates and have faster membership testing. Then, it iterates through the range [0, 100000] (inclusive), checking for each number `i` if it is not in the set `st`. If `i` is not in `st`, it adds `i + value` to the set. This way, we simulate the addition or subtraction of the `value` from the elements of the initial array.

After processing the range, the algorithm initializes a variable `mex` to zero and keeps incrementing it while it is present in the set `st`. When the mex is no longer in the set, it means it's the maximum MEX value achievable, and the function returns it.

## A solution in C++

```cpp
int maximum_mex(std::vector<int>& nums, int value) {
    std::unordered_set<int> st(nums.begin(), nums.end());

    for (int i = 0; i <= 100000; i++) {
        if (!st.count(i))
            st.insert(i + value);
    }

    int mex = 0;
    while (st.count(mex))
        mex++;

    return mex;
}
```
The algorithm starts by transforming the input array into a set `st` to remove duplicates and have faster membership testing. Then, it iterates through the range [0, 100000] (inclusive), checking for each number `i` if it is not in the set `st`. If `i` is not in `st`, it adds `i + value` to the set. This way, we simulate the addition or subtraction of the `value` from the elements of the initial array.

After processing the range, the algorithm initializes a variable `mex` to zero and keeps incrementing it while it is present in the set `st`. When the mex is no longer in the set, it means it's the maximum MEX value achievable, and the function returns it.

## A solution in Python

```python
def maximum_mex(nums: List[int], value: int) -> int:
    st = set(nums)

    for i in range(100001):
        if i not in st:
            st.add(i + value)

    mex = 0
    while mex in st:
        mex += 1

    return mex
```
The algorithm starts by transforming the input array into a set `st` to remove duplicates and have faster membership testing. Then, it iterates through the range [0, 100000] (inclusive), checking for each number `i` if it is not in the set `st`. If `i` is not in `st`, it adds `i + value` to the set. This way, we simulate the addition or subtraction of the `value` from the elements of the initial array.

After processing the range, the algorithm initializes a variable `mex` to zero and keeps incrementing it while it is present in the set `st`. When the mex is no longer in the set, it means it's the maximum MEX value achievable, and the function returns it.

## A solution in Javascript

```javascript
function maximum_mex(nums, value) {
    let st = new Set(nums);

    for (let i = 0; i <= 100000; i++) {
        if (!st.has(i))
            st.add(i + value);
    }

    let mex = 0;
    while (st.has(mex))
        mex++;

    return mex;
}
```
The algorithm starts by transforming the input array into a set `st` to remove duplicates and have faster membership testing. Then, it iterates through the range [0, 100000] (inclusive), checking for each number `i` if it is not in the set `st`. If `i` is not in `st`, it adds `i + value` to the set. This way, we simulate the addition or subtraction of the `value` from the elements of the initial array.

After processing the range, the algorithm initializes a variable `mex` to zero and keeps incrementing it while it is present in the set `st`. When the mex is no longer in the set, it means it's the maximum MEX value achievable, and the function returns it.


# Make the Prefix Sum Non-negative

- slug: make-the-prefix-sum-non-negative
- difficulty: Medium

You are given a **0-indexed** integer array `nums`. You can apply the following operation any number of times:

*   Pick any element from `nums` and put it at the end of `nums`.

The prefix sum array of `nums` is an array `prefix` of the same length as `nums` such that `prefix[i]` is the sum of all the integers `nums[j]` where `j` is in the inclusive range `[0, i]`.

Return _the minimum number of operations such that the prefix sum array does not contain negative integers_. The test cases are generated such that it is always possible to make the prefix sum array non-negative.

**Example 1:**

**Input:** nums = \[2,3,-5,4\]
**Output:** 0
**Explanation:** we do not need to do any operations.
The array is \[2,3,-5,4\]. The prefix sum array is \[2, 5, 0, 4\].

**Example 2:**

**Input:** nums = \[3,-5,-2,6\]
**Output:** 1
**Explanation:** we can do one operation on index 1.
The array after the operation is \[3,-2,6,-5\]. The prefix sum array is \[3, 1, 7, 2\].

**Constraints:**

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

## A solution in Java

```java
public int minOperations(int[] nums) {
    int minPrefix = 0;
    int prefix = 0;
    for (int num : nums) {
        prefix += num;
        minPrefix = Math.min(minPrefix, prefix);
    }
    return minPrefix < 0 ? -minPrefix : 0;
}
```
We initialize two variables `min_prefix` and `prefix` both set to 0. We iterate over the elements in the `nums` array, adding each element to the `prefix`. At each iteration, we compare and store the minimum value between `min_prefix` and `prefix`.

After the loop, we check if `min_prefix` is less than 0. If it is, return the negation of `min_prefix`. Otherwise, return 0.

The logic behind this algorithm is to find the minimum prefix sum that appears in the array. If this minimum prefix sum is negative, we need to perform operations to "shift" the array values so that the minimum prefix sum becomes non-negative. The minimum number of operations required to do this is equal to the absolute value of the minimum prefix sum found. If the minimum prefix sum is non-negative, there is no need to perform any operations.

## A solution in C++

```cpp
int minOperations(vector<int>& nums) {
    int min_prefix = 0;
    int prefix = 0;
    for (int num : nums) {
        prefix += num;
        min_prefix = min(min_prefix, prefix);
    }
    return min_prefix < 0 ? -min_prefix : 0;
}
```
We initialize two variables `min_prefix` and `prefix` both set to 0. We iterate over the elements in the `nums` array, adding each element to the `prefix`. At each iteration, we compare and store the minimum value between `min_prefix` and `prefix`.

After the loop, we check if `min_prefix` is less than 0. If it is, return the negation of `min_prefix`. Otherwise, return 0.

The logic behind this algorithm is to find the minimum prefix sum that appears in the array. If this minimum prefix sum is negative, we need to perform operations to "shift" the array values so that the minimum prefix sum becomes non-negative. The minimum number of operations required to do this is equal to the absolute value of the minimum prefix sum found. If the minimum prefix sum is non-negative, there is no need to perform any operations.

## A solution in Python

```python
def min_operations(nums):
    min_prefix = 0
    prefix = 0
    for num in nums:
        prefix += num
        min_prefix = min(min_prefix, prefix)
    return -min_prefix if min_prefix < 0 else 0
```
We initialize two variables `min_prefix` and `prefix` both set to 0. We iterate over the elements in the `nums` array, adding each element to the `prefix`. At each iteration, we compare and store the minimum value between `min_prefix` and `prefix`.

After the loop, we check if `min_prefix` is less than 0. If it is, return the negation of `min_prefix`. Otherwise, return 0.

The logic behind this algorithm is to find the minimum prefix sum that appears in the array. If this minimum prefix sum is negative, we need to perform operations to "shift" the array values so that the minimum prefix sum becomes non-negative. The minimum number of operations required to do this is equal to the absolute value of the minimum prefix sum found. If the minimum prefix sum is non-negative, there is no need to perform any operations.

## A solution in Javascript

```javascript
function minOperations(nums) {
    let minPrefix = 0;
    let prefix = 0;
    for (let num of nums) {
        prefix += num;
        minPrefix = Math.min(minPrefix, prefix);
    }
    return minPrefix < 0 ? -minPrefix : 0;
}
```
We initialize two variables `min_prefix` and `prefix` both set to 0. We iterate over the elements in the `nums` array, adding each element to the `prefix`. At each iteration, we compare and store the minimum value between `min_prefix` and `prefix`.

After the loop, we check if `min_prefix` is less than 0. If it is, return the negation of `min_prefix`. Otherwise, return 0.

The logic behind this algorithm is to find the minimum prefix sum that appears in the array. If this minimum prefix sum is negative, we need to perform operations to "shift" the array values so that the minimum prefix sum becomes non-negative. The minimum number of operations required to do this is equal to the absolute value of the minimum prefix sum found. If the minimum prefix sum is non-negative, there is no need to perform any operations.


# K Items With the Maximum Sum

- slug: k-items-with-the-maximum-sum
- difficulty: Easy

There is a bag that consists of items, each item has a number `1`, `0`, or `-1` written on it.

You are given four **non-negative** integers `numOnes`, `numZeros`, `numNegOnes`, and `k`.

The bag initially contains:

*   `numOnes` items with `1`s written on them.
*   `numZeroes` items with `0`s written on them.
*   `numNegOnes` items with `-1`s written on them.

We want to pick exactly `k` items among the available items. Return _the **maximum** possible sum of numbers written on the items_.

**Example 1:**

**Input:** numOnes = 3, numZeros = 2, numNegOnes = 0, k = 2
**Output:** 2
**Explanation:** We have a bag of items with numbers written on them {1, 1, 1, 0, 0}. We take 2 items with 1 written on them and get a sum in a total of 2.
It can be proven that 2 is the maximum possible sum.

**Example 2:**

**Input:** numOnes = 3, numZeros = 2, numNegOnes = 0, k = 4
**Output:** 3
**Explanation:** We have a bag of items with numbers written on them {1, 1, 1, 0, 0}. We take 3 items with 1 written on them, and 1 item with 0 written on it, and get a sum in a total of 3.
It can be proven that 3 is the maximum possible sum.

**Constraints:**

*   `0 <= numOnes, numZeros, numNegOnes <= 50`
*   `0 <= k <= numOnes + numZeros + numNegOnes`

## A solution in Java

```java
public int maxSum(int numOnes, int numZeros, int numNegOnes, int k) {
    int maxSum = 0;
    for (int i = 0; i <= k; ++i) {
        int ones = Math.min(i, numOnes);
        int negOnes = Math.min(k - i, numNegOnes);
        maxSum = Math.max(maxSum, ones - negOnes);
    }
    return maxSum;
}
```
We want to find the maximum sum of __k__ items that can be picked from the given bag. Iterate through __0__ to __k__, and pick the minimum between __i__ and __numOnes__ as the count of ones, and pick the minimum between __k-i__ and __numNegOnes__ as the count of -1s. Since 1 - (-1) = 2, every 1 combined with a -1 will increase max_sum by 2. Calculate the maximum between the current `max_sum` and the sum of ones minus negative ones for each iteration. Return the final `max_sum` after the loop has finished, which will have the maximum possible sum of items.

## A solution in C++

```cpp
int maxSum(int numOnes, int numZeros, int numNegOnes, int k) {
    int max_sum = 0;
    for (int i = 0; i <= k; ++i) {
        int ones = min(i, numOnes);
        int neg_ones = min(k - i, numNegOnes);
        max_sum = max(max_sum, ones - neg_ones);
    }
    return max_sum;
}
```
We want to find the maximum sum of __k__ items that can be picked from the given bag. Iterate through __0__ to __k__, and pick the minimum between __i__ and __numOnes__ as the count of ones, and pick the minimum between __k-i__ and __numNegOnes__ as the count of -1s. Since 1 - (-1) = 2, every 1 combined with a -1 will increase max_sum by 2. Calculate the maximum between the current `max_sum` and the sum of ones minus negative ones for each iteration. Return the final `max_sum` after the loop has finished, which will have the maximum possible sum of items.

## A solution in Python

```python
def max_sum(numOnes: int, numZeros: int, numNegOnes: int, k: int) -> int:
    max_sum = 0
    for i in range(k + 1):
        ones = min(i, numOnes)
        neg_ones = min(k - i, numNegOnes)
        max_sum = max(max_sum, ones - neg_ones)
    return max_sum
```
We want to find the maximum sum of __k__ items that can be picked from the given bag. Iterate through __0__ to __k__, and pick the minimum between __i__ and __numOnes__ as the count of ones, and pick the minimum between __k-i__ and __numNegOnes__ as the count of -1s. Since 1 - (-1) = 2, every 1 combined with a -1 will increase max_sum by 2. Calculate the maximum between the current `max_sum` and the sum of ones minus negative ones for each iteration. Return the final `max_sum` after the loop has finished, which will have the maximum possible sum of items.

## A solution in Javascript

```javascript
function maxSum(numOnes, numZeros, numNegOnes, k) {
    let maxSum = 0;
    for (let i = 0; i <= k; ++i) {
        let ones = Math.min(i, numOnes);
        let negOnes = Math.min(k - i, numNegOnes);
        maxSum = Math.max(maxSum, ones - negOnes);
    }
    return maxSum;
}
```
We want to find the maximum sum of __k__ items that can be picked from the given bag. Iterate through __0__ to __k__, and pick the minimum between __i__ and __numOnes__ as the count of ones, and pick the minimum between __k-i__ and __numNegOnes__ as the count of -1s. Since 1 - (-1) = 2, every 1 combined with a -1 will increase max_sum by 2. Calculate the maximum between the current `max_sum` and the sum of ones minus negative ones for each iteration. Return the final `max_sum` after the loop has finished, which will have the maximum possible sum of items.


# Prime Subtraction Operation

- slug: prime-subtraction-operation
- difficulty: Medium

You are given a **0-indexed** integer array `nums` of length `n`.

You can perform the following operation as many times as you want:

*   Pick an index `i` that you haven't picked before, and pick a prime `p` **strictly less than** `nums[i]`, then subtract `p` from `nums[i]`.

Return _true if you can make `nums` a strictly increasing array using the above operation and false otherwise._

A **strictly increasing array** is an array whose each element is strictly greater than its preceding element.

**Example 1:**

**Input:** nums = \[4,9,6,10\]
**Output:** true
**Explanation:** In the first operation: Pick i = 0 and p = 3, and then subtract 3 from nums\[0\], so that nums becomes \[1,9,6,10\].
In the second operation: i = 1, p = 7, subtract 7 from nums\[1\], so nums becomes equal to \[1,2,6,10\].
After the second operation, nums is sorted in strictly increasing order, so the answer is true.

**Example 2:**

**Input:** nums = \[6,8,11,12\]
**Output:** true
**Explanation:** Initially nums is sorted in strictly increasing order, so we don't need to make any operations.

**Example 3:**

**Input:** nums = \[5,8,3\]
**Output:** false
**Explanation:** It can be proven that there is no way to perform operations to make nums sorted in strictly increasing order, so the answer is false.

**Constraints:**

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

## A solution in Java

```java
public boolean strictlyIncreasingArray(int[] nums) {
    for (int i = 0; i < nums.length - 1; ++i) {
        nums[i] -= i;
        if (nums[i] >= nums[i + 1]) {
            return false;
        }
    }
    return true;
}
```
The algorithm iterates through the array, checking if the current element `nums[i]` is strictly less than the next element `nums[i+1]`. Before the comparison, the algorithm subtracts the index `i` from the current element `nums[i]`. This is because, in the prime subtraction operation, an index can only be chosen once, so it essentially checks if the array can be made strictly increasing after applying the prime subtraction to the current index. If for any index `i`, the current element `nums[i]` is greater than or equal to the next element `nums[i+1]`, the function will return `false`, indicating that the array cannot be made strictly increasing.

If the loop completes without finding any such index, the function returns `true`, which shows that the given array can be made strictly increasing through the prime subtraction operation as described above.

## A solution in C++

```cpp
#include <vector>

bool strictlyIncreasingArray(std::vector<int>& nums) {
    for (int i = 0; i < nums.size() - 1; ++i) {
        nums[i] -= i;
        if (nums[i] >= nums[i + 1]) {
            return false;
        }
    }
    return true;
}
```
The algorithm iterates through the array, checking if the current element `nums[i]` is strictly less than the next element `nums[i+1]`. Before the comparison, the algorithm subtracts the index `i` from the current element `nums[i]`. This is because, in the prime subtraction operation, an index can only be chosen once, so it essentially checks if the array can be made strictly increasing after applying the prime subtraction to the current index. If for any index `i`, the current element `nums[i]` is greater than or equal to the next element `nums[i+1]`, the function will return `false`, indicating that the array cannot be made strictly increasing.

If the loop completes without finding any such index, the function returns `true`, which shows that the given array can be made strictly increasing through the prime subtraction operation as described above.

## A solution in Python

```python
def strictlyIncreasingArray(nums):
    for i in range(len(nums) - 1):
        nums[i] -= i
        if nums[i] >= nums[i + 1]:
            return False
    return True
```
The algorithm iterates through the array, checking if the current element `nums[i]` is strictly less than the next element `nums[i+1]`. Before the comparison, the algorithm subtracts the index `i` from the current element `nums[i]`. This is because, in the prime subtraction operation, an index can only be chosen once, so it essentially checks if the array can be made strictly increasing after applying the prime subtraction to the current index. If for any index `i`, the current element `nums[i]` is greater than or equal to the next element `nums[i+1]`, the function will return `false`, indicating that the array cannot be made strictly increasing.

If the loop completes without finding any such index, the function returns `true`, which shows that the given array can be made strictly increasing through the prime subtraction operation as described above.

## A solution in Javascript

```javascript
function strictlyIncreasingArray(nums) {
    for (let i = 0; i < nums.length - 1; ++i) {
        nums[i] -= i;
        if (nums[i] >= nums[i + 1]) {
            return false;
        }
    }
    return true;
}
```
The algorithm iterates through the array, checking if the current element `nums[i]` is strictly less than the next element `nums[i+1]`. Before the comparison, the algorithm subtracts the index `i` from the current element `nums[i]`. This is because, in the prime subtraction operation, an index can only be chosen once, so it essentially checks if the array can be made strictly increasing after applying the prime subtraction to the current index. If for any index `i`, the current element `nums[i]` is greater than or equal to the next element `nums[i+1]`, the function will return `false`, indicating that the array cannot be made strictly increasing.

If the loop completes without finding any such index, the function returns `true`, which shows that the given array can be made strictly increasing through the prime subtraction operation as described above.


# Minimum Operations to Make All Array Elements Equal

- slug: minimum-operations-to-make-all-array-elements-equal
- difficulty: Medium

You are given an array `nums` consisting of positive integers.

You are also given an integer array `queries` of size `m`. For the `ith` query, you want to make all of the elements of `nums` equal to `queries[i]`. You can perform the following operation on the array **any** number of times:

*   **Increase** or **decrease** an element of the array by `1`.

Return _an array_ `answer` _of size_ `m` _where_ `answer[i]` _is the **minimum** number of operations to make all elements of_ `nums` _equal to_ `queries[i]`.

**Note** that after each query the array is reset to its original state.

**Example 1:**

**Input:** nums = \[3,1,6,8\], queries = \[1,5\]
**Output:** \[14,10\]
**Explanation:** For the first query we can do the following operations:
- Decrease nums\[0\] 2 times, so that nums = \[1,1,6,8\].
- Decrease nums\[2\] 5 times, so that nums = \[1,1,1,8\].
- Decrease nums\[3\] 7 times, so that nums = \[1,1,1,1\].
So the total number of operations for the first query is 2 + 5 + 7 = 14.
For the second query we can do the following operations:
- Increase nums\[0\] 2 times, so that nums = \[5,1,6,8\].
- Increase nums\[1\] 4 times, so that nums = \[5,5,6,8\].
- Decrease nums\[2\] 1 time, so that nums = \[5,5,5,8\].
- Decrease nums\[3\] 3 times, so that nums = \[5,5,5,5\].
So the total number of operations for the second query is 2 + 4 + 1 + 3 = 10.

**Example 2:**

**Input:** nums = \[2,9,6,3\], queries = \[10\]
**Output:** \[20\]
**Explanation:** We can increase each value in the array to 10. The total number of operations will be 8 + 1 + 4 + 7 = 20.

**Constraints:**

*   `n == nums.length`
*   `m == queries.length`
*   `1 <= n, m <= 105`
*   `1 <= nums[i], queries[i] <= 109`

## A solution in Java

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

public List<Integer> minOperations(int[] nums, int[] queries) {
    List<Integer> answer = new ArrayList<>();
    for (int query : queries) {
        int operations = 0;
        for (int num : nums) {
            operations += Math.abs(num - query);
        }
        answer.add(operations);
    }
    return answer;
}
```
The algorithm iterates through each `query` in the `queries` array. For each `query`, it then iterates through each element in the `nums` array and calculates the absolute difference between `query` and the element. The absolute difference represents the minimum number of operations required to make the element equal to the `query`. The total number of operations for that `query` is the sum of the absolute differences for each element in `nums`. This process is repeated for all `queries`, and an array containing the total number of operations for each `query` is returned.

## A solution in C++

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

vector<int> min_operations(vector<int>& nums, vector<int>& queries) {
    vector<int> answer;
    for (int query : queries) {
        int operations = 0;
        for (int num : nums) {
            operations += abs(num - query);
        }
        answer.push_back(operations);
    }
    return answer;
}
```
The algorithm iterates through each `query` in the `queries` array. For each `query`, it then iterates through each element in the `nums` array and calculates the absolute difference between `query` and the element. The absolute difference represents the minimum number of operations required to make the element equal to the `query`. The total number of operations for that `query` is the sum of the absolute differences for each element in `nums`. This process is repeated for all `queries`, and an array containing the total number of operations for each `query` is returned.

## A solution in Python

```python
from typing import List

def min_operations(nums: List[int], queries: List[int]) -> List[int]:
    answer = []
    for query in queries:
        operations = 0
        for num in nums:
            operations += abs(num - query)
        answer.append(operations)
    return answer
```
The algorithm iterates through each `query` in the `queries` array. For each `query`, it then iterates through each element in the `nums` array and calculates the absolute difference between `query` and the element. The absolute difference represents the minimum number of operations required to make the element equal to the `query`. The total number of operations for that `query` is the sum of the absolute differences for each element in `nums`. This process is repeated for all `queries`, and an array containing the total number of operations for each `query` is returned.

## A solution in Javascript

```javascript
function minOperations(nums, queries) {
    let answer = [];
    for (let query of queries) {
        let operations = 0;
        for (let num of nums) {
            operations += Math.abs(num - query);
        }
        answer.push(operations);
    }
    return answer;
}
```
The algorithm iterates through each `query` in the `queries` array. For each `query`, it then iterates through each element in the `nums` array and calculates the absolute difference between `query` and the element. The absolute difference represents the minimum number of operations required to make the element equal to the `query`. The total number of operations for that `query` is the sum of the absolute differences for each element in `nums`. This process is repeated for all `queries`, and an array containing the total number of operations for each `query` is returned.


# Collect Coins in a Tree

- slug: collect-coins-in-a-tree
- difficulty: Hard

There exists an undirected and unrooted tree with `n` nodes indexed from `0` to `n - 1`. You are given an integer `n` and a 2D integer array edges of length `n - 1`, where `edges[i] = [ai, bi]` indicates that there is an edge between nodes `ai` and `bi` in the tree. You are also given an array `coins` of size `n` where `coins[i]` can be either `0` or `1`, where `1` indicates the presence of a coin in the vertex `i`.

Initially, you choose to start at any vertex in the tree. Then, you can perform the following operations any number of times:

*   Collect all the coins that are at a distance of at most `2` from the current vertex, or
*   Move to any adjacent vertex in the tree.

Find _the minimum number of edges you need to go through to collect all the coins and go back to the initial vertex_.

Note that if you pass an edge several times, you need to count it into the answer several times.

**Example 1:**

**Input:** coins = \[1,0,0,0,0,1\], edges = \[\[0,1\],\[1,2\],\[2,3\],\[3,4\],\[4,5\]\]
**Output:** 2
**Explanation:** Start at vertex 2, collect the coin at vertex 0, move to vertex 3, collect the coin at vertex 5 then move back to vertex 2.

**Example 2:**

**Input:** coins = \[0,0,0,1,1,0,0,1\], edges = \[\[0,1\],\[0,2\],\[1,3\],\[1,4\],\[2,5\],\[5,6\],\[5,7\]\]
**Output:** 2
**Explanation:** Start at vertex 0, collect the coins at vertices 4 and 3, move to vertex 2,  collect the coin at vertex 7, then move back to vertex 0.

**Constraints:**

*   `n == coins.length`
*   `1 <= n <= 3 * 104`
*   `0 <= coins[i] <= 1`
*   `edges.length == n - 1`
*   `edges[i].length == 2`
*   `0 <= ai, bi < n`
*   `ai != bi`
*   `edges` represents a valid tree.

## A solution in Java

```java
import java.util.*;

public int minEdgesToCollectCoins(int[] coins, int[][] edges) {
    int n = coins.length;
    List<List<Integer>> adj = new ArrayList<>();
    for (int i = 0; i < n; i++) {
        adj.add(new ArrayList<>());
    }
    for (int[] edge : edges) {
        adj.get(edge[0]).add(edge[1]);
        adj.get(edge[1]).add(edge[0]);
    }
    return dfs(adj, coins, 0, -1)[1] / 2;
}

private int[] dfs(List<List<Integer>> adj, int[] coins, int node, int parent) {
    int sum = coins[node], distance = 0;
    for (int neighbor : adj.get(node)) {
        if (neighbor != parent) {
            int[] result = dfs(adj, coins, neighbor, node);
            sum += result[0];
            distance += 2 * result[0] + result[1];
        }
    }
    return new int[] {sum, distance};
}
```
The algorithm starts by constructing an adjacency list `adj` from the input `edges`. Then, it performs a depth-first search (DFS) from the starting vertex (0) by calling the `dfs` function.

The `dfs` function takes the adjacency list `adj`, the `coins` array, the current node `node`, and the parent node `parent` as its arguments. It returns a pair of integers: `(sum_coins, distance)`, where `sum_coins` is the total number of coins in the subtree rooted at the current node, and `distance` is the total distance required to collect all those coins.

In the `dfs` function, we iterate over all the neighbors of the current node. If the neighbor is not the parent, we recursively call `dfs` for that neighbor. For each child, we calculate the total number of coins and the total distance as we did for the parent. Then, we can update the total number of coins and the total distance as follows:

1. Add the number of coins retrieved from the child to the total number of coins.
2. Add twice the number of coins retrieved from the child plus the distance retrieved from the child to the total distance. This is because we need to go back and forth for each child.

Finally, we return the total number of coins and the total distance divided by 2, as each edge is counted twice in the total distance.

## A solution in C++

```cpp
#include <vector>
#include <utility>

using std::vector;
using std::pair;

pair<int, int> dfs(const vector<vector<int>>& adj, const vector<int>& coins, int node, int parent) {
    int sum = coins[node], distance = 0;
    for (int neighbor : adj[node]) {
        if (neighbor != parent) {
            auto result = dfs(adj, coins, neighbor, node);
            sum += result.first;
            distance += 2 * result.first + result.second;
        }
    }
    return {sum, distance};
}

int minEdgesToCollectCoins(const vector<int>& coins, const vector<vector<int>>& edges) {
    int n = coins.size();
    vector<vector<int>> adj(n);
    for (const auto& edge : edges) {
        adj[edge[0]].push_back(edge[1]);
        adj[edge[1]].push_back(edge[0]);
    }
    return dfs(adj, coins, 0, -1).second / 2;
}
```
The algorithm starts by constructing an adjacency list `adj` from the input `edges`. Then, it performs a depth-first search (DFS) from the starting vertex (0) by calling the `dfs` function.

The `dfs` function takes the adjacency list `adj`, the `coins` array, the current node `node`, and the parent node `parent` as its arguments. It returns a pair of integers: `(sum_coins, distance)`, where `sum_coins` is the total number of coins in the subtree rooted at the current node, and `distance` is the total distance required to collect all those coins.

In the `dfs` function, we iterate over all the neighbors of the current node. If the neighbor is not the parent, we recursively call `dfs` for that neighbor. For each child, we calculate the total number of coins and the total distance as we did for the parent. Then, we can update the total number of coins and the total distance as follows:

1. Add the number of coins retrieved from the child to the total number of coins.
2. Add twice the number of coins retrieved from the child plus the distance retrieved from the child to the total distance. This is because we need to go back and forth for each child.

Finally, we return the total number of coins and the total distance divided by 2, as each edge is counted twice in the total distance.

## A solution in Python

```python
from collections import defaultdict

def min_edges_to_collect_coins(coins, edges):
    adj = defaultdict(list)
    for a, b in edges:
        adj[a].append(b)
        adj[b].append(a)
    return dfs(adj, coins, 0, -1)[1] // 2

def dfs(adj, coins, node, parent):
    sum_coins = coins[node]
    distance = 0
    for neighbor in adj[node]:
        if neighbor != parent:
            result = dfs(adj, coins, neighbor, node)
            sum_coins += result[0]
            distance += 2 * result[0] + result[1]
    return (sum_coins, distance)
```
The algorithm starts by constructing an adjacency list `adj` from the input `edges`. Then, it performs a depth-first search (DFS) from the starting vertex (0) by calling the `dfs` function.

The `dfs` function takes the adjacency list `adj`, the `coins` array, the current node `node`, and the parent node `parent` as its arguments. It returns a pair of integers: `(sum_coins, distance)`, where `sum_coins` is the total number of coins in the subtree rooted at the current node, and `distance` is the total distance required to collect all those coins.

In the `dfs` function, we iterate over all the neighbors of the current node. If the neighbor is not the parent, we recursively call `dfs` for that neighbor. For each child, we calculate the total number of coins and the total distance as we did for the parent. Then, we can update the total number of coins and the total distance as follows:

1. Add the number of coins retrieved from the child to the total number of coins.
2. Add twice the number of coins retrieved from the child plus the distance retrieved from the child to the total distance. This is because we need to go back and forth for each child.

Finally, we return the total number of coins and the total distance divided by 2, as each edge is counted twice in the total distance.

## A solution in Javascript

```javascript
function minEdgesToCollectCoins(coins, edges) {
    const adj = new Array(coins.length).fill(null).map(() => []);
    for (let [a, b] of edges) {
        adj[a].push(b);
        adj[b].push(a);
    }
    return dfs(adj, coins, 0, -1)[1] / 2;
}

function dfs(adj, coins, node, parent) {
    let sum_coins = coins[node];
    let distance = 0;
    for (let neighbor of adj[node]) {
        if (neighbor !== parent) {
            let result = dfs(adj, coins, neighbor, node);
            sum_coins += result[0];
            distance += 2 * result[0] + result[1];
        }
    }
    return [sum_coins, distance];
}
```
The algorithm starts by constructing an adjacency list `adj` from the input `edges`. Then, it performs a depth-first search (DFS) from the starting vertex (0) by calling the `dfs` function.

The `dfs` function takes the adjacency list `adj`, the `coins` array, the current node `node`, and the parent node `parent` as its arguments. It returns a pair of integers: `(sum_coins, distance)`, where `sum_coins` is the total number of coins in the subtree rooted at the current node, and `distance` is the total distance required to collect all those coins.

In the `dfs` function, we iterate over all the neighbors of the current node. If the neighbor is not the parent, we recursively call `dfs` for that neighbor. For each child, we calculate the total number of coins and the total distance as we did for the parent. Then, we can update the total number of coins and the total distance as follows:

1. Add the number of coins retrieved from the child to the total number of coins.
2. Add twice the number of coins retrieved from the child plus the distance retrieved from the child to the total distance. This is because we need to go back and forth for each child.

Finally, we return the total number of coins and the total distance divided by 2, as each edge is counted twice in the total distance.