**Definitions:** Given the `head`

of a linked list, remove the n^{th} node from the end of the list and return list’s head.

LeetCode provides us also with a few graphical examples. However, the definition is quite clear, and there is not much that we can add to it.

Although, LeetCode problem sets certain constrains, none of them will be very critical and limiting. These constrains are:

- 1 <= number of nodes <= 30
- 0 <= Node.val <= 100
- 1 <= n <= number of nodes

A brief look at the constraints should give us straightforward edge cases.

The first edge case should be a linked list with only one element and demand the removal of the first element from the end of the linked list. Basically, we should return `NULL`

.

A second edge case is very similar; we will have a small number of nodes, let’s say two, and we should remove the first or second element from the end. We should get back a linked list of the maximum length of one element for the second edge case.

Any other case will lead towards returning a list of length two or more elements.

While `ListNode`

class is not important, I will still rather keep the reference for the `ListNode`

class code here:

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

First of all, I will provide a clean code for the solution so you can go through it. And in case you will have doubts or questions, you can read further. Then, below the answer, I will go through the code and explain parts of the code in greater detail.

Here is a clean code for LeetCode’s *Remove N-th Node From End Of The List* solution:

```
public class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyNode = new ListNode(0);
dummyNode.next = head;
ListNode slow = dummyNode;
ListNode fast = dummyNode;
// Move fast pointer in front of slow, so the gap between slow and fast pointer becomes n.
while (n > 0) {
fast = fast.next;
n--;
}
// You have created window between slow and fast pointer.
// Move the window on the end of the linked list and maintain the gap.
while (fast != null) {
slow = slow.next;
fast = fast.next;
}
slow.next = slow.next.next;
return dummyNode.next;
}
}
```

Do you understand the solution?

Let’s take a deeper look into the solution.

**Note to remember**: Good advice – always, you will need a **dummy node** when you have to remove an element in the linked list.

on the beginning, we will “hoist” a small trick where we connect head `ListNode`

to a **dummy node**. The role of this dummy node will be only to keep a Java *reference* on the method returnable `head`

node.

I will use an example from the LeetCode page and use a linked list node with five elements for better clarity. Element for removal from the end of the linked list will be the second from the back of the linked list.

```
ListNode dummyNode = new ListNode(0);
// dummyNode -> NULL
dummyNode.next = head;
// dummyNode -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL
```

Now, we will use a trick with slow and fast pointer. Let’s assign two new nodes, **slow** and **fast**, reference to **dummy node** .

```
ListNode slow = dummyNode;
// slow --> dummyNode -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL
ListNode fast = dummyNode;
// fast --> dummyNode -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL
```

Right now everything is ready for our little trick:

```
ListNode dummyNode = new ListNode(0);
dummyNode.next = head;
ListNode slow = dummyNode;
ListNode fast = dummyNode;
```

What we want is to create a gap between **slow** and **fast** node with the size of the element we want to remove from the linked list end. We will visualize it better right away. But until then, we should realize that we want to create a window of size **n**. It will help us, when sliding towards the end, make a border on which we will find the element we want to remove.

Let’s loop **fast** pointer n-times sideways:

```
while (n > 0) {
fast = fast.next;
n--;
}
// F
// dummyNode -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL
// F
// dummyNode -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL
// F
// dummyNode -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL
```

Now we have a two pointers, **slow** and **fast**, separated by the length of n.

All we have to do is move the window created by two pointers, **slow** and **fast**, to the end of the linked list.

```
while (fast != null) {
slow = slow.next;
fast = fast.next;
}
// dummyNode -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL
// S
// dummyNode -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL
// F
// |<- gap ->|
// dummyNode -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL
// S
// dummyNode -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL
// F
// |<- gap ->|
// dummyNode -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL
// S
// dummyNode -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL
// F
// |<- gap ->|
```

We see that now we moved our window created by **slow** and **fast** pointer on the end of linked list.

