Insert into a Binary Search Tree - Leetcode 701 - Python

NeetCodeIO · Intermediate ·⚡ Algorithms & Data Structures ·3y ago

Key Takeaways

The video teaches how to insert a node into a binary search tree, covering both recursive and iterative solutions, with a focus on handling edge cases and understanding time and memory complexity. It uses Python to implement the solutions for Leetcode problem 701.

Full Transcript

hey everyone welcome back and let's write some more neat code today so today let's solve the problem insert into a binary search tree we're given the root of a binary search tree and a value that we want to insert into the tree and then we want to return the new root of the tree also it is guaranteed that the new value does not exist in the original BST and they also clarify that there are multiple ways to solve this problem there's multiple ways to insert into a binary search tree and we can return any of them thankfully now before we get started on the solution let's actually break this problem down there's a few key points to notice first of all this is a binary search tree not just a regular binary tree so there is a sorted property to the tree remember that for every single node in the tree every node in the left subtree of that node is going to be less than the value here four it's going to be less than 4 and every value in the right subtree is going to be greater than 4 and this property is recursive so it's not just true for the root node it's true for every single node in the tree now they also clarified that we're guaranteed that the new value that we're inserting in this case 5 does not already exist in the tree that's very important because that's first of all usually the case with binary search trees but it's also important because we need to find a position that we can insert this five in now technically if we wanted to we could put the 5 in the root spot and then like rebalance the entire tree around the new root value that's kind of a difficult way to do this now the simple way to do this you might already remember if you took a data structures and algorithms class but I really want to emphasize the thought process behind this problem because it's very trivial for me to solve it because I kind of know exactly how to do it the easiest way you start at the root and you basically keep searching until we get to a null position now how do you search while you use the sorted proper if we're inserting a 5 is that greater than four or less than four we know it's definitely not going to be equal to any node in the entire tree it's never going to happen we're either going to go to the right or we're going to go to the left in this case 5 is greater we're going to go to the right now for 7 are we going to the left or are we going to the right we're going to go to the left and now we reached a null position we're guaranteed to reach a null position because like I said we know for sure 5 does not already exist in the tree so every time we get to a new node we're either going to go left or we're going to go right now unless the tree is infinitely large we know for sure we're going to reach a null position and that's where we want to insert this 5 into so we put the 5 over here and you can see that's pretty much what they had in the output now how do we actually code this up well there's two ways to do it we can do it the iterative way or we can do it the recursive way let's compare and contrast these two different ways to do this very quickly if we do this iteratively we're going to start at the root and then we're going to go to seven and then we're going to end up at a null position now how do we actually insert a node here well we would want to connect this node and add a left child for it a five so therefore we don't really want our pointer to end over here because we need access to the parent node so we would want to stop at the point where we see that okay we want to go left but left is null so therefore we stop and we go ahead and insert the node that's a pretty easy and doable way to do this we could also do it the recursive way which I think is a little bit trickier because there's a very important Edge case here that I want to emphasize what happens if we have an empty tree we want to insert five into an empty tree because remember we actually have to return the root of the node of the binary search tree and in this case we'll have a new root node if our tree is empty then we have a new root node so in the iterative solution I think it's pretty easy because all you have to do is create a node and then return it but for the recursive solution it's a bit different because for the recursive solution we're actually handling that edge case that I talked about in both cases because in the recursive solution when we get to the null position over here we actually want to create that node 5 and then return it up to its parent and then from its parent we're going to say we inserted a new node into the left subtree and then we return to that tree so we're going to take that tree and set it to the left child of seven I think the recursive solution is a bit harder but I think it's also more powerful because you can apply it to other problems more easily and I think it's really important to understand so I'm going to be focusing on the recursive solution when we code it up right now but I'll also briefly show the iterative solution towards the end before we move on what would be the time complexity of inserting a node well first of all how are we going to measure it we can measure it based on the size of our binary search tree let's say n is the number of nodes in our tree and we could also measure it using the height of the tree let's say h is the height of our tree technically in the worst case this is going to be the time complexity Big O of H because we don't have to visit every single node we're going to every step either go left or go right so we're just going to basically have like a chain like this which is going to be the length of the height of the tree in the worst case though we might not have a balanced tree it might just look something like this technically the worst case time complexity could also be Big O of N I like to say Big O of H though because it's more accurate I think because H could be equal to N I think it's more correct to say that the time complexity is the height of the tree it's also worth mentioning though that the recursive solution takes extra memory because we have a call stack we're going to do it recursively we're going to call a function here we're going to call a function here we're going to keep doing that basically same thing the height of the tree so the memory complexity is going to be a big O of H whereas if we do it iteratively we don't have a call stack we just have a pointer that we keep shifting and therefore the memory complexity of that will be constant Big O of one okay now let's code it up remember the first Edge case what if we have an empty tree well then we basically want to create a new tree node we can do that with the Constructor passing in the value parameter that we're given and this is what we want to return after we've created a new tree otherwise we know we have to keep searching until we do reach null we know we're going to reach it eventually but we have to figure out which direction we want to go in is the value greater than the current value that we're at the current node that we were given if it is then we want to call insert on the right subtree passing in the exact same value of course now here's where things can get a bit confusing remember after we insert into the right sub tree what if the right subtree of the root is null that means what this insert function would do is it would just create a new tree node and then return it but if we return it like this we're not doing anything with it then root Dot right will still equal null so to change that we want root dot right to be equal to the new node that we just inserted and we want to do the exact same thing in the opposite case where our value would be less than root dot val I don't have to specify that here though because we know for sure value is never going to be equal to root dot val so I'm just going to copy and paste this and just change a couple values we want to do this now on the left side of the tree because our value is less than the current root value that we're at so we basically just change this now the last thing here is after we do that we still need to return the root the reason being what if root dot right here when we pass it in to the insert function is non-null then we would basically call insert end up in this function and then maybe we'd have to call insert again going either of the directions and keep doing that multiple times so in that case the root actually would not change the route that this insert function would call would not change we would want to return it and then keep assigning it to root dot right that would not do anything in that case where it's not changing but we know we still have to have these assignments in the case that the return value did change which would of course only happen if the route that we passed was null and then we created a new node and then returned that so let's run this to make sure that it works and as you can see yes it does and it's pretty efficient now let me briefly show you the iterative solution so this is the iterative solution we have the same base case if we are given an empty tree we just create a node and then return it otherwise we set our current Warner equal to the root and I just go while true because we know we're going to keep going until we reach null and the way I wrote this we never need to break out of this while loop because I'm just returning root inside of these but you know you could have done it the other way that's up to your preference but logically this is mostly the same if the value we want to insert is greater than the current value we go to the right otherwise we go to the left now what happens if we can't go any further to the right then we go ahead and insert the new node because we know we found the null pointer and then we return the root notice how what I'm returning is not Cur I'm returning the root because that's what we want to return for this insertion otherwise though if we didn't find the null pointer then we go ahead and just say Cur is equal to Cur dot right we're doing logically the exact same thing on the left side of the tree as you can see below and that's pretty much the iterative solution I'll go ahead and run it to make sure that it works and as you can see yes it does and it's pretty much just as efficient in terms of memory it's probably a bit more efficient if this was helpful please like And subscribe if you'd like to see code solutions for languages other than python check out neat code.io it's got a ton of free resources to help you prepare for coding interviews thanks for watching and hopefully I'll see you pretty soon

