Insert Greatest Common Divisors in Linked List - Leetcode 2807 - Python

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

Key Takeaways

The video demonstrates how to insert the greatest common divisors into a linked list using the Euclidean algorithm and UKID's algorithm for greatest common divisor, with a time complexity of log M, and provides a step-by-step solution to the Leetcode problem 2807 in Python.

Full Transcript

hey everyone welcome back and let's write some more neat code today and you better not skip this video because we are finally going to be doing my favorite subject some math let's get into it insert greatest common divisors into linked list very very straightforward problem conceptually but the math I'm going to show you probably isn't easy but I think you'll understand it by the end of this video and who knows it might blow your mind take a look at this link list all we want to do is modify it all we want to do is insert a node here here and here between two adjacent nodes and we want to give it a particular value which is the greatest common diviser and we'll talk about that a bit more in depth but just to kind of go over the basic part imagine we have a pointer we're maintaining a pointer we're here this is our current pointer we're going to insert a node here only if there exists a next node if the next node is non null okay then what do we do well we take the next pointer here and set it to the new node that we're creating and we set the next pointer of that new node to the next node of this node so that's going to require a bit of pointer manipulation but nothing crazy the code will be pretty straightforward and then when we update our current pointer remember now that we have this node extra we can't just shift by one we have to shift by two so that we get to this node then we can insert a new node in between there and then after we do that it's going to look something like this the blue nodes are the new ones the values matter though the value has to be the greatest common divisor between these two so a number that divides this and divides this without a remainder that happens to be six because think about this for a second the greatest common divisor between these two can't possibly be greater than the minimum of them right like this could be the largest possible value that we have okay and then you know a brute force would be just counting down from here try six try five try four try three etc etc that would be Big O of n where n is not the size of the list but let's say n is the value of this I guess I'll call that M obviously in that case the time complexity is going to be n * m because we're going to insert roughly the same number of nodes that we have in terms of like the size of the list and if each node takes this much to compute like the value of that node that's going to be the time complexity but there's a algorithm a math algorithm called the greatest common divisor algorithm it's ukids algorithm for doing that a very famous mathematician and that algorithm actually runs in log M time where m is the minimum value between those two that's actually a built-in function if you just want to call the built-in function that's perfectly fine but I want to show you how to you know implement this algorithm from scratch it's not that long it's like literally three or four lines of code most people can probably write it out and if they can't they can look it up and then memorize it or whatever but I want to explain to you why it works I want to clear every doubt in your mind and don't you dare skip over this part suppose we have two numbers 48 and 18 their greatest common divisor I'll just just tell you is six but how do you compute it and how do you do it efficiently well let me I'll call this a and I'll call this B but this is the bigger number and this is the smaller number but ultimately this is what we're trying to do the first thing that we could try is just check if this number divides that then we're done right because this is the largest possible Factor we could have so if this divides that then we're good right now it doesn't right if it doesn't do that we care about what the remainder is the remainder is the key so I'm going to write out a formula there is some value it could be one the greatest common divisor between these two numbers could be one like for example with three and seven the greatest common divisor is one it could be one or it could be something else but whatever it is we call it g the greatest common divisor if B does not divide a then we can't just write a very simple formula like a / B is equal to X where would be the greatest common divisor we will have a remainder and that remainder can be kind of summarized with this equation like in this concrete example 48 / 18 well I think that's going to be two with a remainder of 12 the reason being 18 goes into 48 two times and it becomes 36 but if we add another 18 then it's going to go over 48 so the difference the remainder between these two is of course 12 that much makes sense sense so if we take the bigger number and mod it by the smaller number we will get the remainder of course in this case that's going to be 12 now I'm going to tell you why the algorithm works and then I'm going to prove it we started with these two values we're trying to find the gcd of these two the next step is going to be for us to take these two values and find the gcd of them until we get to a point where we can do this operation and get zero cuz if the remainder is then zero then we know that the smaller number divides both of them and then that number will be the result and you can kind of tell that this is going to be efficient it can't possibly be more than log n cuz we're taking a number and dividing it how many times can you take a number and divide it until it reaches one or zero well that's like by definition of log n and the base in this case actually is going to be bigger than two on average but anyways now let me prove to you why it'll work I'll just kind of simulate the rest of it so now we have 18 and 12 so now I'm going to take 18 and then mod it by 12 I get a remainder of six okay now I take these two numbers do the same thing I get 12 mod it by six now I have zero okay this is the magic number we got six this is our result but why does it work well it kind of goes back to this formula and a couple key points the first point is that any number that is a divisor of A and B is also going to be a divisor of B and R let's think about the extreme case where B is the divisor B is the divisor of a well in that case r would be zero and technically any number is a divisor of zero and point two is kind of the opposite of this any number that's a divisor of BR like a common divisor is also going to be a divisor of ab now if these two things are true the reason this is important is because if these two things are true then that means that the greatest common diviser of A and B is going to be the same as the greatest common divisor of B and R so essentially we're taking a big problem and turning it into a sub problem and we're doing that repetitively until we get to a smaller problem that we can actually solve and understand so now let me quickly demonstrate to you why these two points are true take a look at what we're doing over here when we have 48 and we're modding it by 18 we're doing this we're saying okay minus 18 1 okay it's it's uh 30 it's still greater than 18 okay minus 18 again okay now it's 12 okay now it's not greater than 18 so now we're good isn't it true that if there's a value I'll call it g or F like a divisor or a factor if it's a factor of 18 that just means that we can take that number multiply it by something and then get 18 in other words like if we sum this up a few times I don't know how many times but then we can get to 18 for example 6 is a factor of 18 you add six three times and you'll get 18 and suppose that that factor is common to this one as well so now I'm going to use the names for these this is a this is B so basically some value G exists which multiplied by let's call it X1 will equal a like that's the definition of a factor and let's say this is the greatest common factor and it's also a factor of B so b equal to G times let's call it X2 some number is going to equal B I'm starting to run out of space so I'm just going to use this like white line as a boundary so now I'm going to do a minus B and that's going to be this minus this but I'm going to factor out the G I'm going to say G is this X1 - X2 so what this proves here is that any difference between two numbers Like A and B if we take the difference between these that difference is going to have G as a factor right and so when we are doing the mod operation down here that's essentially what we're doing we're taking the smaller number and subtracting it from the bigger one so of course we expect these to have the greatest common divisor and then we do that operation multiple times and of course that should also have the greatest common divisor so I just proved to you 0.1 anything that divides A and B is also going to divide B and r i mean the fact that it'll divide B is Tri trivial but I just prove to you that it's also going to divide the remainder now I'm going to prove to you the second Point down here and this I'll do quickly suppose there's a number that divides R and I'll say R is equal to G * X1 actually I'm going to do X2 just because we know R is the smaller number in this case and I'll do the same thing over here B is equal to G * X1 now if you were to take these two um formulas substitute it in this you'll get something like this a is equal to this * Q I'm going to factor out the G I'm going to put G out there and then on the inside I'm going to have X1 * q and I'm going to put this replace it with r and I'm going to factor out the G so this is that so G the greatest common factor of B and R is obviously a factor of a I mean this formula kind of proves it you can divide both of these by G this formula proves it g * some number this formula is going to be some number is going to equal a so I just proved both of these to you I just proved that this algorithm works and I'm going to codee it up for you now and you're going to realize how trivial it is so let's code this up first things first let's just do the gcd part because that's going to be harder than the rest so I'm going to start with that while it's still fresh in our mind okay we have these two numbers let's assume that a is bigger than b and I'm going to do this while B is greater than zero eventually it'll reach zero we're going to do this we're going to replace a with B we're going to replace B with a a modded by B by doing it this way we preserve the fact that this is always going to be greater than or equal to this one and we're doing it iteratively because we don't want to do it recursively and lose U memory though it's possible to do this recursively and that's literally it so now you tell me what's the return value going to be are we returning a or b well B is eventually going to reach zero when it does a is going to be the greatest common divisor between them and we know it's the greatest common divisor between them because of the sub problem when we start with A and B and we replace them with b and the remainder those two numbers are guaranteed to have the same common divisor and so we keep doing this we keep solving the sub problem until we reach the base case when one of them is zero then the greatest common divisor between them is going to be the one that's nonzero so that's why it works and down here is going to be the easy part the link list part so current is going to be at the beginning of the link list while current. next is nonnull the reason why we don't just do while occur is because we want to insert nodes between two nodes so there must be a next node for us to insert the node into so I'm just going to get the two values between the nodes current and the current.next value and then I'm going to create a list node I'm going to give it a value of gcd of the these two so I'm going to copy that do gcd of these two and then I'm going to pass in for the next pointer of this new list node that we're creating I'm going to pass in the current uh next node so that it can be connected with it and then this I'm actually going to assign to current. next and then after that's done I'm going to shift current by two I'm going to set it to do next. next and at the end we want to return the head of the length list the head is not going to change because we're only inserting nodes between two adjacent noes we don't need a dummy node in this problem just return the original head now one question you might have if you're clever is how do you know I put the max here and I put the Min here what if I put the smaller one what if I put 18 for a and I put 48 for B what's going to happen let's look at it well a is going to be assigned to B A is going to end up being 48 and B is going to be assigned to 18 moded by 48 now you tell me what's the result of this mod it's just going to be 18 if you take a smaller number and mod it by a bigger one it's just going to be the smaller number so the Beautiful the elegant thing about this algorithm is it'll actually fix itself if you pass it in in the wrong order it'll still work I mean isn't that so beautiful I would even say it's better than sex not that I would know of course anyways let's finally run this and you can see it works and I promise you it's pretty efficient I think I probably had too much fun making this video anyways have a good day I'm going to go back to working on my system design newsletter