The only thing left is to skip the desired node after **slow** pointer.

```
slow.next = slow.next.next;
// dummyNode -> 1 -> 2 -> 3 -> 4 -> 5 -> NULL
// S <- reassigning the node
// dummyNode -> 1 -> 2 -> 3 -> 5 -> NULL
```

Finally we can return the reference on **head** from **dummy node**:

```
// returning the head of helping dummy node
return dummyNode.next;
```

As we see, our solution is providing results on the first run. Therefore, we even managed to fulfil the bonus part of the LeetCode problem solution required to solve the problem with one pass on the linked list.

**Time Complexity**: O(N), where N is the number of nodes in the given list. We need to loop once through all the nodes to get with the **fast** pointer to the end of the given linked list.

**Space Complexity**: O(1), since we do not use any auxiliary space and use only constant space for **slow** and **fast** pointers.

```
package com.bigocrazy.leetcode;
import org.junit.Assert;
import org.junit.Test;
import com.bigocrazy.leetcode.Solution;
public class TestCases {
@Test
public void testLeetcodeBasicExample1() {
ListNode head = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5)))));
ListNode result = Solution.removeNthFromEnd(head, 2);
Assert.assertEquals(1, result.val);
result = result.next;
Assert.assertEquals(2, result.val);
result = result.next;
Assert.assertEquals(3, result.val);
result = result.next;
Assert.assertEquals(5, result.val);
Assert.assertEquals(null, result.next);
}
@Test
public void testLeetcodeBasicExample2() {
ListNode head = new ListNode(1);
ListNode result = Solution.removeNthFromEnd(head, 1);
Assert.assertEquals(null, result);
}
@Test
public void testLeetcodeBasicExample3() {
ListNode head = new ListNode(1, new ListNode(2));
ListNode result = Solution.removeNthFromEnd(head, 1);
Assert.assertEquals(1, result.val);
Assert.assertEquals(null, result.next);
}
}
```

The problem only asks us to remove the node from the linked list and not delete it. So a good question to ask the interviewer is if it is also required to remove the node from the linked list or completely delete it from memory. Since this problem has not been stated, if the node is not needed somewhere else, it is still better to remove the node from the linked list as asked.

However, if we want to delete the node altogether, then we will free the memory by assigning `NULL`

to the removed node from the linked list before returning the linked list `head`

from the method.

This article has shown how to solve the 19th LeetCode problem Remove Nth Node From End Of The List. We hope that the solution for this problem was easy to clear and easy to understand.

Do you know other ways how to solve this problem? Did you find a mistake in our solution? Or have you found a similar question on other platforms? Let us know in the comment to adjust the description, and your contribution will help others better solve this problem.

]]>

This is a medium LeetCode problem, under number 102 – Binary Tree Level Order Traversal. The problem definition goes like this:

Given the root of a binary tree, return the level order traversal of its nodes’ values. (i.e., from left to right, level by level).

At first, LeetCode gives us an excellent example of what the problem requires to solve.

1 / \ 21 22 / \ 31 32

As we move on the levels of the Binary Tree, we need to add all elements on that level to the list. The result will then consist of all the element lists from all the levels of the Binary Tree.

**Output:**

`[[1],[21,22],[31,32]]`

There are two constraints for this LeetCode problem:

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

While the sheer value of the node is not the problem (second constraint), the range condition for the number of nodes in the tree is (first constraint). As you can see, the lower range is 0. And zero means that we can get a null reference (rather null-pointer) as input for our algorithmic solution. Keep in mind this edge case when trying to solve this LeetCode problem.

If you think about it, the solution to this problem is relatively straightforward. So, let’s try to solve this problem decoratively, and you will see how easy it is to solve this problem.

We need two lists, one for overall results and one for partial sub-level results. We will collect sub-level results into overall results.

`List` subResults = new ArrayList<>();
List> results = new ArrayList<>();

We will also need two queues, one for the current iteration and the second for collecting the next Tree level elements.