Original Description

🚀 https://neetcode.io/ - A better way to prepare for Coding Interviews Problem Link: https://neetcode.io/problems/insert-into-a-binary-search-tree 0:00 - Read the problem 0:30 - Drawing Explanation 5:58 - Coding Explanation leetcode 701 #neetcode #leetcode #python
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from NeetCodeIO · NeetCodeIO · 16 of 60

1 Leetcode 149 - Maximum Points on a Line - Python
Leetcode 149 - Maximum Points on a Line - Python
NeetCodeIO
2 Design Linked List - Leetcode 707 - Python
Design Linked List - Leetcode 707 - Python
NeetCodeIO
3 Minimum Time to Collect All Apples in a Tree - Leetcode 1443 - Python
Minimum Time to Collect All Apples in a Tree - Leetcode 1443 - Python
NeetCodeIO
4 Design Browser History - Leetcode 1472 - Python
Design Browser History - Leetcode 1472 - Python
NeetCodeIO
5 Number of Good Paths - Leetcode 2421 - Python
Number of Good Paths - Leetcode 2421 - Python
NeetCodeIO
6 Flip String to Monotone Increasing - Leetcode 926 - Python
Flip String to Monotone Increasing - Leetcode 926 - Python
NeetCodeIO
7 Maximum Sum Circular Subarray - Leetcode 918 - Python
Maximum Sum Circular Subarray - Leetcode 918 - Python
NeetCodeIO
8 Find Closest Node to Given Two Nodes - Leetcode 2359 - Python
Find Closest Node to Given Two Nodes - Leetcode 2359 - Python
NeetCodeIO
9 Concatenated Words - Leetcode 472 - Python
Concatenated Words - Leetcode 472 - Python
NeetCodeIO
10 Data Stream as Disjoint Intervals - Leetcode 352 - Python
Data Stream as Disjoint Intervals - Leetcode 352 - Python
NeetCodeIO
11 LFU Cache - Leetcode 460 - Python
LFU Cache - Leetcode 460 - Python
NeetCodeIO
12 N-th Tribonacci Number - Leetcode 1137
N-th Tribonacci Number - Leetcode 1137
NeetCodeIO
13 Best Team with no Conflicts - Leetcode 1626 - Python
Best Team with no Conflicts - Leetcode 1626 - Python
NeetCodeIO
14 Greatest Common Divisor of Strings - Leetcode 1071 - Python
Greatest Common Divisor of Strings - Leetcode 1071 - Python
NeetCodeIO
15 Shortest Path in a Binary Matrix - Leetcode 1091 - Python
Shortest Path in a Binary Matrix - Leetcode 1091 - Python
NeetCodeIO
Insert into a Binary Search Tree - Leetcode 701 - Python
Insert into a Binary Search Tree - Leetcode 701 - Python
NeetCodeIO
17 Delete Node in a BST - Leetcode 450 - Python
Delete Node in a BST - Leetcode 450 - Python
NeetCodeIO
18 Shuffle the Array (Constant Space) - Leetcode 1470 - Python
Shuffle the Array (Constant Space) - Leetcode 1470 - Python
NeetCodeIO
19 Fruits into Basket - Leetcode 904 - Python
Fruits into Basket - Leetcode 904 - Python
NeetCodeIO
20 Number of Subarrays of size K and Average Greater than or Equal to Threshold - Leetcode 1343 Python
Number of Subarrays of size K and Average Greater than or Equal to Threshold - Leetcode 1343 Python
NeetCodeIO
21 Naming a Company - Leetcode 2306 - Python
Naming a Company - Leetcode 2306 - Python
NeetCodeIO
22 As Far from Land as Possible - Leetcode 1162 - Python
As Far from Land as Possible - Leetcode 1162 - Python
NeetCodeIO
23 Shortest Path with Alternating Colors - Leetcode 1129 - Python
Shortest Path with Alternating Colors - Leetcode 1129 - Python
NeetCodeIO
24 Minimum Fuel Cost to Report to the Capital - Leetcode 2477 - Python
Minimum Fuel Cost to Report to the Capital - Leetcode 2477 - Python
NeetCodeIO
25 Count Odd Numbers in an Interval Range - Leetcode 1523 - Python
Count Odd Numbers in an Interval Range - Leetcode 1523 - Python
NeetCodeIO
26 Contains Duplicate II - Leetcode 219 - Python
Contains Duplicate II - Leetcode 219 - Python
NeetCodeIO
27 Path with Maximum Probability - Leetcode 1514 - Python
Path with Maximum Probability - Leetcode 1514 - Python
NeetCodeIO
28 Add to Array-Form of Integer - Leetcode 989 - Python
Add to Array-Form of Integer - Leetcode 989 - Python
NeetCodeIO
29 Unique Paths II - Leetcode 63 - Python
Unique Paths II - Leetcode 63 - Python
NeetCodeIO
30 Minimum Distance between BST Nodes - Leetcode 783 - Python
Minimum Distance between BST Nodes - Leetcode 783 - Python
NeetCodeIO
31 Design Hashmap - Leetcode 706 - Python
Design Hashmap - Leetcode 706 - Python
NeetCodeIO
32 Range Sum Query Immutable - Leetcode 303 - Python
Range Sum Query Immutable - Leetcode 303 - Python
NeetCodeIO
33 Binary Tree Zigzag Level Order Traversal - Leetcode 103 - Python
Binary Tree Zigzag Level Order Traversal - Leetcode 103 - Python
NeetCodeIO
34 Middle of the Linked List - Leetcode 876 - Python
Middle of the Linked List - Leetcode 876 - Python
NeetCodeIO
35 Course Schedule IV - Leetcode 1462 - Python
Course Schedule IV - Leetcode 1462 - Python
NeetCodeIO
36 Single Element in a Sorted Array - Leetcode 540 - Python
Single Element in a Sorted Array - Leetcode 540 - Python
NeetCodeIO
37 Capacity to Ship Packages - Leetcode 1011 - Python
Capacity to Ship Packages - Leetcode 1011 - Python
NeetCodeIO
38 IPO - Leetcode 502 - Python
IPO - Leetcode 502 - Python
NeetCodeIO
39 Minimize Deviation in Array - Leetcode 1675 - Python
Minimize Deviation in Array - Leetcode 1675 - Python
NeetCodeIO
40 Longest Turbulent Array - Leetcode 978 - Python
Longest Turbulent Array - Leetcode 978 - Python
NeetCodeIO
41 Last Stone Weight II - Leetcode 1049 - Python
Last Stone Weight II - Leetcode 1049 - Python
NeetCodeIO
42 Construct Quad Tree - Leetcode 427 - Python
Construct Quad Tree - Leetcode 427 - Python
NeetCodeIO
43 Find Duplicate Subtrees - Leetcode 652 - Python
Find Duplicate Subtrees - Leetcode 652 - Python
NeetCodeIO
44 Sort an Array - Leetcode 912 - Python
Sort an Array - Leetcode 912 - Python
NeetCodeIO
45 Ones and Zeroes - Leetcode 474 - Python
Ones and Zeroes - Leetcode 474 - Python
NeetCodeIO
46 Remove Duplicates from Sorted Array II - Leetcode 80 - Python
Remove Duplicates from Sorted Array II - Leetcode 80 - Python
NeetCodeIO
47 Maximum Twin Sum of a Linked List - Leetcode 2130 - Python
Maximum Twin Sum of a Linked List - Leetcode 2130 - Python
NeetCodeIO
48 Concatenation of Array - Leetcode 1929 - Python
Concatenation of Array - Leetcode 1929 - Python
NeetCodeIO
49 Symmetric Tree - Leetcode 101 - Python
Symmetric Tree - Leetcode 101 - Python
NeetCodeIO
50 Check Completeness of a Binary Tree - Leetcode 958 - Python
Check Completeness of a Binary Tree - Leetcode 958 - Python
NeetCodeIO
51 Construct Binary Tree from Inorder and Postorder Traversal - Leetcode 106 - Python
Construct Binary Tree from Inorder and Postorder Traversal - Leetcode 106 - Python
NeetCodeIO
52 Find Peak Element - Leetcode 162 - Python
Find Peak Element - Leetcode 162 - Python
NeetCodeIO
53 Accounts Merge - Leetcode 721 - Python
Accounts Merge - Leetcode 721 - Python
NeetCodeIO
54 Binary Tree Preorder Traversal (Iterative) - Leetcode 144 - Python
Binary Tree Preorder Traversal (Iterative) - Leetcode 144 - Python
NeetCodeIO
55 Binary Tree Postorder Traversal (Iterative) - Leetcode 145 - Python
Binary Tree Postorder Traversal (Iterative) - Leetcode 145 - Python
NeetCodeIO
56 Number of Zero-Filled Subarrays - Leetcode 2348 - Python
Number of Zero-Filled Subarrays - Leetcode 2348 - Python
NeetCodeIO
57 Minimum Score of a Path Between Two Cities - Leetcode 2492 - Python
Minimum Score of a Path Between Two Cities - Leetcode 2492 - Python
NeetCodeIO
58 Sqrt(x) - Leetcode 69 - Python
Sqrt(x) - Leetcode 69 - Python
NeetCodeIO
59 Successful Pairs of Spells and Potions - Leetcode 2300 - Python
Successful Pairs of Spells and Potions - Leetcode 2300 - Python
NeetCodeIO
60 Optimal Partition of String - Leetcode 2405 - Python
Optimal Partition of String - Leetcode 2405 - Python
NeetCodeIO

