# Path Sum II

- slug: path-sum-ii
- difficulty: Medium

Given the `root` of a binary tree and an integer `targetSum`, return _all **root-to-leaf** paths where the sum of the node values in the path equals_ `targetSum`_. Each path should be returned as a list of the node **values**, not node references_.

A **root-to-leaf** path is a path starting from the root and ending at any leaf node. A **leaf** is a node with no children.

**Example 1:**

**Input:** root = \[5,4,8,11,null,13,4,7,2,null,null,5,1\], targetSum = 22
**Output:** \[\[5,4,11,2\],\[5,8,4,5\]\]
**Explanation:** There are two paths whose sum equals targetSum:
5 + 4 + 11 + 2 = 22
5 + 8 + 4 + 5 = 22

**Example 2:**

**Input:** root = \[1,2,3\], targetSum = 5
**Output:** \[\]

**Example 3:**

**Input:** root = \[1,2\], targetSum = 0
**Output:** \[\]

**Constraints:**

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

## A solution in Java

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

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

public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
    List<List<Integer>> ans = new ArrayList<>();
    List<Integer> current = new ArrayList<>();
    helper(root, targetSum, current, ans);
    return ans;
}

private void helper(TreeNode root, int targetSum, List<Integer> current, List<List<Integer>> ans) {
    if (root == null) return;
    current.add(root.val);
    if (root.left == null && root.right == null && targetSum == root.val) {
        ans.add(new ArrayList<>(current));
    }
    helper(root.left, targetSum - root.val, current, ans);
    helper(root.right, targetSum - root.val, current, ans);
    current.remove(current.size() - 1);
}
```
This algorithm does a Depth First Search (DFS) traversal of the given binary tree. At each recursive call(level), the value of the current node is subtracted from the targetSum. When a leaf node is reached, the targetSum is compared with the current node value. If they are equal, then the current path of nodes is added to the result vector (ans). After traversal finishes, ans is returned which contains all the paths with the required sum.

## A solution in C++

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

void helper(TreeNode* root, int targetSum, vector<int>& current, vector<vector<int>>& ans) {
    if (!root) return;
    current.push_back(root->val);
    if (!root->left && !root->right && targetSum == root->val) {
        ans.push_back(current);
    }
    helper(root->left, targetSum - root->val, current, ans);
    helper(root->right, targetSum - root->val, current, ans);
    current.pop_back();
}

vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
    vector<vector<int>> ans;
    vector<int> current;
    helper(root, targetSum, current, ans);
    return ans;
}
```
This algorithm does a Depth First Search (DFS) traversal of the given binary tree. At each recursive call(level), the value of the current node is subtracted from the targetSum. When a leaf node is reached, the targetSum is compared with the current node value. If they are equal, then the current path of nodes is added to the result vector (ans). After traversal finishes, ans is returned which contains all the paths with the required sum.

## A solution in Python

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

def pathSum(root, targetSum):
    def helper(root, targetSum, current, ans):
        if not root:
            return
        current.append(root.val)
        if not root.left and not root.right and targetSum == root.val:
            ans.append(current[:])
        helper(root.left, targetSum - root.val, current, ans)
        helper(root.right, targetSum - root.val, current, ans)
        current.pop()

    ans = []
    helper(root, targetSum, [], ans)
    return ans
```
This algorithm does a Depth First Search (DFS) traversal of the given binary tree. At each recursive call(level), the value of the current node is subtracted from the targetSum. When a leaf node is reached, the targetSum is compared with the current node value. If they are equal, then the current path of nodes is added to the result vector (ans). After traversal finishes, ans is returned which contains all the paths with the required sum.

## A solution in Javascript

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

function pathSum(root, targetSum) {
    const ans = [];
    const helper = (root, targetSum, current) => {
        if (!root) return;
        current.push(root.val);
        if (!root.left && !root.right && targetSum === root.val) {
            ans.push([...current]);
        }
        helper(root.left, targetSum - root.val, current);
        helper(root.right, targetSum - root.val, current);
        current.pop();
    };

    helper(root, targetSum, []);
    return ans;
}
```
This algorithm does a Depth First Search (DFS) traversal of the given binary tree. At each recursive call(level), the value of the current node is subtracted from the targetSum. When a leaf node is reached, the targetSum is compared with the current node value. If they are equal, then the current path of nodes is added to the result vector (ans). After traversal finishes, ans is returned which contains all the paths with the required sum.


# Flatten Binary Tree to Linked List

- slug: flatten-binary-tree-to-linked-list
- difficulty: Medium

Given the `root` of a binary tree, flatten the tree into a "linked list ":