`Queue` queue = new LinkedList<>();
Queue nextLevelQueue = new LinkedList<>();

We need to start the algorithmic engine by padding the root into the current iteration queue. After the first root element is placed into the current iteration queue, we can iterate through the current iteration queue until it is empty and check all nodes for the next level tree nodes. Then, subsequent level tree nodes will be placed into the next level queue.

`Queue` queue = new LinkedList<>();
List subResults = new ArrayList<>();
queue.add(root);
Queue nextLevelQueue = new LinkedList<>();
List> results = new ArrayList<>();
while (!queue.isEmpty()) {
TreeNode treeNode = queue.poll();
if (treeNode.left != null) {
nextLevelQueue.add(treeNode.left);
}
if (treeNode.right != null) {
nextLevelQueue.add(treeNode.right);
}
subResults.add(treeNode.val);
}
return results;

At the end of the iteration, for each current level node, we need to check if the current level queue is empty. If the queue is empty, we need to appropriately exchange values and clean up current level temporal data storage.

```
if (queue.isEmpty()) {
queue.addAll(nextLevelQueue);
nextLevelQueue = new LinkedList<>();
results.add(subResults);
subResults = new ArrayList<>();
}
```

In the end, the whole algorithm will be looking like this:

```
public class Solution {
public static List
```> levelOrder(TreeNode root) {
Queue queue = new LinkedList<>();
List subResults = new ArrayList<>();
queue.add(root);
Queue nextLevelQueue = new LinkedList<>();
List> results = new ArrayList<>();
while (!queue.isEmpty()) {
TreeNode treeNode = queue.poll();
if (treeNode.left != null) {
nextLevelQueue.add(treeNode.left);
}
if (treeNode.right != null) {
nextLevelQueue.add(treeNode.right);
}
subResults.add(treeNode.val);
if (queue.isEmpty()) {
queue.addAll(nextLevelQueue);
nextLevelQueue = new LinkedList<>();
results.add(subResults);
subResults = new ArrayList<>();
}
}
return results;
}
}

Now, we should look at our solution and solve it for any edge case we can think of. Does the current solution work for all edge cases?

Do you remember when we were instantly suspicious about LeetCode problem constraints and the possibility of null-pointer on method input? Let’s handle the root null case now:

```
public class Solution {
public static List
```> levelOrder(TreeNode root) {
List> results = new ArrayList<>();
if (root == null) {
return results;
}
Queue queue = new LinkedList<>();
List subResults = new ArrayList<>();
queue.add(root);
Queue nextLevelQueue = new LinkedList<>();
while (!queue.isEmpty()) {
TreeNode treeNode = queue.poll();
if (treeNode.left != null) {
nextLevelQueue.add(treeNode.left);
}
if (treeNode.right != null) {
nextLevelQueue.add(treeNode.right);
}
subResults.add(treeNode.val);
if (queue.isEmpty()) {
queue.addAll(nextLevelQueue);
nextLevelQueue = new LinkedList<>();
results.add(subResults);
subResults = new ArrayList<>();
}
}
return results;
}
}

Is this a good solution? Yes and no. One can argue that our solution is an unclever – brute-force solution. You managed to solve the problem. But you used too many resources doing it. Are two queues necessary? Do we need to reference a new element every iteration?

In reality, there is a better way to iterate through the tree and search for its breath. And **for any successful coding interview, for any qualified interview candidate, the candidate should know better than writing algorithm in a brute-force way**. Especially in the case of this LeetCode problem. **Binary Tree Level Order Traversal problem is an excellent exercise for the Breath-First Search candidate knowledge demonstration.**

Let’s go and optimize the existing solution.