This video teaches how to insert a node into a binary search tree using both recursive and iterative solutions in Python, covering edge cases and complexity analysis. It's essential for understanding fundamental data structures and algorithms. By following this lesson, you'll be able to implement binary search tree insertion and analyze its efficiency.

Key Takeaways
  1. Create a new tree node when inserting into an empty tree
  2. Call insert on the right subtree if the value is greater than the current value
  3. Handle the edge case of inserting a node into a null position in the recursive solution
  4. Create a new tree node and return it in the iterative solution
  5. Analyze time complexity as Big O of H, the height of the tree
  6. Analyze memory complexity of the recursive and iterative solutions
💡 Understanding the trade-offs between recursive and iterative solutions is crucial for efficient algorithm design, especially considering time and memory complexity.

Related AI Lessons

Bloom Filters, Explained Properly
Learn how Bloom filters work and their benefits, including tiny memory and blazing speed, in exchange for potential false positives.
Dev.to · Daksh Gargas
Prefix Sums: The Preprocessing Trick That Makes Range Queries Instant
Learn how prefix sums enable instant range queries in arrays, boosting performance in various applications
Medium · Programming
I Thought I Was Ready for the Interview — Then One Simple Math Question Destroyed Me
A simple math question can destroy a developer's interview, highlighting the importance of being prepared for unexpected questions
Medium · Programming
Week 2(Day 10): LeetCode Two Pointers(slow & fast): Remove Duplicates from Sorted Array (Brute…
Learn to remove duplicates from a sorted array using the two pointers technique, improving from brute force to optimized solutions
Medium · Python

Chapters (3)

Read the problem
0:30 Drawing Explanation
5:58 Coding Explanation
Up next
Stump Grinder Carbide Wheel Grinds Hardwood To Chips
Innoforge Studio
Watch →