Original Description

🚀 https://neetcode.io/ - A better way to prepare for Coding Interviews 🧑‍💼 LinkedIn: https://www.linkedin.com/in/navdeep-singh-3aaa14161/ 🐦 Twitter: https://twitter.com/neetcode1 ⭐ BLIND-75 PLAYLIST: https://www.youtube.com/watch?v=KLlXCFG5TnA&list=PLot-Xpze53ldVwtstag2TL4HQhAnC8ATf Problem Link: https://neetcode.io/problems/insert-greatest-common-divisors-in-linked-list 0:00 - Read the problem 2:35 - Proving Euclid's Algorithm 10:05 - Coding Explanation leetcode 2807 #neetcode #leetcode #python
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from NeetCodeIO · NeetCodeIO · 0 of 60

← Previous Next →
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
16 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 the greatest common divisors into a linked list using the Euclidean algorithm and UKID's algorithm, and provides a step-by-step solution to the Leetcode problem 2807 in Python. The video covers concepts such as linked lists, greatest common divisors, algorithms, and time complexity, and provides practical examples and code snippets to illustrate the concepts.

Key Takeaways
  1. Create a list node with the GCD of two values
  2. Pass the next pointer of the new list node to the current next node
  3. Assign the new list node to current.next
  4. Shift current pointer by two to point to the next node
  5. Use UKID's algorithm to compute the greatest common divisor
  6. Repeat the process until the end of the linked list is reached