```
public class Solution {
public List
```> levelOrder(TreeNode root) {
List> results = new ArrayList<>();
if(root == null) {
return results;
}
Queue queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()){
int queueSize = queue.size();
List subResults = new LinkedList<>();
// This will loop n-times based on the size of queue in current moment
for (int i = 0; i < queueSize; i++) {
TreeNode treeNode = queue.remove();
if(treeNode.left != null) {
queue.add(treeNode.left);
}
if(treeNode.right != null) {
queue.add(treeNode.right);
}
subResults.add(treeNode.val);
}
results.add(subResults);
}
return results;
}
}

As you can see, we managed to eliminate one entire queue by checking queue size when iterating through the current level of tree breath.

While this algorithm is excellent, we still introduce a new reference on the variable for every iteration; and we did not fully utilize the full potential of `Queue`

data structure. It is possible to improve even this even differently.

```
public class Solution {
public List
```> levelOrder(TreeNode root) {
List> results = new ArrayList<>();
if(root == null) {
return results;
}
Queue queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
int queueSize = queue.size();
List subResults = new LinkedList<>();
// This will loop n-times based on the size of queue in current moment
for (int i = 0; i < queueSize; i++) {
if(queue.peek().left != null) {
queue.offer(queue.peek().left);
}
if(queue.peek().right != null) {
queue.offer(queue.peek().right);
}
subResults.add(queue.poll().val);
}
results.add(subResults);
}
return results;
}
}

Now the solution does not create a reference on a new element every iteration.

Rewriting this solution for this LeetCode problem several times is a good exercise for using Queue methods and knowledge of the Breadth-First Search algorithm.

**Note to remember**: **Learn following algorithmic structure by heart. It is a signal of good knowledge of data structures.**

All three tests provided by LeetCode are sufficient to cover the most important cases:

```
public class TestCases {
private static final boolean TRUE = true;
@Test
public void testLeetcodeBasicExamples() {
// Example 1
// root = [3,9,20,null,null,15,7]
TreeNode input = new TreeNode(3,
new TreeNode(9, null, null),
new TreeNode(20,
new TreeNode(15, null, null),
new TreeNode(7, null, null)));
List
```> result = Solution.levelOrder(input);
Assert.assertEquals(List.of(3), result.get(0));
Assert.assertEquals(List.of(9,20), result.get(1));
Assert.assertEquals(List.of(15,7), result.get(2));
// Example 2
// root = [1]
input = new TreeNode(1, null, null);
result = Solution.levelOrder(input);
Assert.assertEquals(List.of(1), result.get(0));
// Example 3
// root = []
input = new TreeNode(1, null, null);
result = Solution.levelOrder(input);
Assert.assertEquals(TRUE, result.isEmpty());
}
}

This article went through several stages of solving has LeetCode Binary Tree Level Order Traversal problem. First, we designed a rough brute-force leaky solution which we trough out the article turned to a fine-grained, edge-case handling solution that fully utilized Queue methods.

This LeetCode Binary Tree Level Order Traversal problem is an outstanding problem **to exercise Breath-First Search and Java Queue as data structure**.

Keep in mind edge conditions. As we have seen, there was a sneaky constraint that could be lethal during your coding interview. Always start with defining and realizing problem constraints; keep them somewhere on the edge of your board but always visible. Test your solution for edge cases before submission.

Do you know other ways how to solve this problem? Did you find a mistake in our solution? Or have you found a similar question on other platforms? Let us know in the comment to adjust the description, and your contribution will help others better solve this problem.

]]>

Given a binary tree, check whether it is symmetric at its root. You can understand the symmetry of a binary tree as a condition when the left branch of the tree from the root node is the mirror reflection of the right branch of the root node.

For example, this tree is symmetric, left branch from root is mirror reflection of right branch.

1 / \ 2 2 / \ / \ 3 4 4 3

However, this example of the tree is not. This tree is not symmetric; the left branch from the root is not a mirror reflection of the right branch.

1 / \ 2 2 \ \ 3 3

**Definitions:** A root is generally noting start of the tree. It can be interchangeably used as a start node for a branch of arbitrary length. A leaf is a node with no children. A branch is a node connecting one parent node and one or two child nodes.