*   The "linked list " should use the same `TreeNode` class where the `right` child pointer points to the next node in the list and the `left` child pointer is always `null`.
*   The "linked list " should be in the same order as a [**pre-order** **traversal**](https://en.wikipedia.org/wiki/Tree_traversal#Pre-order,_NLR) of the binary tree.

**Example 1:**

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

**Example 2:**

**Input:** root = \[\]
**Output:** \[\]

**Example 3:**

**Input:** root = \[0\]
**Output:** \[0\]

**Constraints:**

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

**Follow up:** Can you flatten the tree in-place (with `O(1)` extra space)?

## A solution in Java

```java
public void flatten(TreeNode root) {
    if (root == null) return;
    flatten(root.left);
    flatten(root.right);
    if (root.left != null) {
        TreeNode temp = root.right;
        root.right = root.left;
        root.left = null;
        while (root.right != null) root = root.right;
        root.right = temp;
    }
}
```
1. Check if the root is null, then return.
2. Recursively flatten the left and right subtrees.
3. If there is a left subtree, temporarily store the right subtree in a variable `temp`.
4. Make the right subtree the left subtree and set the left subtree to null.
5. Move to the rightmost node in the new right subtree.
6. Set the right node of the rightmost node to the `temp` variable.
7. The tree will now be flattened into a "linked list" where all nodes are right child nodes.

## A solution in C++

```cpp
void flatten(TreeNode* root) {
    if (!root) return;
    flatten(root->left);
    flatten(root->right);
    if (root->left) {
        TreeNode* temp = root->right;
        root->right = root->left;
        root->left = nullptr;
        while (root->right) root = root->right;
        root->right = temp;
    }
}
```
1. Check if the root is null, then return.
2. Recursively flatten the left and right subtrees.
3. If there is a left subtree, temporarily store the right subtree in a variable `temp`.
4. Make the right subtree the left subtree and set the left subtree to null.
5. Move to the rightmost node in the new right subtree.
6. Set the right node of the rightmost node to the `temp` variable.
7. The tree will now be flattened into a "linked list" where all nodes are right child nodes.

## A solution in Python

```python
def flatten(root):
    if not root:
        return
    flatten(root.left)
    flatten(root.right)
    if root.left:
        temp = root.right
        root.right = root.left
        root.left = None
        while root.right:
            root = root.right
        root.right = temp
```
1. Check if the root is null, then return.
2. Recursively flatten the left and right subtrees.
3. If there is a left subtree, temporarily store the right subtree in a variable `temp`.
4. Make the right subtree the left subtree and set the left subtree to null.
5. Move to the rightmost node in the new right subtree.
6. Set the right node of the rightmost node to the `temp` variable.
7. The tree will now be flattened into a "linked list" where all nodes are right child nodes.

## A solution in Javascript

```javascript
function flatten(root) {
    if (!root) return;
    flatten(root.left);
    flatten(root.right);
    if (root.left) {
        let temp = root.right;
        root.right = root.left;
        root.left = null;
        while (root.right) root = root.right;
        root.right = temp;
    }
}
```
1. Check if the root is null, then return.
2. Recursively flatten the left and right subtrees.
3. If there is a left subtree, temporarily store the right subtree in a variable `temp`.
4. Make the right subtree the left subtree and set the left subtree to null.
5. Move to the rightmost node in the new right subtree.
6. Set the right node of the rightmost node to the `temp` variable.
7. The tree will now be flattened into a "linked list" where all nodes are right child nodes.


# Distinct Subsequences

- slug: distinct-subsequences
- difficulty: Hard

Given two strings `s` and `t`, return _the number of distinct_ **_subsequences_** _of_ `s` _which equals_ `t`.

The test cases are generated so that the answer fits on a 32-bit signed integer.

**Example 1:**

**Input:** s =  "rabbbit ", t =  "rabbit "
**Output:** 3
**Explanation:**
As shown below, there are 3 ways you can generate  "rabbit " from s.
`**rabb**b**it**`
`**ra**b**bbit**`
`**rab**b**bit**`

**Example 2:**

**Input:** s =  "babgbag ", t =  "bag "
**Output:** 5
**Explanation:**
As shown below, there are 5 ways you can generate  "bag " from s.
`**ba**b**g**bag`
`**ba**bgba**g**`
`**b**abgb**ag**`
`ba**b**gb**ag**`
`babg**bag**`

**Constraints:**

*   `1 <= s.length, t.length <= 1000`
*   `s` and `t` consist of English letters.

## A solution in Java

```java
public int numDistinct(String s, String t) {
    int m = s.length(), n = t.length();
    int[][] dp = new int[m + 1][n + 1];

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

    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (s.charAt(i - 1) == t.charAt(j - 1)) {
                dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
            } else {
                dp[i][j] = dp[i - 1][j];
            }
        }
    }

    return dp[m][n];
}
```
The algorithm uses dynamic programming to count the number of distinct subsequences. The main idea is to create a 2D table `dp` where `dp[i][j]` represents the number of distinct subsequences of the first `i` characters in string `s` that equal the first `j` characters in string `t`.

The algorithm initializes the first row of the table since there are no subsequences of an empty string. Then, it iterates through each character in both strings, comparing for equality. If the characters are equal, the value of `dp[i][j]` is updated to `dp[i - 1][j - 1] + dp[i - 1][j]`. If the characters are not equal, the value of `dp[i][j]` is updated to `dp[i - 1][j]`. After filling the 2D table, the value at `dp[m][n]` represents the total number of distinct subsequences of `s` that equal `t`.

## A solution in C++

```cpp
int numDistinct(string s, string t) {
    int m = s.size(), n = t.size();
    vector<vector<unsigned int>> dp(m + 1, vector<unsigned int>(n + 1, 0));

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

    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (s[i - 1] == t[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
            } else {
                dp[i][j] = dp[i - 1][j];
            }
        }
    }

    return dp[m][n];
}
```
The algorithm uses dynamic programming to count the number of distinct subsequences. The main idea is to create a 2D table `dp` where `dp[i][j]` represents the number of distinct subsequences of the first `i` characters in string `s` that equal the first `j` characters in string `t`.

The algorithm initializes the first row of the table since there are no subsequences of an empty string. Then, it iterates through each character in both strings, comparing for equality. If the characters are equal, the value of `dp[i][j]` is updated to `dp[i - 1][j - 1] + dp[i - 1][j]`. If the characters are not equal, the value of `dp[i][j]` is updated to `dp[i - 1][j]`. After filling the 2D table, the value at `dp[m][n]` represents the total number of distinct subsequences of `s` that equal `t`.

## A solution in Python

```python
def numDistinct(s: str, t: str) -> int:
    m, n = len(s), len(t)
    dp = [[0] * (n + 1) for _ in range(m + 1)]

    for i in range(m + 1):
        dp[i][0] = 1

    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if s[i - 1] == t[j - 1]:
                dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]
            else:
                dp[i][j] = dp[i - 1][j]

    return dp[m][n]
```
The algorithm uses dynamic programming to count the number of distinct subsequences. The main idea is to create a 2D table `dp` where `dp[i][j]` represents the number of distinct subsequences of the first `i` characters in string `s` that equal the first `j` characters in string `t`.

The algorithm initializes the first row of the table since there are no subsequences of an empty string. Then, it iterates through each character in both strings, comparing for equality. If the characters are equal, the value of `dp[i][j]` is updated to `dp[i - 1][j - 1] + dp[i - 1][j]`. If the characters are not equal, the value of `dp[i][j]` is updated to `dp[i - 1][j]`. After filling the 2D table, the value at `dp[m][n]` represents the total number of distinct subsequences of `s` that equal `t`.

## A solution in Javascript

```javascript
function numDistinct(s, t) {
    const m = s.length, n = t.length;
    const dp = Array.from({length: m + 1}, () => Array(n + 1).fill(0));

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

    for (let i = 1; i <= m; i++) {
        for (let j = 1; j <= n; j++) {
            if (s[i - 1] === t[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
            } else {
                dp[i][j] = dp[i - 1][j];
            }
        }
    }

    return dp[m][n];
}
```
The algorithm uses dynamic programming to count the number of distinct subsequences. The main idea is to create a 2D table `dp` where `dp[i][j]` represents the number of distinct subsequences of the first `i` characters in string `s` that equal the first `j` characters in string `t`.

The algorithm initializes the first row of the table since there are no subsequences of an empty string. Then, it iterates through each character in both strings, comparing for equality. If the characters are equal, the value of `dp[i][j]` is updated to `dp[i - 1][j - 1] + dp[i - 1][j]`. If the characters are not equal, the value of `dp[i][j]` is updated to `dp[i - 1][j]`. After filling the 2D table, the value at `dp[m][n]` represents the total number of distinct subsequences of `s` that equal `t`.


# Populating Next Right Pointers in Each Node

- slug: populating-next-right-pointers-in-each-node
- difficulty: Medium

You are given a **perfect binary tree** where all leaves are on the same level, and every parent has two children. The binary tree has the following definition:

struct Node {
  int val;
  Node \*left;
  Node \*right;
  Node \*next;
}

Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to `NULL`.

Initially, all next pointers are set to `NULL`.

**Example 1:**

**Input:** root = \[1,2,3,4,5,6,7\]
**Output:** \[1,#,2,3,#,4,5,6,7,#\]
**Explanation:** Given the above perfect binary tree (Figure A), your function should populate each next pointer to point to its next right node, just like in Figure B. The serialized output is in level order as connected by the next pointers, with '#' signifying the end of each level.

**Example 2:**

**Input:** root = \[\]
**Output:** \[\]

**Constraints:**

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

**Follow-up:**

*   You may only use constant extra space.
*   The recursive approach is fine. You may assume implicit stack space does not count as extra space for this problem.

## A solution in Java

```java
public void connect(TreeLinkNode root) {
    if (root == null || root.left == null) return;
    root.left.next = root.right;
    if (root.next != null) {
        root.right.next = root.next.left;
    }
    connect(root.left);
    connect(root.right);
}
```
The algorithm to populate the next pointers is a simple modification of the pre-order traversal of the binary tree. We start with the root, and for each node, we check if it has left and right children. If so, we set the left child's next pointer to point to the right child. If the current node's next pointer is not null, we set its right child's next pointer to the left child of its next node. Finally, we recursively call the function on the left and right children.

## A solution in C++

```cpp
void connect(Node* root) {
    if (!root) return;
    if (root->left) {
        root->left->next = root->right;
        if (root->next) {
            root->right->next = root->next->left;
        }
    }
    connect(root->left);
    connect(root->right);
}
```
The algorithm to populate the next pointers is a simple modification of the pre-order traversal of the binary tree. We start with the root, and for each node, we check if it has left and right children. If so, we set the left child's next pointer to point to the right child. If the current node's next pointer is not null, we set its right child's next pointer to the left child of its next node. Finally, we recursively call the function on the left and right children.

## A solution in Python

```python
def connect(self, root: 'Node') -> 'Node':
    if not root or not root.left:
        return root
    root.left.next = root.right
    if root.next:
        root.right.next = root.next.left
    self.connect(root.left)
    self.connect(root.right)
    return root
```
The algorithm to populate the next pointers is a simple modification of the pre-order traversal of the binary tree. We start with the root, and for each node, we check if it has left and right children. If so, we set the left child's next pointer to point to the right child. If the current node's next pointer is not null, we set its right child's next pointer to the left child of its next node. Finally, we recursively call the function on the left and right children.

## A solution in Javascript

```javascript
function connect(root) {
    if (root === null || root.left === null) return root;
    root.left.next = root.right;
    if (root.next !== null) {
        root.right.next = root.next.left;
    }
    connect(root.left);
    connect(root.right);
    return root;
}
```
The algorithm to populate the next pointers is a simple modification of the pre-order traversal of the binary tree. We start with the root, and for each node, we check if it has left and right children. If so, we set the left child's next pointer to point to the right child. If the current node's next pointer is not null, we set its right child's next pointer to the left child of its next node. Finally, we recursively call the function on the left and right children.


# Populating Next Right Pointers in Each Node II

- slug: populating-next-right-pointers-in-each-node-ii
- difficulty: Medium

Given a binary tree

struct Node {
  int val;
  Node \*left;
  Node \*right;
  Node \*next;
}

Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to `NULL`.

Initially, all next pointers are set to `NULL`.

**Example 1:**

**Input:** root = \[1,2,3,4,5,null,7\]
**Output:** \[1,#,2,3,#,4,5,7,#\]
**Explanation:** Given the above binary tree (Figure A), your function should populate each next pointer to point to its next right node, just like in Figure B. The serialized output is in level order as connected by the next pointers, with '#' signifying the end of each level.

**Example 2:**

**Input:** root = \[\]
**Output:** \[\]

**Constraints:**

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

**Follow-up:**

*   You may only use constant extra space.
*   The recursive approach is fine. You may assume implicit stack space does not count as extra space for this problem.

## A solution in Java

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

class Node {
    public int val;
    public Node left;
    public Node right;
    public Node next;

    public Node(int _val) {
        val = _val;
        left = null;
        right = null;
        next = null;
    }
}

public Node connect(Node root) {
    if (root == null) return null;

    Queue<Node> queue = new LinkedList<>();
    queue.offer(root);

    while(!queue.isEmpty()) {
        int levelSize = queue.size();
        Node prev = null;

        for (int i = 0; i < levelSize; i++) {
            Node currentNode = queue.poll();

            if (prev != null) prev.next = currentNode;
            prev = currentNode;

            if(currentNode.left != null) queue.offer(currentNode.left);
            if(currentNode.right != null) queue.offer(currentNode.right);
        }
    }

    return root;
}
```
The basic idea of the algorithm is to perform level-order traversal (Breadth First Search) on the binary tree. We use a queue to store the nodes in each level. For each level, we iterate through its nodes, update the `next` pointer, and add their children to the end of the queue. The `prev` variable holds the previous node in the current level. The `next` pointer of the `prev` node is updated to the current node. The variable `prev` is then set to the current node. Repeat this process until the queue is empty which means we have visited all the nodes in the tree.

## A solution in C++

```cpp
#include <queue>

class Node {
public:
    int val;
    Node* left;
    Node* right;
    Node* next;

    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
};

Node* connect(Node* root) {
    if (!root) return NULL;

    std::queue<Node*> q;
    q.push(root);

    while (!q.empty()) {
        int levelSize = q.size();
        Node* prev = NULL;

        for (int i = 0; i < levelSize; ++i) {
            Node* currentNode = q.front();
            q.pop();

            if (prev) prev->next = currentNode;
            prev = currentNode;

            if (currentNode->left) q.push(currentNode->left);
            if (currentNode->right) q.push(currentNode->right);
        }
    }

    return root;
}
```
The basic idea of the algorithm is to perform level-order traversal (Breadth First Search) on the binary tree. We use a queue to store the nodes in each level. For each level, we iterate through its nodes, update the `next` pointer, and add their children to the end of the queue. The `prev` variable holds the previous node in the current level. The `next` pointer of the `prev` node is updated to the current node. The variable `prev` is then set to the current node. Repeat this process until the queue is empty which means we have visited all the nodes in the tree.

## A solution in Python

```python
class Node:
    def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
        self.val = val
        self.left = left
        self.right = right
        self.next = next

def connect(root: 'Node') -> 'Node':
    if not root:
        return None

    q = [root]

    while q:
        level_size = len(q)
        prev = None

        for i in range(level_size):
            current_node = q.pop(0)

            if prev:
                prev.next = current_node
            prev = current_node

            if current_node.left:
                q.append(current_node.left)
            if current_node.right:
                q.append(current_node.right)

    return root
```
The basic idea of the algorithm is to perform level-order traversal (Breadth First Search) on the binary tree. We use a queue to store the nodes in each level. For each level, we iterate through its nodes, update the `next` pointer, and add their children to the end of the queue. The `prev` variable holds the previous node in the current level. The `next` pointer of the `prev` node is updated to the current node. The variable `prev` is then set to the current node. Repeat this process until the queue is empty which means we have visited all the nodes in the tree.

## A solution in Javascript

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

function connect(root) {
    if(!root) {
        return null;
    }

    const queue = [root];

    while(queue.length) {
        let levelSize = queue.length;
        let prev = null;

        for(let i = 0; i < levelSize; i++) {
            let currentNode = queue.shift();

            if(prev) {
                prev.next = currentNode;
            }
            prev = currentNode;

            if(currentNode.left) queue.push(currentNode.left);
            if(currentNode.right) queue.push(currentNode.right);
        }
    }

    return root;
}
```
The basic idea of the algorithm is to perform level-order traversal (Breadth First Search) on the binary tree. We use a queue to store the nodes in each level. For each level, we iterate through its nodes, update the `next` pointer, and add their children to the end of the queue. The `prev` variable holds the previous node in the current level. The `next` pointer of the `prev` node is updated to the current node. The variable `prev` is then set to the current node. Repeat this process until the queue is empty which means we have visited all the nodes in the tree.


# Pascal's Triangle

- slug: pascals-triangle
- difficulty: Easy

Given an integer `numRows`, return the first numRows of **Pascal's triangle**.

In **Pascal's triangle**, each number is the sum of the two numbers directly above it as shown:

**Example 1:**

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

**Example 2:**

**Input:** numRows = 1
**Output:** \[\[1\]\]

**Constraints:**

*   `1 <= numRows <= 30`

## A solution in Java

```java
public List<List<Integer>> generate(int numRows) {
    List<List<Integer>> pascalsTriangle = new ArrayList<>();
    for (int i = 0; i < numRows; i++) {
        List<Integer> row = new ArrayList<>();
        row.add(1);
        for (int j = 1; j < i; j++) {
            row.add(pascalsTriangle.get(i - 1).get(j - 1) + pascalsTriangle.get(i - 1).get(j));
        }
        if (i > 0) row.add(1);
        pascalsTriangle.add(row);
    }
    return pascalsTriangle;
}
```
The algorithm iterates through each row of Pascal's Triangle, from 0 to numRows-1, and generates the corresponding row with the required values based on the row index. For each row, it initializes an array or list, and then sets the first element to 1 (since all rows start with 1).

Next, we iterate from the second element to the (i-1)-th element of the row (i being the row index). Each element (at index j) of the row is set to the sum of the two values positioned just above it in the previous row - these values are available at (i-1, j-1) and (i-1, j) in Pascal's Triangle.

If the current row is not the first row, we add another 1 at the end of the row, since all rows end with 1 (except the very first row).

Finally, we append the row to the resulting Pascal's Triangle structure (list of lists or vector of vectors). After completing the loop, the algorithm returns the Pascal's Triangle structure containing numRows.

## A solution in C++

```cpp
vector<vector<int>> generate(int numRows) {
    vector<vector<int>> pascalsTriangle(numRows);
    for (int i = 0; i < numRows; i++) {
        pascalsTriangle[i].resize(i + 1);
        pascalsTriangle[i][0] = pascalsTriangle[i][i] = 1;
        for (int j = 1; j < i; j++) {
            pascalsTriangle[i][j] = pascalsTriangle[i - 1][j - 1] + pascalsTriangle[i - 1][j];
        }
    }
    return pascalsTriangle;
}
```
The algorithm iterates through each row of Pascal's Triangle, from 0 to numRows-1, and generates the corresponding row with the required values based on the row index. For each row, it initializes an array or list, and then sets the first element to 1 (since all rows start with 1).

Next, we iterate from the second element to the (i-1)-th element of the row (i being the row index). Each element (at index j) of the row is set to the sum of the two values positioned just above it in the previous row - these values are available at (i-1, j-1) and (i-1, j) in Pascal's Triangle.

If the current row is not the first row, we add another 1 at the end of the row, since all rows end with 1 (except the very first row).

Finally, we append the row to the resulting Pascal's Triangle structure (list of lists or vector of vectors). After completing the loop, the algorithm returns the Pascal's Triangle structure containing numRows.

## A solution in Python

```python
def generate(numRows):
    pascalsTriangle = []
    for i in range(numRows):
        row = [1]
        if i > 0:
            for j in range(1, i):
                row.append(pascalsTriangle[i-1][j-1] + pascalsTriangle[i-1][j])
            row.append(1)
        pascalsTriangle.append(row)
    return pascalsTriangle
```
The algorithm iterates through each row of Pascal's Triangle, from 0 to numRows-1, and generates the corresponding row with the required values based on the row index. For each row, it initializes an array or list, and then sets the first element to 1 (since all rows start with 1).

Next, we iterate from the second element to the (i-1)-th element of the row (i being the row index). Each element (at index j) of the row is set to the sum of the two values positioned just above it in the previous row - these values are available at (i-1, j-1) and (i-1, j) in Pascal's Triangle.

If the current row is not the first row, we add another 1 at the end of the row, since all rows end with 1 (except the very first row).

Finally, we append the row to the resulting Pascal's Triangle structure (list of lists or vector of vectors). After completing the loop, the algorithm returns the Pascal's Triangle structure containing numRows.

## A solution in Javascript

```javascript
function generate(numRows) {
    const pascalsTriangle = [];
    for (let i = 0; i < numRows; i++) {
        const row = [1];
        for (let j = 1; j < i; j++) {
            row.push(pascalsTriangle[i - 1][j - 1] + pascalsTriangle[i - 1][j]);
        }
        if (i > 0) row.push(1);
        pascalsTriangle.push(row);
    }
    return pascalsTriangle;
}
```
The algorithm iterates through each row of Pascal's Triangle, from 0 to numRows-1, and generates the corresponding row with the required values based on the row index. For each row, it initializes an array or list, and then sets the first element to 1 (since all rows start with 1).

Next, we iterate from the second element to the (i-1)-th element of the row (i being the row index). Each element (at index j) of the row is set to the sum of the two values positioned just above it in the previous row - these values are available at (i-1, j-1) and (i-1, j) in Pascal's Triangle.

If the current row is not the first row, we add another 1 at the end of the row, since all rows end with 1 (except the very first row).

Finally, we append the row to the resulting Pascal's Triangle structure (list of lists or vector of vectors). After completing the loop, the algorithm returns the Pascal's Triangle structure containing numRows.


# Pascal's Triangle II

- slug: pascals-triangle-ii
- difficulty: Easy

Given an integer `rowIndex`, return the `rowIndexth` (**0-indexed**) row of the **Pascal's triangle**.

In **Pascal's triangle**, each number is the sum of the two numbers directly above it as shown:

**Example 1:**

**Input:** rowIndex = 3
**Output:** \[1,3,3,1\]

**Example 2:**

**Input:** rowIndex = 0
**Output:** \[1\]

**Example 3:**

**Input:** rowIndex = 1
**Output:** \[1,1\]

**Constraints:**

*   `0 <= rowIndex <= 33`

**Follow up:** Could you optimize your algorithm to use only `O(rowIndex)` extra space?

## A solution in Java

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

public List<Integer> getRow(int rowIndex) {
    List<Integer> row = new ArrayList<>();
    for (int i = 0; i <= rowIndex; i++) {
        row.add(1);
        for (int j = i - 1; j > 0; j--) {
            row.set(j, row.get(j) + row.get(j - 1));
        }
    }
    return row;
}
```
The algorithm initializes the row with the given rowIndex size and fills it with 1s. Then, we iterate through the rowIndex and update each entry of the row using the sum of the two numbers directly above it (based on Pascal's triangle property), i.e., row[j] = row[j] + row[j-1]. We get the rowIndexth row of Pascal's triangle once the iterations are completed.

## A solution in C++

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

vector<int> getRow(int rowIndex) {
    vector<int> row(rowIndex + 1, 1);
    for (int i = 1; i <= rowIndex; i++) {
        for (int j = i - 1; j > 0; j--) {
            row[j] += row[j - 1];
        }
    }
    return row;
}
```
The algorithm initializes the row with the given rowIndex size and fills it with 1s. Then, we iterate through the rowIndex and update each entry of the row using the sum of the two numbers directly above it (based on Pascal's triangle property), i.e., row[j] = row[j] + row[j-1]. We get the rowIndexth row of Pascal's triangle once the iterations are completed.

## A solution in Python

```python
def get_row(rowIndex):
    row = [1] * (rowIndex + 1)
    for i in range(1, rowIndex + 1):
        for j in range(i - 1, 0, -1):
            row[j] += row[j - 1]
    return row
```
The algorithm initializes the row with the given rowIndex size and fills it with 1s. Then, we iterate through the rowIndex and update each entry of the row using the sum of the two numbers directly above it (based on Pascal's triangle property), i.e., row[j] = row[j] + row[j-1]. We get the rowIndexth row of Pascal's triangle once the iterations are completed.

## A solution in Javascript

```javascript
function getRow(rowIndex) {
    const row = new Array(rowIndex + 1).fill(1);
    for (let i = 1; i <= rowIndex; i++) {
        for (let j = i - 1; j > 0; j--) {
            row[j] += row[j - 1];
        }
    }
    return row;
}
```
The algorithm initializes the row with the given rowIndex size and fills it with 1s. Then, we iterate through the rowIndex and update each entry of the row using the sum of the two numbers directly above it (based on Pascal's triangle property), i.e., row[j] = row[j] + row[j-1]. We get the rowIndexth row of Pascal's triangle once the iterations are completed.


# Triangle

- slug: triangle
- difficulty: Medium

Given a `triangle` array, return _the minimum path sum from top to bottom_.

For each step, you may move to an adjacent number of the row below. More formally, if you are on index `i` on the current row, you may move to either index `i` or index `i + 1` on the next row.

**Example 1:**

**Input:** triangle = \[\[2\],\[3,4\],\[6,5,7\],\[4,1,8,3\]\]
**Output:** 11
**Explanation:** The triangle looks like:
   2
  3 4
 6 5 7
4 1 8 3
The minimum path sum from top to bottom is 2 + 3 + 5 + 1 = 11 (underlined above).

**Example 2:**

**Input:** triangle = \[\[-10\]\]
**Output:** -10

**Constraints:**

*   `1 <= triangle.length <= 200`
*   `triangle[0].length == 1`
*   `triangle[i].length == triangle[i - 1].length + 1`
*   `-104 <= triangle[i][j] <= 104`

**Follow up:** Could you do this using only `O(n)` extra space, where `n` is the total number of rows in the triangle?

## A solution in Java

```java
public int minimumTotal(List<List<Integer>> triangle) {
    for (int row = triangle.size() - 2; row >= 0; row--) {
        for (int col = 0; col < triangle.get(row).size(); col++) {
            int minSum = Math.min(triangle.get(row + 1).get(col), triangle.get(row + 1).get(col + 1));
            triangle.get(row).set(col, triangle.get(row).get(col) + minSum);
        }
    }
    return triangle.get(0).get(0);
}
```
The algorithm starts from the second last row of the triangle, moving bottom-up. For each number in the current row, we add the minimum adjacent number in the row below it. This is done for all numbers in the current row. Then, we move to the row above and repeat the process. This way, we are calculating the minimum path sum for each number in the triangle until we reach the top. Finally, the minimum path sum from top to bottom can be found in the top-most number (triangle[0][0]) after these operations are complete.

## A solution in C++

```cpp
int minimumTotal(vector<vector<int>>& triangle) {
    for (int row = triangle.size() - 2; row >= 0; row--) {
        for (int col = 0; col < triangle[row].size(); col++) {
            triangle[row][col] += min(triangle[row + 1][col], triangle[row + 1][col + 1]);
        }
    }
    return triangle[0][0];
}
```
The algorithm starts from the second last row of the triangle, moving bottom-up. For each number in the current row, we add the minimum adjacent number in the row below it. This is done for all numbers in the current row. Then, we move to the row above and repeat the process. This way, we are calculating the minimum path sum for each number in the triangle until we reach the top. Finally, the minimum path sum from top to bottom can be found in the top-most number (triangle[0][0]) after these operations are complete.

## A solution in Python

```python
def minimumTotal(triangle):
    for row in range(len(triangle) - 2, -1, -1):
        for col in range(len(triangle[row])):
            triangle[row][col] += min(triangle[row + 1][col], triangle[row + 1][col + 1])
    return triangle[0][0]
```
The algorithm starts from the second last row of the triangle, moving bottom-up. For each number in the current row, we add the minimum adjacent number in the row below it. This is done for all numbers in the current row. Then, we move to the row above and repeat the process. This way, we are calculating the minimum path sum for each number in the triangle until we reach the top. Finally, the minimum path sum from top to bottom can be found in the top-most number (triangle[0][0]) after these operations are complete.

## A solution in Javascript

```javascript
function minimumTotal(triangle) {
    for (let row = triangle.length - 2; row >= 0; row--) {
        for (let col = 0; col < triangle[row].length; col++) {
            triangle[row][col] += Math.min(triangle[row + 1][col], triangle[row + 1][col + 1]);
        }
    }
    return triangle[0][0];
}
```
The algorithm starts from the second last row of the triangle, moving bottom-up. For each number in the current row, we add the minimum adjacent number in the row below it. This is done for all numbers in the current row. Then, we move to the row above and repeat the process. This way, we are calculating the minimum path sum for each number in the triangle until we reach the top. Finally, the minimum path sum from top to bottom can be found in the top-most number (triangle[0][0]) after these operations are complete.


# Best Time to Buy and Sell Stock

- slug: best-time-to-buy-and-sell-stock
- difficulty: Easy

You are given an array `prices` where `prices[i]` is the price of a given stock on the `ith` day.

You want to maximize your profit by choosing a **single day** to buy one stock and choosing a **different day in the future** to sell that stock.

Return _the maximum profit you can achieve from this transaction_. If you cannot achieve any profit, return `0`.

**Example 1:**

**Input:** prices = \[7,1,5,3,6,4\]
**Output:** 5
**Explanation:** Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell.

**Example 2:**

**Input:** prices = \[7,6,4,3,1\]
**Output:** 0
**Explanation:** In this case, no transactions are done and the max profit = 0.

**Constraints:**

*   `1 <= prices.length <= 105`
*   `0 <= prices[i] <= 104`

## A solution in Java

```java
public int maxProfit(int[] prices) {
    int minPrice = Integer.MAX_VALUE;
    int maxProfit = 0;
    for (int price : prices) {
        minPrice = Math.min(minPrice, price);
        maxProfit = Math.max(maxProfit, price - minPrice);
    }
    return maxProfit;
}
```
The algorithm iterates through the input array of prices. We maintain two variables: `minPrice` to track the minimum price encountered up to the current day, and `maxProfit` to track maximum achievable profit.

For each day, we update:
1. `minPrice` by comparing its value with the current day's stock price.
2. `maxProfit` by comparing its value with the difference between the current day's stock price and the minimum stock price encountered so far.

At the end of the iteration, the algorithm returns the value stored in `maxProfit`, which is the maximum possible profit that can be achieved.

## A solution in C++

```cpp
int maxProfit(vector<int>& prices) {
    int minPrice = INT_MAX;
    int maxProfit = 0;
    for (int price : prices) {
        minPrice = min(minPrice, price);
        maxProfit = max(maxProfit, price - minPrice);
    }
    return maxProfit;
}
```
The algorithm iterates through the input array of prices. We maintain two variables: `minPrice` to track the minimum price encountered up to the current day, and `maxProfit` to track maximum achievable profit.

For each day, we update:
1. `minPrice` by comparing its value with the current day's stock price.
2. `maxProfit` by comparing its value with the difference between the current day's stock price and the minimum stock price encountered so far.

At the end of the iteration, the algorithm returns the value stored in `maxProfit`, which is the maximum possible profit that can be achieved.

## A solution in Python

```python
def maxProfit(prices):
    minPrice = float('inf')
    maxProfit = 0
    for price in prices:
        minPrice = min(minPrice, price)
        maxProfit = max(maxProfit, price - minPrice)
    return maxProfit
```
The algorithm iterates through the input array of prices. We maintain two variables: `minPrice` to track the minimum price encountered up to the current day, and `maxProfit` to track maximum achievable profit.

For each day, we update:
1. `minPrice` by comparing its value with the current day's stock price.
2. `maxProfit` by comparing its value with the difference between the current day's stock price and the minimum stock price encountered so far.

At the end of the iteration, the algorithm returns the value stored in `maxProfit`, which is the maximum possible profit that can be achieved.

## A solution in Javascript

```javascript
function maxProfit(prices) {
    let minPrice = Number.MAX_VALUE;
    let maxProfit = 0;
    for (const price of prices) {
        minPrice = Math.min(minPrice, price);
        maxProfit = Math.max(maxProfit, price - minPrice);
    }
    return maxProfit;
}
```
The algorithm iterates through the input array of prices. We maintain two variables: `minPrice` to track the minimum price encountered up to the current day, and `maxProfit` to track maximum achievable profit.

For each day, we update:
1. `minPrice` by comparing its value with the current day's stock price.
2. `maxProfit` by comparing its value with the difference between the current day's stock price and the minimum stock price encountered so far.

At the end of the iteration, the algorithm returns the value stored in `maxProfit`, which is the maximum possible profit that can be achieved.


# Best Time to Buy and Sell Stock II

- slug: best-time-to-buy-and-sell-stock-ii
- difficulty: Medium

You are given an integer array `prices` where `prices[i]` is the price of a given stock on the `ith` day.

On each day, you may decide to buy and/or sell the stock. You can only hold **at most one** share of the stock at any time. However, you can buy it then immediately sell it on the **same day**.

Find and return _the **maximum** profit you can achieve_.

**Example 1:**

**Input:** prices = \[7,1,5,3,6,4\]
**Output:** 7
**Explanation:** Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4.
Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.
Total profit is 4 + 3 = 7.

**Example 2:**

**Input:** prices = \[1,2,3,4,5\]
**Output:** 4
**Explanation:** Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
Total profit is 4.

**Example 3:**

**Input:** prices = \[7,6,4,3,1\]
**Output:** 0
**Explanation:** There is no way to make a positive profit, so we never buy the stock to achieve the maximum profit of 0.

**Constraints:**

*   `1 <= prices.length <= 3 * 104`
*   `0 <= prices[i] <= 104`

## A solution in Java

```java
public int maxProfit(int[] prices) {
    int max_profit = 0;
    for (int i = 1; i < prices.length; i++) {
        if (prices[i] > prices[i - 1]) {
            max_profit += prices[i] - prices[i - 1];
        }
    }
    return max_profit;
}
```
The algorithm loops through the given array of stock prices, starting from the second day. For each day, it checks if the price of the stock is higher than the previous day's price. If so, it calculates the difference between the two prices and adds this profit to the total maximum profit. By doing this, we are considering all the possible profitable transactions and accumulating the maximum profit we can achieve.

This approach has a runtime complexity of O(n), where n is the number of days in the input array.

## A solution in C++

```cpp
int maxProfit(vector<int>& prices) {
    int max_profit = 0;
    for (int i = 1; i < prices.size(); i++) {
        if (prices[i] > prices[i - 1]) {
            max_profit += prices[i] - prices[i - 1];
        }
    }
    return max_profit;
}
```
The algorithm loops through the given array of stock prices, starting from the second day. For each day, it checks if the price of the stock is higher than the previous day's price. If so, it calculates the difference between the two prices and adds this profit to the total maximum profit. By doing this, we are considering all the possible profitable transactions and accumulating the maximum profit we can achieve.

This approach has a runtime complexity of O(n), where n is the number of days in the input array.

## A solution in Python

```python
def max_profit(prices):
    max_profit = 0
    for i in range(1, len(prices)):
        if prices[i] > prices[i - 1]:
            max_profit += prices[i] - prices[i - 1]
    return max_profit
```
The algorithm loops through the given array of stock prices, starting from the second day. For each day, it checks if the price of the stock is higher than the previous day's price. If so, it calculates the difference between the two prices and adds this profit to the total maximum profit. By doing this, we are considering all the possible profitable transactions and accumulating the maximum profit we can achieve.

This approach has a runtime complexity of O(n), where n is the number of days in the input array.

## A solution in Javascript

```javascript
function maxProfit(prices) {
    let max_profit = 0;
    for (let i = 1; i < prices.length; i++) {
        if (prices[i] > prices[i - 1]) {
            max_profit += prices[i] - prices[i - 1];
        }
    }
    return max_profit;
}
```
The algorithm loops through the given array of stock prices, starting from the second day. For each day, it checks if the price of the stock is higher than the previous day's price. If so, it calculates the difference between the two prices and adds this profit to the total maximum profit. By doing this, we are considering all the possible profitable transactions and accumulating the maximum profit we can achieve.

This approach has a runtime complexity of O(n), where n is the number of days in the input array.


# Best Time to Buy and Sell Stock III

- slug: best-time-to-buy-and-sell-stock-iii
- difficulty: Hard

You are given an array `prices` where `prices[i]` is the price of a given stock on the `ith` day.

Find the maximum profit you can achieve. You may complete **at most two transactions**.

**Note:** You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).

**Example 1:**

**Input:** prices = \[3,3,5,0,0,3,1,4\]
**Output:** 6
**Explanation:** Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3.

**Example 2:**

**Input:** prices = \[1,2,3,4,5\]
**Output:** 4
**Explanation:** Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are engaging multiple transactions at the same time. You must sell before buying again.

**Example 3:**

**Input:** prices = \[7,6,4,3,1\]
**Output:** 0
**Explanation:** In this case, no transaction is done, i.e. max profit = 0.

**Constraints:**

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

## A solution in Java

```java
public int maxProfit(int[] prices) {
    int buy1 = Integer.MAX_VALUE, buy2 = Integer.MAX_VALUE;
    int profit1 = 0, profit2 = 0;

    for (int price : prices) {
        buy1 = Math.min(buy1, price);
        profit1 = Math.max(profit1, price - buy1);
        buy2 = Math.min(buy2, price - profit1);
        profit2 = Math.max(profit2, price - buy2);
    }

    return profit2;
}
```
1. Initialize variables buy1 and buy2 to track the minimum prices, and profit1 and profit2 to track the maximum profits.
2. Iterate through prices array.
3. Update buy1 to the minimum of buy1 and the current price.
4. Update profit1 to the maximum of profit1 and the current price - buy1.
5. Update buy2 to the minimum of buy2 and the current price - profit1.
6. Update profit2 to the maximum of profit2 and the current price - buy2.
7. Return profit2. This is the profit from two transactions.

## A solution in C++

```cpp
int maxProfit(vector<int>& prices) {
    int buy1 = INT_MAX, buy2 = INT_MAX;
    int profit1 = 0, profit2 = 0;

    for (int price : prices) {
        buy1 = min(buy1, price);
        profit1 = max(profit1, price - buy1);
        buy2 = min(buy2, price - profit1);
        profit2 = max(profit2, price - buy2);
    }

    return profit2;
}
```
1. Initialize variables buy1 and buy2 to track the minimum prices, and profit1 and profit2 to track the maximum profits.
2. Iterate through prices array.
3. Update buy1 to the minimum of buy1 and the current price.
4. Update profit1 to the maximum of profit1 and the current price - buy1.
5. Update buy2 to the minimum of buy2 and the current price - profit1.
6. Update profit2 to the maximum of profit2 and the current price - buy2.
7. Return profit2. This is the profit from two transactions.

## A solution in Python

```python
def maxProfit(prices):
    buy1, buy2 = float("inf"), float("inf")
    profit1, profit2 = 0, 0

    for price in prices:
        buy1 = min(buy1, price)
        profit1 = max(profit1, price - buy1)
        buy2 = min(buy2, price - profit1)
        profit2 = max(profit2, price - buy2)

    return profit2
```
1. Initialize variables buy1 and buy2 to track the minimum prices, and profit1 and profit2 to track the maximum profits.
2. Iterate through prices array.
3. Update buy1 to the minimum of buy1 and the current price.
4. Update profit1 to the maximum of profit1 and the current price - buy1.
5. Update buy2 to the minimum of buy2 and the current price - profit1.
6. Update profit2 to the maximum of profit2 and the current price - buy2.
7. Return profit2. This is the profit from two transactions.

## A solution in Javascript

```javascript
function maxProfit(prices) {
    let buy1 = Infinity, buy2 = Infinity;
    let profit1 = 0, profit2 = 0;

    for (let price of prices) {
        buy1 = Math.min(buy1, price);
        profit1 = Math.max(profit1, price - buy1);
        buy2 = Math.min(buy2, price - profit1);
        profit2 = Math.max(profit2, price - buy2);
    }

    return profit2;
}
```
1. Initialize variables buy1 and buy2 to track the minimum prices, and profit1 and profit2 to track the maximum profits.
2. Iterate through prices array.
3. Update buy1 to the minimum of buy1 and the current price.
4. Update profit1 to the maximum of profit1 and the current price - buy1.
5. Update buy2 to the minimum of buy2 and the current price - profit1.
6. Update profit2 to the maximum of profit2 and the current price - buy2.
7. Return profit2. This is the profit from two transactions.


# Binary Tree Maximum Path Sum

- slug: binary-tree-maximum-path-sum
- difficulty: Hard

A **path** in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. A node can only appear in the sequence **at most once**. Note that the path does not need to pass through the root.

The **path sum** of a path is the sum of the node's values in the path.

Given the `root` of a binary tree, return _the maximum **path sum** of any **non-empty** path_.

**Example 1:**

**Input:** root = \[1,2,3\]
**Output:** 6
**Explanation:** The optimal path is 2 -> 1 -> 3 with a path sum of 2 + 1 + 3 = 6.

**Example 2:**

**Input:** root = \[-10,9,20,null,null,15,7\]
**Output:** 42
**Explanation:** The optimal path is 15 -> 20 -> 7 with a path sum of 15 + 20 + 7 = 42.

**Constraints:**

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

## A solution in Java

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

public int maxPathSum(TreeNode root) {
    int[] maxSum = new int[]{Integer.MIN_VALUE};
    helper(root, maxSum);
    return maxSum[0];
}

private int helper(TreeNode root, int[] maxSum) {
    if (root == null) return 0;

    int left = Math.max(0, helper(root.left, maxSum));
    int right = Math.max(0, helper(root.right, maxSum));

    maxSum[0] = Math.max(maxSum[0], left + right + root.val);

    return Math.max(left, right) + root.val;
}
```
The algorithm is based on Depth First Search (DFS) traversal of the binary tree.

1. Create a helper function that takes the root and maximum path sum reference as the input parameters.
2. If the current node (root) is null, return 0.
3. Call the helper function recursively for the left and right child nodes:
   - Set `left` as the maximum of 0 and the helper function call for the left child.
   - Set `right` as the maximum of 0 and the helper function call for the right child.
4. Update the maximum path sum using the current maximum, the sum of the current node's value, and the left and right children's values.
5. Return the sum of the current node's value and the maximum of the left and right subtrees.

Call the helper function with the given binary tree root and return the maximum path sum.

## A solution in C++

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

int helper(TreeNode* root, int& maxSum) {
    if(!root) return 0;

    int left = max(0, helper(root->left, maxSum));
    int right = max(0, helper(root->right, maxSum));

    maxSum = max(maxSum, left + right + root->val);

    return max(left, right) + root->val;
}

int maxPathSum(TreeNode* root) {
    int maxSum = INT_MIN;
    helper(root, maxSum);
    return maxSum;
}
```
The algorithm is based on Depth First Search (DFS) traversal of the binary tree.

1. Create a helper function that takes the root and maximum path sum reference as the input parameters.
2. If the current node (root) is null, return 0.
3. Call the helper function recursively for the left and right child nodes:
   - Set `left` as the maximum of 0 and the helper function call for the left child.
   - Set `right` as the maximum of 0 and the helper function call for the right child.
4. Update the maximum path sum using the current maximum, the sum of the current node's value, and the left and right children's values.
5. Return the sum of the current node's value and the maximum of the left and right subtrees.

Call the helper function with the given binary tree root and return the maximum path sum.

## A solution in Python

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

def maxPathSum(root: TreeNode) -> int:
    def helper(root):
        nonlocal maxSum
        if not root:
            return 0

        left = max(0, helper(root.left))
        right = max(0, helper(root.right))

        maxSum = max(maxSum, left + right + root.val)

        return max(left, right) + root.val

    maxSum = float('-inf')
    helper(root)
    return maxSum
```
The algorithm is based on Depth First Search (DFS) traversal of the binary tree.

1. Create a helper function that takes the root and maximum path sum reference as the input parameters.
2. If the current node (root) is null, return 0.
3. Call the helper function recursively for the left and right child nodes:
   - Set `left` as the maximum of 0 and the helper function call for the left child.
   - Set `right` as the maximum of 0 and the helper function call for the right child.
4. Update the maximum path sum using the current maximum, the sum of the current node's value, and the left and right children's values.
5. Return the sum of the current node's value and the maximum of the left and right subtrees.

Call the helper function with the given binary tree root and return the maximum path sum.

## A solution in Javascript

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

function maxPathSum(root) {
    let maxSum = Number.MIN_SAFE_INTEGER;

    function helper(node) {
        if (node === null) return 0;

        const left = Math.max(0, helper(node.left));
        const right = Math.max(0, helper(node.right));

        maxSum = Math.max(maxSum, left + right + node.val);

        return Math.max(left, right) + node.val;
    }

    helper(root);
    return maxSum;
}
```
The algorithm is based on Depth First Search (DFS) traversal of the binary tree.

1. Create a helper function that takes the root and maximum path sum reference as the input parameters.
2. If the current node (root) is null, return 0.
3. Call the helper function recursively for the left and right child nodes:
   - Set `left` as the maximum of 0 and the helper function call for the left child.
   - Set `right` as the maximum of 0 and the helper function call for the right child.
4. Update the maximum path sum using the current maximum, the sum of the current node's value, and the left and right children's values.
5. Return the sum of the current node's value and the maximum of the left and right subtrees.

Call the helper function with the given binary tree root and return the maximum path sum.


# Valid Palindrome

- slug: valid-palindrome
- difficulty: Easy

A phrase is a **palindrome** if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.

Given a string `s`, return `true` _if it is a **palindrome**, or_ `false` _otherwise_.

**Example 1:**

**Input:** s =  "A man, a plan, a canal: Panama "
**Output:** true
**Explanation:**  "amanaplanacanalpanama " is a palindrome.

**Example 2:**

**Input:** s =  "race a car "
**Output:** false
**Explanation:**  "raceacar " is not a palindrome.

**Example 3:**

**Input:** s =  "  "
**Output:** true
**Explanation:** s is an empty string  " " after removing non-alphanumeric characters.
Since an empty string reads the same forward and backward, it is a palindrome.

**Constraints:**

*   `1 <= s.length <= 2 * 105`
*   `s` consists only of printable ASCII characters.

## A solution in Java

```java
public boolean isPalindrome(String s) {
    StringBuilder cleaned = new StringBuilder();
    for (char c : s.toCharArray()) {
        if (Character.isLetterOrDigit(c)) {
            cleaned.append(Character.toLowerCase(c));
        }
    }
    int left = 0, right = cleaned.length() - 1;
    while (left < right) {
        if (cleaned.charAt(left++) != cleaned.charAt(right--)) return false;
    }
    return true;
}
```
1. Clean the given string by removing non-alphanumeric characters and converting uppercase letters to lowercase.
2. Initialize two pointers: `left` pointing to the beginning of the cleaned string and `right` pointing to the end.
3. Iterate through the cleaning string, comparing the characters at the `left` and `right` pointers. If they are not equal, return `false` as it's not a palindrome.
4. If the loop completes, it means the input string is a palindrome, so return `true`.

## A solution in C++

```cpp
#include <cctype>
#include <algorithm>

bool isPalindrome(std::string s) {
    s.erase(std::remove_if(s.begin(), s.end(), [](char c) { return !std::isalnum(c); }), s.end());
    std::transform(s.begin(), s.end(), s.begin(), ::tolower);
    int left = 0, right = s.size() - 1;
    while (left < right) {
        if (s[left++] != s[right--]) return false;
    }
    return true;
}
```
1. Clean the given string by removing non-alphanumeric characters and converting uppercase letters to lowercase.
2. Initialize two pointers: `left` pointing to the beginning of the cleaned string and `right` pointing to the end.
3. Iterate through the cleaning string, comparing the characters at the `left` and `right` pointers. If they are not equal, return `false` as it's not a palindrome.
4. If the loop completes, it means the input string is a palindrome, so return `true`.

## A solution in Python

```python
def isPalindrome(s: str) -> bool:
    cleaned = "".join(c.lower() for c in s if c.isalnum())
    left, right = 0, len(cleaned) - 1
    while left < right:
        if cleaned[left] != cleaned[right]:
            return False
        left += 1
        right -= 1
    return True
```
1. Clean the given string by removing non-alphanumeric characters and converting uppercase letters to lowercase.
2. Initialize two pointers: `left` pointing to the beginning of the cleaned string and `right` pointing to the end.
3. Iterate through the cleaning string, comparing the characters at the `left` and `right` pointers. If they are not equal, return `false` as it's not a palindrome.
4. If the loop completes, it means the input string is a palindrome, so return `true`.

## A solution in Javascript

```javascript
function isPalindrome(s) {
    const cleaned = s.toLowerCase().replace(/[^a-z0-9]/g, '');
    let left = 0, right = cleaned.length - 1;
    while (left < right) {
        if (cleaned[left++] !== cleaned[right--]) return false;
    }
    return true;
}
```
1. Clean the given string by removing non-alphanumeric characters and converting uppercase letters to lowercase.
2. Initialize two pointers: `left` pointing to the beginning of the cleaned string and `right` pointing to the end.
3. Iterate through the cleaning string, comparing the characters at the `left` and `right` pointers. If they are not equal, return `false` as it's not a palindrome.
4. If the loop completes, it means the input string is a palindrome, so return `true`.


# Word Ladder II

- slug: word-ladder-ii
- difficulty: Hard

A **transformation sequence** from word `beginWord` to word `endWord` using a dictionary `wordList` is a sequence of words `beginWord -> s1 -> s2 -> ... -> sk` such that:

*   Every adjacent pair of words differs by a single letter.
*   Every `si` for `1 <= i <= k` is in `wordList`. Note that `beginWord` does not need to be in `wordList`.
*   `sk == endWord`

Given two words, `beginWord` and `endWord`, and a dictionary `wordList`, return _all the **shortest transformation sequences** from_ `beginWord` _to_ `endWord`_, or an empty list if no such sequence exists. Each sequence should be returned as a list of the words_ `[beginWord, s1, s2, ..., sk]`.

**Example 1:**

**Input:** beginWord =  "hit ", endWord =  "cog ", wordList = \[ "hot ", "dot ", "dog ", "lot ", "log ", "cog "\]
**Output:** \[\[ "hit ", "hot ", "dot ", "dog ", "cog "\],\[ "hit ", "hot ", "lot ", "log ", "cog "\]\]
**Explanation:** There are 2 shortest transformation sequences:
 "hit " ->  "hot " ->  "dot " ->  "dog " ->  "cog "
 "hit " ->  "hot " ->  "lot " ->  "log " ->  "cog "

**Example 2:**

**Input:** beginWord =  "hit ", endWord =  "cog ", wordList = \[ "hot ", "dot ", "dog ", "lot ", "log "\]
**Output:** \[\]
**Explanation:** The endWord  "cog " is not in wordList, therefore there is no valid transformation sequence.

**Constraints:**

*   `1 <= beginWord.length <= 5`
*   `endWord.length == beginWord.length`
*   `1 <= wordList.length <= 500`
*   `wordList[i].length == beginWord.length`
*   `beginWord`, `endWord`, and `wordList[i]` consist of lowercase English letters.
*   `beginWord != endWord`
*   All the words in `wordList` are **unique**.
*   The **sum** of all shortest transformation sequences does not exceed `105`.

## A solution in Java

```java
import java.util.*;

public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
    Set<String> dict = new HashSet<>(wordList);
    if (!dict.contains(endWord)) {
        return Collections.emptyList();
    }

    Map<String, List<String>> adjacent = new HashMap<>();
    Map<String, Integer> distance = new HashMap<>();
    Queue<String> queue = new LinkedList<>();
    queue.offer(beginWord);
    distance.put(beginWord, 0);

    while (!queue.isEmpty()) {
        String current = queue.poll();
        if (current.equals(endWord)) {
            break;
        }
        for (String neighbor : neighbors(current)) {
            if (!dict.contains(neighbor)) {
                continue;
            }
            if (!distance.containsKey(neighbor)) {
                distance.put(neighbor, distance.get(current) + 1);
                queue.offer(neighbor);
            }
            if (distance.get(neighbor).equals(distance.get(current) + 1)) {
                adjacent.computeIfAbsent(current, k -> new ArrayList<>()).add(neighbor);
            }
        }
    }

    List<List<String>> result = new ArrayList<>();
    List<String> path = new ArrayList<>();
    path.add(beginWord);
    backtrack(beginWord, endWord, path, adjacent, result);
    return result;
}

private void backtrack(String current, String endWord, List<String> path, Map<String, List<String>> adjacent, List<List<String>> result) {
    if (current.equals(endWord)) {
        result.add(new ArrayList<>(path));
        return;
    }
    for (String next : adjacent.getOrDefault(current, Collections.emptyList())) {
        path.add(next);
        backtrack(next, endWord, path, adjacent, result);
        path.remove(path.size() - 1);
    }
}

private List<String> neighbors(String word) {
    List<String> result = new ArrayList<>();
    char[] chars = word.toCharArray();
    for (int i = 0; i < chars.length; i++) {
        char original = chars[i];
        for (char j = 'a'; j <= 'z'; j++) {
            if (j == original) {
                continue;
            }
            chars[i] = j;
            result.add(new String(chars));
        }
        chars[i] = original;
    }
    return result;
}
```
1. Create a dictionary set, adjacent map, distance map, and a queue to store words.
2. Initialize the queue with the beginWord and set its distance to 0.
3. Define a neighbors function that returns all possible words by changing one character of the given word.
4. Run a BFS from the beginWord, updating the distances and adjacent maps.
5. The BFS stops when it reaches the endWord or finishes visiting all reachable words.
6. Define a backtrack function to search through the explored adjacent map to construct the transformation paths.
7. Call the backtrack function with the beginWord, and return the result list, which contains the shortest transformations.

## A solution in C++

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

std::vector<std::vector<std::string>> findLadders(std::string beginWord, std::string endWord, std::vector<std::string>& wordList) {
    std::unordered_set<std::string> dict(wordList.begin(), wordList.end());
    if (dict.find(endWord) == dict.end()) {
        return {};
    }
    std::unordered_map<std::string, std::vector<std::string>> adjacent;
    std::unordered_map<std::string, int> distance;

    auto neighbors = [&](const std::string& word) {
        std::vector<std::string> result;
        std::string temp = word;
        for (char& ch : temp) {
            char original = ch;
            for (int i = 'a'; i <= 'z'; ++i) {
                ch = i;
                if (dict.count(temp) && temp != word) {
                    result.push_back(temp);
                }
            }
            ch = original;
        }
        return result;
    };

    std::queue<std::string> q;
    q.push(beginWord);
    distance[beginWord] = 0;

    while (!q.empty()) {
        std::string current = q.front();
        q.pop();
        if (current == endWord) {
            break;
        }
        for (const std::string& neighbor : neighbors(current)) {
            if (!distance.count(neighbor)) {
                distance[neighbor] = distance[current] + 1;
                q.push(neighbor);
            }
            if (distance[neighbor] == distance[current] + 1) {
                adjacent[current].push_back(neighbor);
            }
        }
    }

    std::vector<std::vector<std::string>> result;
    std::vector<std::string> path = {beginWord};
    std::function<void(const std::string&)> backtrack = [&](const std::string& word) {
        if (word == endWord) {
            result.push_back(path);
            return;
        }
        for (const std::string& next : adjacent[word]) {
            path.push_back(next);
            backtrack(next);
            path.pop_back();
        }
    };

    backtrack(beginWord);
    return result;
}
```
1. Create a dictionary set, adjacent map, distance map, and a queue to store words.
2. Initialize the queue with the beginWord and set its distance to 0.
3. Define a neighbors function that returns all possible words by changing one character of the given word.
4. Run a BFS from the beginWord, updating the distances and adjacent maps.
5. The BFS stops when it reaches the endWord or finishes visiting all reachable words.
6. Define a backtrack function to search through the explored adjacent map to construct the transformation paths.
7. Call the backtrack function with the beginWord, and return the result list, which contains the shortest transformations.

## A solution in Python

```python
from collections import defaultdict, deque

def findLadders(beginWord, endWord, wordList):
    wordList = set(wordList)
    if endWord not in wordList:
        return []

    adjacent = defaultdict(list)
    distance = defaultdict(int)
    queue = deque([beginWord])
    distance[beginWord] = 0

    def neighbors(word):
        for i in range(len(word)):
            for j in range(ord('a'), ord('z') + 1):
                yield word[:i] + chr(j) + word[i + 1:]

    while queue:
        current = queue.popleft()
        if current == endWord:
            break
        for neighbor in neighbors(current):
            if neighbor not in wordList:
                continue
            if neighbor not in distance:
                distance[neighbor] = distance[current] + 1
                queue.append(neighbor)
            if distance[neighbor] == distance[current] + 1:
                adjacent[current].append(neighbor)

    result = []
    path = [beginWord]

    def backtrack(word):
        if word == endWord:
            result.append(path[:])
        else:
            for next_word in adjacent[word]:
                path.append(next_word)
                backtrack(next_word)
                path.pop()

    backtrack(beginWord)
    return result
```
1. Create a dictionary set, adjacent map, distance map, and a queue to store words.
2. Initialize the queue with the beginWord and set its distance to 0.
3. Define a neighbors function that returns all possible words by changing one character of the given word.
4. Run a BFS from the beginWord, updating the distances and adjacent maps.
5. The BFS stops when it reaches the endWord or finishes visiting all reachable words.
6. Define a backtrack function to search through the explored adjacent map to construct the transformation paths.
7. Call the backtrack function with the beginWord, and return the result list, which contains the shortest transformations.

## A solution in Javascript

```javascript
function findLadders(beginWord, endWord, wordList) {
    const dict = new Set(wordList);
    if (!dict.has(endWord)) {
        return [];
    }

    const adjacent = new Map();
    const distance = new Map();
    const queue = [beginWord];
    distance.set(beginWord, 0);

    function neighbors(word) {
        const result = [];
        for (let i = 0; i < word.length; i++) {
            for (let j = 'a'.charCodeAt(0); j <= 'z'.charCodeAt(0); j++) {
                const next = word.slice(0, i) + String.fromCharCode(j) + word.slice(i + 1);
                if (next !== word) {
                    result.push(next);
                }
            }
        }
        return result;
    }

    while (queue.length > 0) {
        const current = queue.shift();
        if (current === endWord) {
            break;
        }
        for (const neighbor of neighbors(current)) {
            if (!dict.has(neighbor)) {
                continue;
            }
            if (!distance.has(neighbor)) {
                distance.set(neighbor, distance.get(current) + 1);
                queue.push(neighbor);
            }
            if (distance.get(neighbor) === distance.get(current) + 1) {
                if (!adjacent.has(current)) {
                    adjacent.set(current, []);
                }
                adjacent.get(current).push(neighbor);
            }
        }
    }

    const result = [];
    const path = [beginWord];

    function backtrack(word) {
        if (word === endWord) {
            result.push([...path]);
            return;
        }
        for (const next of (adjacent.get(word) || [])) {
            path.push(next);
            backtrack(next);
            path.pop();
        }
    }

    backtrack(beginWord);
    return result;
}
```
1. Create a dictionary set, adjacent map, distance map, and a queue to store words.
2. Initialize the queue with the beginWord and set its distance to 0.
3. Define a neighbors function that returns all possible words by changing one character of the given word.
4. Run a BFS from the beginWord, updating the distances and adjacent maps.
5. The BFS stops when it reaches the endWord or finishes visiting all reachable words.
6. Define a backtrack function to search through the explored adjacent map to construct the transformation paths.
7. Call the backtrack function with the beginWord, and return the result list, which contains the shortest transformations.


# Word Ladder

- slug: word-ladder
- difficulty: Hard

A **transformation sequence** from word `beginWord` to word `endWord` using a dictionary `wordList` is a sequence of words `beginWord -> s1 -> s2 -> ... -> sk` such that:

*   Every adjacent pair of words differs by a single letter.
*   Every `si` for `1 <= i <= k` is in `wordList`. Note that `beginWord` does not need to be in `wordList`.
*   `sk == endWord`

Given two words, `beginWord` and `endWord`, and a dictionary `wordList`, return _the **number of words** in the **shortest transformation sequence** from_ `beginWord` _to_ `endWord`_, or_ `0` _if no such sequence exists._

**Example 1:**

**Input:** beginWord =  "hit ", endWord =  "cog ", wordList = \[ "hot ", "dot ", "dog ", "lot ", "log ", "cog "\]
**Output:** 5
**Explanation:** One shortest transformation sequence is  "hit " ->  "hot " ->  "dot " ->  "dog " -> cog ", which is 5 words long.

**Example 2:**

**Input:** beginWord =  "hit ", endWord =  "cog ", wordList = \[ "hot ", "dot ", "dog ", "lot ", "log "\]
**Output:** 0
**Explanation:** The endWord  "cog " is not in wordList, therefore there is no valid transformation sequence.

**Constraints:**

*   `1 <= beginWord.length <= 10`
*   `endWord.length == beginWord.length`
*   `1 <= wordList.length <= 5000`
*   `wordList[i].length == beginWord.length`
*   `beginWord`, `endWord`, and `wordList[i]` consist of lowercase English letters.
*   `beginWord != endWord`
*   All the words in `wordList` are **unique**.

## A solution in Java

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

public int ladderLength(String beginWord, String endWord, List<String> wordList) {
    Set<String> dict = new HashSet<>(wordList);
    if (!dict.contains(endWord)) return 0;

    Queue<String> q = new LinkedList<>();
    q.offer(beginWord);
    int steps = 1;

    while (!q.isEmpty()) {
        int size = q.size();
        for (int i = 0; i < size; ++i) {
            String currentWord = q.poll();
            if (currentWord.equals(endWord)) return steps;

            char[] charArray = currentWord.toCharArray();
            for (int j = 0; j < charArray.length; ++j) {
                char originalChar = charArray[j];
                for (int k = 0; k < 26; ++k) {
                    charArray[j] = (char) ('a' + k);
                    String newWord = new String(charArray);
                    if (dict.remove(newWord)) {
                        q.offer(newWord);
                    }
                }
                charArray[j] = originalChar;
            }
        }
        ++steps;
    }
    return 0;
}
```
In this problem, we use a breadth-first search (BFS) algorithm to find the shortest transformation sequence from `beginWord` to `endWord`:

1. Create an unordered set `dict` or `word_set` with all the words from `wordList` for fast look-up, and check if it contains the `endWord`.
2. Create a queue for BFS, initialize it with `beginWord`, and initialize `steps` variable to 1.
3. Repeat the following steps while the queue is not empty:
   a) For each level of BFS, store the current level size, and create an empty set for `current_level` (only in Python & JavaScript).
   b) Iterate for each word in the current BFS level:
      - Dequeue the next `currentWord`, and check for `endWord`; if found return the current `steps` value.
      - Iterate through each character of the `currentWord`; for every character, replace it with 26 possible lowercase alphabets.
        - If the new word is in the `dict` or `word_set`, enqueue it in the queue, and remove it. In Python and JavaScript, also add it to the `current_level` set.
      - Revert the character back to the original character.
   c) Increment the `steps` value by 1, and in Python/javascript, update the `word_set` by removing words present in `current_level`.
4. If the queue is empty and no sequence is found, return 0.

## A solution in C++

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

int ladderLength(std::string beginWord, std::string endWord, std::vector<std::string>& wordList) {
    std::unordered_set<std::string> dict(wordList.begin(), wordList.end());
    if (!dict.count(endWord)) return 0;

    std::queue<std::string> q;
    q.push(beginWord);
    int steps = 1;

    while (!q.empty()) {
        int size = q.size();
        for (int i = 0; i < size; ++i) {
            std::string currentWord = q.front();
            q.pop();
            if (currentWord == endWord) return steps;

            for (char& c : currentWord) {
                char originalChar = c;
                for (int j = 0; j < 26; ++j) {
                    c = 'a' + j;
                    if (dict.count(currentWord)) {
                        q.push(currentWord);
                        dict.erase(currentWord);
                    }
                }
                c = originalChar;
            }
        }
        ++steps;
    }
    return 0;
}
```
In this problem, we use a breadth-first search (BFS) algorithm to find the shortest transformation sequence from `beginWord` to `endWord`:

1. Create an unordered set `dict` or `word_set` with all the words from `wordList` for fast look-up, and check if it contains the `endWord`.
2. Create a queue for BFS, initialize it with `beginWord`, and initialize `steps` variable to 1.
3. Repeat the following steps while the queue is not empty:
   a) For each level of BFS, store the current level size, and create an empty set for `current_level` (only in Python & JavaScript).
   b) Iterate for each word in the current BFS level:
      - Dequeue the next `currentWord`, and check for `endWord`; if found return the current `steps` value.
      - Iterate through each character of the `currentWord`; for every character, replace it with 26 possible lowercase alphabets.
        - If the new word is in the `dict` or `word_set`, enqueue it in the queue, and remove it. In Python and JavaScript, also add it to the `current_level` set.
      - Revert the character back to the original character.
   c) Increment the `steps` value by 1, and in Python/javascript, update the `word_set` by removing words present in `current_level`.
4. If the queue is empty and no sequence is found, return 0.

## A solution in Python

```python
from collections import deque

def ladderLength(beginWord, endWord, wordList):
    word_set = set(wordList)
    if endWord not in word_set:
        return 0

    q = deque([beginWord])
    steps = 1

    while q:
        size = len(q)
        current_level = set()

        for _ in range(size):
            current_word = q.popleft()
            if current_word == endWord:
                return steps

            word_chars = list(current_word)
            for i in range(len(word_chars)):
                original_char = word_chars[i]
                for j in range(26):
                    word_chars[i] = chr(ord('a') + j)
                    new_word = ''.join(word_chars)
                    if new_word in word_set:
                        q.append(new_word)
                        current_level.add(new_word)

                word_chars[i] = original_char

        word_set -= current_level
        steps += 1

    return 0
```
In this problem, we use a breadth-first search (BFS) algorithm to find the shortest transformation sequence from `beginWord` to `endWord`:

1. Create an unordered set `dict` or `word_set` with all the words from `wordList` for fast look-up, and check if it contains the `endWord`.
2. Create a queue for BFS, initialize it with `beginWord`, and initialize `steps` variable to 1.
3. Repeat the following steps while the queue is not empty:
   a) For each level of BFS, store the current level size, and create an empty set for `current_level` (only in Python & JavaScript).
   b) Iterate for each word in the current BFS level:
      - Dequeue the next `currentWord`, and check for `endWord`; if found return the current `steps` value.
      - Iterate through each character of the `currentWord`; for every character, replace it with 26 possible lowercase alphabets.
        - If the new word is in the `dict` or `word_set`, enqueue it in the queue, and remove it. In Python and JavaScript, also add it to the `current_level` set.
      - Revert the character back to the original character.
   c) Increment the `steps` value by 1, and in Python/javascript, update the `word_set` by removing words present in `current_level`.
4. If the queue is empty and no sequence is found, return 0.

## A solution in Javascript

```javascript
function ladderLength(beginWord, endWord, wordList) {
    const wordSet = new Set(wordList);
    if (!wordSet.has(endWord)) return 0;

    const q = [beginWord];
    let steps = 1;

    while (q.length > 0) {
        const size = q.length;
        const currentLevel = new Set();

        for (let i = 0; i < size; ++i) {
            const currentWord = q.shift();
            if (currentWord === endWord) return steps;

            const wordChars = currentWord.split('');
            for (let j = 0; j < wordChars.length; ++j) {
                const originalChar = wordChars[j];
                for (let k = 0; k < 26; ++k) {
                    wordChars[j] = String.fromCharCode('a'.charCodeAt(0) + k);
                    const newWord = wordChars.join('');
                    if (wordSet.has(newWord)) {
                        q.push(newWord);
                        currentLevel.add(newWord);
                    }
                }
                wordChars[j] = originalChar;
            }
        }
        steps++;
        for (const word of currentLevel) {
            wordSet.delete(word);
        }
    }
    return 0;
}
```
In this problem, we use a breadth-first search (BFS) algorithm to find the shortest transformation sequence from `beginWord` to `endWord`:

1. Create an unordered set `dict` or `word_set` with all the words from `wordList` for fast look-up, and check if it contains the `endWord`.
2. Create a queue for BFS, initialize it with `beginWord`, and initialize `steps` variable to 1.
3. Repeat the following steps while the queue is not empty:
   a) For each level of BFS, store the current level size, and create an empty set for `current_level` (only in Python & JavaScript).
   b) Iterate for each word in the current BFS level:
      - Dequeue the next `currentWord`, and check for `endWord`; if found return the current `steps` value.
      - Iterate through each character of the `currentWord`; for every character, replace it with 26 possible lowercase alphabets.
        - If the new word is in the `dict` or `word_set`, enqueue it in the queue, and remove it. In Python and JavaScript, also add it to the `current_level` set.
      - Revert the character back to the original character.
   c) Increment the `steps` value by 1, and in Python/javascript, update the `word_set` by removing words present in `current_level`.
4. If the queue is empty and no sequence is found, return 0.


# Longest Consecutive Sequence

- slug: longest-consecutive-sequence
- difficulty: Medium

Given an unsorted array of integers `nums`, return _the length of the longest consecutive elements sequence._

You must write an algorithm that runs in `O(n)` time.

**Example 1:**

**Input:** nums = \[100,4,200,1,3,2\]
**Output:** 4
**Explanation:** The longest consecutive elements sequence is `[1, 2, 3, 4]`. Therefore its length is 4.

**Example 2:**

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

**Constraints:**

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

## A solution in Java

```java
public int longestConsecutive(int[] nums) {
    Set<Integer> elements = new HashSet<>();
    for (int num : nums) {
        elements.add(num);
    }

    int longestSeq = 0;

    for (int num : nums) {
        if (!elements.contains(num - 1)) {
            int currentNum = num;
            int currentSeq = 1;

            while (elements.contains(currentNum + 1)) {
                currentNum++;
                currentSeq++;
            }

            longestSeq = Math.max(longestSeq, currentSeq);
        }
    }
    return longestSeq;
}
```
The algorithm first creates a set (or hash set) with the given array of integers called `elements`. The set will allow us to have a fast O(1) lookup on our next step.
Now we iterate through the original array of numbers, and for each number, we check if `(number - 1)` is not in the `elements` set. If it's not in the set, it means we can start counting a new consecutive sequence.
Next, we create two variables, `currentNum` and `currentSeq`, and initialize them with the current number and 1, respectively.
We then use a while loop to check if the next number (`currentNum + 1`) is in the `elements` set. If it is, we increment both `currentNum` and `currentSeq`. This process will continue, finding consecutive elements in the set, until no more consecutive elements are found.
Finally, to get the length of the longest consecutive sequence, we update the `longestSeq` variable by choosing the maximum value between itself and `currentSeq`. This will keep track of the longest consecutive sequence found so far.
The process continues until all numbers in the original array have been checked, and at the end, `longestSeq` will store the answer - the length of the longest consecutive elements sequence.

## A solution in C++

```cpp
int longestConsecutive(vector<int>& nums) {
    unordered_set<int> elements(nums.begin(), nums.end());
    int longestSeq = 0;

    for (int num : nums) {
        if (elements.find(num - 1) == elements.end()) {
            int currentNum = num;
            int currentSeq = 1;

            while (elements.find(currentNum + 1) != elements.end()) {
                currentNum += 1;
                currentSeq += 1;
            }

            longestSeq = max(longestSeq, currentSeq);
        }
    }
    return longestSeq;
}
```
The algorithm first creates a set (or hash set) with the given array of integers called `elements`. The set will allow us to have a fast O(1) lookup on our next step.
Now we iterate through the original array of numbers, and for each number, we check if `(number - 1)` is not in the `elements` set. If it's not in the set, it means we can start counting a new consecutive sequence.
Next, we create two variables, `currentNum` and `currentSeq`, and initialize them with the current number and 1, respectively.
We then use a while loop to check if the next number (`currentNum + 1`) is in the `elements` set. If it is, we increment both `currentNum` and `currentSeq`. This process will continue, finding consecutive elements in the set, until no more consecutive elements are found.
Finally, to get the length of the longest consecutive sequence, we update the `longestSeq` variable by choosing the maximum value between itself and `currentSeq`. This will keep track of the longest consecutive sequence found so far.
The process continues until all numbers in the original array have been checked, and at the end, `longestSeq` will store the answer - the length of the longest consecutive elements sequence.

## A solution in Python

```python
def longest_consecutive(nums):
    elements = set(nums)
    longest_seq = 0

    for num in nums:
        if num - 1 not in elements:
            current_num = num
            current_seq = 1

            while current_num + 1 in elements:
                current_num += 1
                current_seq += 1

            longest_seq = max(longest_seq, current_seq)

    return longest_seq
```
The algorithm first creates a set (or hash set) with the given array of integers called `elements`. The set will allow us to have a fast O(1) lookup on our next step.
Now we iterate through the original array of numbers, and for each number, we check if `(number - 1)` is not in the `elements` set. If it's not in the set, it means we can start counting a new consecutive sequence.
Next, we create two variables, `currentNum` and `currentSeq`, and initialize them with the current number and 1, respectively.
We then use a while loop to check if the next number (`currentNum + 1`) is in the `elements` set. If it is, we increment both `currentNum` and `currentSeq`. This process will continue, finding consecutive elements in the set, until no more consecutive elements are found.
Finally, to get the length of the longest consecutive sequence, we update the `longestSeq` variable by choosing the maximum value between itself and `currentSeq`. This will keep track of the longest consecutive sequence found so far.
The process continues until all numbers in the original array have been checked, and at the end, `longestSeq` will store the answer - the length of the longest consecutive elements sequence.

## A solution in Javascript

```javascript
function longestConsecutive(nums) {
    const elements = new Set(nums);
    let longestSeq = 0;

    for (const num of nums) {
        if (!elements.has(num - 1)) {
            let currentNum = num;
            let currentSeq = 1;

            while (elements.has(currentNum + 1)) {
                currentNum++;
                currentSeq++;
            }

            longestSeq = Math.max(longestSeq, currentSeq);
        }
    }

    return longestSeq;
}
```
The algorithm first creates a set (or hash set) with the given array of integers called `elements`. The set will allow us to have a fast O(1) lookup on our next step.
Now we iterate through the original array of numbers, and for each number, we check if `(number - 1)` is not in the `elements` set. If it's not in the set, it means we can start counting a new consecutive sequence.
Next, we create two variables, `currentNum` and `currentSeq`, and initialize them with the current number and 1, respectively.
We then use a while loop to check if the next number (`currentNum + 1`) is in the `elements` set. If it is, we increment both `currentNum` and `currentSeq`. This process will continue, finding consecutive elements in the set, until no more consecutive elements are found.
Finally, to get the length of the longest consecutive sequence, we update the `longestSeq` variable by choosing the maximum value between itself and `currentSeq`. This will keep track of the longest consecutive sequence found so far.
The process continues until all numbers in the original array have been checked, and at the end, `longestSeq` will store the answer - the length of the longest consecutive elements sequence.