💡 The Euclidean algorithm and UKID's algorithm can be used to efficiently compute the greatest common divisor of two numbers, and can be applied to solve problems such as inserting the greatest common divisors into a linked list.

Related Reads

📰
O(N) Manacher's Algorithm with Mirror Boundary Optimization
Learn to optimize palindrome detection using Manacher's Algorithm with mirror boundary optimization, reducing time complexity to O(N)
Dev.to · Dipaditya Das
📰
Building a Power Grid Inside Minecraft with BFS Algorithms
Learn to build a power grid inside Minecraft using BFS algorithms and understand its relevance to cloud services
Dev.to · Carlos Cortez 🇵🇪 [AWS Hero]
📰
The Run-Length Encoding Trick: How Simple Strings Get Compressed
Learn how Run-Length Encoding (RLE) compresses simple strings, a fundamental technique in programming and data compression, and apply it to optimize storage and transmission of data
Medium · Programming
📰
75 Days of Leetcode — Day 4: #238 — Product of Array Except Self
Solve the Product of Array Except Self problem on LeetCode to improve coding skills and learn array manipulation techniques
Medium · AI

Chapters (3)

Read the problem
2:35 Proving Euclid's Algorithm
10:05 Coding Explanation
Up next
Stump Grinder Carbide Wheel Grinds Hardwood To Chips
Innoforge Studio
Watch →