- The number of nodes in the tree is in the range
`[1, 1000]`

`-100 <= Node.val <= 100`

When we look at problem constraints, we can see no condition we should be worried about. The number of nodes is relatively small, and the value of nodes is not essential. We care only about geometric symmetry. We will not really work with values (accept comparing value nodes on the tree levels).

For `TreeNode`

we will use predefined class which is provided by LeetCode platform.

```
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
```

The basic idea of our solution is to try to solve this problem in the simplest best-case scenario. We will take our simplest best case scenario from above, and we will bring its left and right node into the helping function `isSymmetric(TreeNode left, TreeNode right)`

. Here we will take all the possible scenarios of we will return the answer consequently.

```
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) {
return false;
}
return isSymmetric(root.left, root.right);
}
// Eliminate all the options
private boolean isSymmetric(TreeNode left, TreeNode right) {
if(left == null && right == null) {
return true;
}
if((left == null && right != null) || (left != null && right == null)) {
return false;
}
if(left.val != right.val) {
return false;
}
if(!isSymmetric(left.left, right.right)) {
return false;
}
if(!isSymmetric(left.right, right.left)) {
return false;
}
return true;
}
}
```

First we will ask if the nodes are `null`

. If they are tree is symmetrical. For example, tree with one element is symmetrical for left and right node `null`

.

Then we will take negative scenarios. What if left node has value and right is `null`

? Or vice versa? The tree is not symmetrical.

Do children nodes values equal? If yes, the tree is symmetrical. If not, the tree is not symmetrical.

And here comes the last part. Now we will take children nodes of children nodes of the root, and we will compare them against each other. But we will do it to compare the right sides for children of mirrored reflection. We are doing recursion, and we need to return a certain value as default. As we have accounted for all other cases in previous lines, if all is symmetrical, the tree is symmetrical, and we can return the default value as `true`

. Return value gives us a hint on how to handle the recursive call on unsymmetrical children of the children. If they are not symmetrical we need to return `false`

. And since we put recursive call into `if`

evaluation condition, negating the return value we can enter the `if`

block and return `false`

. This will secure us a recursive call on all conditions.

**Note to remember**: Try to solve this problem for the simplest best case scenario, when a tree has three symmetric levels. Solve all cases for the root node, continue recursively.

The recursive solution might be complex at first. But by slow approach debunking on smaller pieces, this recursion can be build up quickly.

This article showed you one recursive approach how to solve LeetCode problem number 101 regarding the symmetric tree. Start slowly with a simple best case scenario and figure out all the cases of symmetry of the tree on the way. A slow approach that considers all issues should help you to build an easily recursive solution.

Thanks for reading. Like us? Refer us to your friends and help us grow.

Have you found a similar question on other platforms? Let us know in the comment to adjust the description, and your contribution will help others be better at solving this problem.

]]>

Given a binary tree, check whether it is possible to find a path from the root to the leaf that will be equal to the target sum.

For example, in this tree, there exists a path from the root to the leaf with value 22:

5/ \48 / / \1113 4 / \ \ 721

There is a path of sum 22 if we connect `ThreeNode`

s 5 -> 4 -> 11 -> 2.

**Definitions:** A root is generally noting start of the tree. It can be interchangeably used as a start node for a branch of arbitrary length. A leaf is a node with no children. A branch is a node connecting one parent node and one or two child nodes.

- The number of nodes in the tree is in the range
`[0, 5000]`

. - Value of TreeNode can have range in
`-1000 <= Node.val <= 1000`

- Target sum of tree path can be in
`-1000 <= targetSum <= 1000`

In trees, we aim for the recursive solution. For the worst-case scenario, the tree will be one long uninterrupted chain of `TreeNodes`

with a length of 5000. In the case of a recursive solution, it will lead to 5000 frames on the stack.

Values or target sum in this problem does not matter. They are just integers numbers that we can easily represent in modern programming languages, and we do not have any other limitations on hardware.

For `TreeNode`

we will use predefined class which is provided by LeetCode platform.

```
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
```

And implementation of the Path Sum solution in Java is as follows:

```
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) {
return false;
}
return pathfinder(root, 0, targetSum);
}
private boolean pathfinder(TreeNode root, int currentSum, int targetSum) {
currentSum = currentSum + root.val
boolean pathFound = targetSum == currentSum;
// Left is not null, Right are not null
if (root.left != null && root.right != null) {
boolean leftPath = pathfinder(root.left, currentSum, targetSum);
boolean rightPath = pathfinder(root.right, currentSum, targetSum);
return leftPath || rightPath;
}
// Left is null, Right is not null
if (root.left == null && root.right != null) {
return pathfinder(root.right, currentSum, targetSum);
}
// Left is not null, Right is null
if (root.left != null && root.right == null) {
return pathfinder(root.left, currentSum, targetSum);
}
// Left is null, Right is not null
// if (root.left == null && root.right == null) {
return pathFound;
};
}
```

We will create helping function `pathfinder(TreeNode root, int currentSum, int targetSum)`

which will help us to push down the recursion additional value of current sum.

Inside the helping function `pathfinder`

we will make our decision based on the state of `TreeNode`

children. If both children are nulls, we know we came to the end of the path, and we can evaluate if the route to `TreeNode`

leaf is valid. Otherwise, we take every other case and handle it separately. In this way, we handle all children's state cases and control the boolean output of the recursive helper method.

And here is a simplified version of the code above:

```
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) {
return false;
}
return pathfinder(root, 0, targetSum);
}
private boolean pathfinder(TreeNode root, int currentSum, int targetSum) {
currentSum += root.val;
boolean pathFound = targetSum == currentSum;
if (root.left != null && root.right != null) {
return pathfinder(root.left, currentSum, targetSum) || pathfinder(root.right, currentSum, targetSum);
}
if (root.left == null && root.right != null) {
return pathfinder(root.right, currentSum, targetSum);
}
if (root.left != null && root.right == null) {
return pathfinder(root.left, currentSum, targetSum);
}
return pathFound;
}
}
```

**Note to remember**: Create a helper function that eliminates all existing cases of root children state.

You might encounter a simplified version of this solution in the form of a "one-liner". However, this solution is tough to read at first sight, and it is improbable you would write it on the first try. But it might come to you if you cut the solution into smaller pieces, into more understandable chunks of code.

```
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) {
return false;
} else if (root.left == null && root.right == null && sum - root.val == 0) {
return true;
} else {
return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val)
}
}
}
```

If we get to the bottom of the tree and the root element is `null`

, we do not find the path. We get to the `null`

root in case of invalid paths from the root to the leaf.

However, if we are at a higher level of the null root in its predecessor and it is a valid path from the tree root to its leaf, we check the left and right node for `null`

, and we check that path is the same target sum we desired. We do this by discounting the target sum with the root's value.

The last case of the recursive algorithm stands in all the other nodes in branches. When the left or right child is not null, we recursively discount the node (root) value from targetSum and hope on the next Stackframe for the best, what is, in our case, finding the path from the root to the leaf.

The last case of the recursive algorithm stands for all the other nodes in tree branches. When the left or right child is not `null`

, we recursively discount `TreeNode`

value from the target sum and hope on the next Stackframe for the best, in our case, finding the path from the root to leaf.

This article showed you two approaches to solving LeetCode problem number 112 regarding path sum. First, start slowly with small test cases of small trees and figure out all the states of `TreeNode`

children. Then, beginning with the "from a small to a big" approach should help you to build an easily recursive solution.

Thanks for reading. Like us? Refer us to your friends and help us grow.

Have you found a similar question on other platforms? Let us know in the comment to adjust the description, and your contribution will help others be better at solving this problem.

]]>