Binary Prefix Divisible By 5 - Leetcode 1018 - Python

NeetCode · Beginner ·⚡ Algorithms & Data Structures ·7mo ago

Key Takeaways

The video solves the Leetcode 1018 problem, Binary Prefix Divisible By 5, using Python, and explains the process of creating an array of binary prefixes and checking if each prefix is divisible by 5.

Full Transcript

Hey everyone, welcome back and let's write some more neat code today. So today, let's solve the problem binary prefix divisible by five. It feels a little bit awkward uh making another elite code video after that last video I just made. Uh but anyways, let's get into it. So this is a pretty uh interesting problem, I guess, for an easy one at least. So we're given a binary array, meaning it's only going to contain zeros and ones. And basically they tell us that every I mean they don't use the word prefix. I guess they don't use it anywhere in the description, but they use it in the title. So title is kind of more descriptive than the problem statement. But basically every one of these prefixes here from the beginning to the end of the array represents a number. It's the binary representation of a number. And they make it pretty easy for us because the order the relative order of these is going to be preserved. So like they use this example and they say the first one is just one. And the reason they say the second one is two because you just take the second like the first two digits and then read them from left to right. The binary representation of two. That's what we have over here. And then lastly this one whether you go left to right or right to left it's the same but we still go left to right. And this is the binary representation of five. So for this we have the uh zero here which of course is going to be zero. And then here we have 0 1 which of course is uh one and then here we have four. So 0 1 1 and then that's going to be four. What we want then of all of these is we want to create an array of the same size as this. And so the first one we just want to know is this divisible by five. So we get that by taking this modding it by five. If we get a zero then it's divisible by five otherwise it's not. Right now this is. So then we can put a true in the first slot here. Second one 5 we're going to get a remainder. So that's false. 4 5 that's also false. So that's why this is the array that we would return for this. Couple parts to this question and really the trickiest part is the fact that the size of this array you have to be careful because the size of the array I think in the worst case could be this. And the key thing to note here is this is bigger than 32 and bigger than 64. So in most languages where you're going to probably use a 32 or 64-bit integer, this is too big for that. Python doesn't have that problem. So, you can kind of just get away with not reading the constraints in Python, but I feel like that's cheating. I'm probably I'll show you the code in Python. It's pretty similar to the code in C++, but I'm going to do the C++ one as well because I want to show you that the naive solution is not really going to work for C++. But the real solution, the better solution isn't much more difficult. So, first I want to show you how you can actually build these integers. It's pretty straightforward. Uh for the first here, we're just going to get a zero. For the next one to build this, we're going to take this zero, shift it to the left, and then we're going to get an empty slot over here. Empty slot is just another word for zero. So to that empty slot, we can take this bit and add it there. If it's a zero, nothing's going to happen. If it's a one, we're going to get that. So you can see it does look pretty correct. So same thing, if we want to build the next one, we take this entire thing and shift it to the left. You get zero, one, empty slot. Then you take this, you add it there, you get a one, and then you get what you want. Okay? So, building these isn't super hard. And then taking them, modding them by five also isn't super hard. But watch what's going to happen here. What if I had this big string of ones? And so, I don't even know what number this is anymore. Let's say I have a really big string of ones. Let's just say there's 10 of them for now. There's 10 one digits. I mean, the way I'm going to code this up, this would never happen, but I'm just trying to show you this. Like, this would never be more than like 32. And it would probably be much less than 32, actually. But, uh, so let's say we have these. And then let's say we have three more slots here. So, let's say that this here is any number except five because five can be represented with this right here. 1 0 1 is five. So there's two cases. This is kind of the thought process you have to go through here. There's two cases. Either what we have is divisible by five or it's not divisible by five. So if it is divisible by five, that's the easy case here because what's going to happen when you take a number like this one and you mod it by five, you're going to get zero. So my claim to you is when you take this number let's just call it cur whatever the current number is and then you mod it by five and let's say you get zero. My claim is we can safely replace the entire number the entire current number we can replace it with zero because it is divisible by five. And I'll show you why that's not going to negatively impact the next number that we end up looking at. And the answer is pretty simple because we take the current number. It's all we know is it's divisible by five. We don't know what the rest of these digits are. We don't really care. We don't care what number this ends up forming. It's divisible by five. Okay. And we know that when we look at the next number, all we're going to do is take cur and then shift it to the left by one. And then we're going to add whatever the digit that we look at, let's call that n. So why is it that if we ended up reassigning this to zero rather than the actual number that it actually was, why isn't that going to neg negatively impact anything? Because shifting a number to the left is equivalent to multiplying it by two. Cuz that's just like the definition of binary. Everything in the onees place goes to the two's place. Everything in the two's place goes to the four's place. Everything doubles. So if you take a number that was already divisible by five, then you double it. It's still divisible by five. If you double it again, it's still divisible by five. So, it doesn't matter that we got rid of it, that we we reset it down to zero. It doesn't matter. That was a good thing for us to do because now we don't have to take up too many bits. We're not going to get that overflow issue. So, that was the good thing about that. And then since we're not looking at those anymore, now we can actually focus on the relevant digits, the new digits. So, there's that case. Now, there's the other case. What if this was not divisible by five? Well, whatever it happens to be, it could either be less than five. So maybe it's something like this. It's four. Well, then it's going to stay the exact same. So taking cur modding it by five, it's going to leave it at what cur was if this is less than five. Now, it's true that we would end up getting rid of everything over here. But that's okay because none of those digits are even relevant anymore in terms of determining if this guy is divisible by five. So that's why uh this is good. Reassigning this after modding it by five is good cuz we're getting rid of the unnecessary digits that wouldn't even contribute in the first place. Now the other case is what if this number is not divisible by five but it's bigger than five. Well that would be something like this. I think that's a seven. So in this case we're kind of doing the same thing that we did where we chopped off all these digits but in this case we're not really fully chopping off the digit but we're saying that okay this is seven. uh after taking seven modding it by five we get two. So we're saying that we can take this and we can reset it down to two. And the reason that's fine is because when we take this two now and we shift it to the left, it's going to become a four. So if I just do the math for you, which is we had seven, what we would have originally done is we would have shifted that to the left and it would have turned into a four. And then if you take that and you mod it by five, you would get four, right? You'd still eliminate the two fives. Now, I didn't do that. I took seven, I modded it by five. Then I got a two left over. And now I'm going to shift that to the left. So now it's going to become a four. You mod that by five, it's still a four. So the math works out in every one of these cases. And I if you thought that this was kind of overexlaining why this works, I would partially agree with you because the main intuition, the main intuition of why all this stuff works is the fact that we're taking this number, we're shifting it to the left, which is effectively doubling it. And doubling a number is not going to cause any problems. It's not going to make anything inconsistent when we're modding that number by any number. Whether it was five or whether this was a prime number, it wouldn't matter because by definition, if n is divisible by five, then 2 * n is also going to be divisible by five. If it was not divisible by 5, then by definition, 2 * n is also not going to be divisible by five. And also that the the number the modding is going to be consistent. The result is always going to be consistent. But anyways, this explanation got a little bit messy. So if you still don't understand it, I think you will once I get into the code. So, let's go ahead and do that. But, does anybody have any questions? Huh? There's nothing wrong with having questions. Okay, that's not what I was trying to say. I just think that people are doing themselves a disservice if they don't at least try to answer their own questions because I think a lot of the time people are smart enough to do so. They just don't believe that they can. It's all I was trying to say. Okay. So, I'm going to go ahead and create my result array. I'm going to keep track of my current number zero, which is initially going to be zero. I'm going to go through every number in my list of nums and I'm going to take the current number and I'm firstly I'm going to shift it to the left initially when this was zero. It's not going to do anything. So that's fine. Then to that I'm going to add the current number and whether it's zero or one. I'm going to assign that back to cur. I'm not going to do the modding. I'm not going to update cur with the mod. I'm I'm going to use the mod with the result. So before I append to the result, I'm going to say is cur divisible by five. If that's zero, then this is obviously going to evaluate to true. If it's not, it's going to be false. And then here I can return the result. And this works in Python because integers are arbitrarily large. They are we're not going to have to worry about any overflow. And so on the left here, you can see that it works. It's pretty efficient. But there is a bug with this. And the bug doesn't really show until you use a different language. So this is pretty much the same code in a C++. I'm taking the number, shifting it to the left, adding n, and then I'm taking the boolean, and then appending that to the result. And if I try to run this, we're going to get an error. And notice the example right here. Notice this example right there. How many integers do we have here? Well, if you're too lazy to count, um, I just do like a quick controll. So, I'm going to control F for the comma. So, you can see the first one is the second one on the page. And I'm just going to keep going through this until we get to the last one. And you'll see that this is the 39th. So obviously this is more than 32. I was trying to store it in a 32-bit integer. And that's why we had an issue. It overflowed. So we can take this and mod it by five so that this cur will never be bigger than 32. And in fact, it'll never be I don't think any bigger than like a three or four bit integer. And then we can use that and still mod it by five and see if it was divisible by five. And again, by doing that, we're not messing up the number for future iterations because every time we shift it to the left, it is doubling, which is not going to cause any problems. So now I'm going to just go ahead and take this and run it. You can see here, this one works now, and it is efficient. Okay, but seriously, does anybody does anybody have any questions? because I can think of at least one pretty good question and I didn't cover it in this video. So, you might honestly have had that question, especially if you're somebody who, you know, thinks pretty deeply about things. I talked about how overflowing is going to mess things up. But why is it going to mess things up? What's going to happen if it overflows? Because I mean, let's say we have a 32-bit integer. And let's let's just say let's just use a few ones, right? And let's say these are the most significant bits. So let's say this is the 302 bit, the most significant one. And so when I bit shift that to the left, I'm getting rid of that information. When we mod by five, I said getting rid of that information, that's not a problem. And I kind of explained why. But why is shifting this to the left and getting rid of that an issue? That's not modding it by five. That's not getting rid of a multiple of five from this number. That's getting rid of a power of two, a very significant power of two. So like 2 to the power of 31. And the reason that's a problem is because that number is specifically not a power of five. If it was a power of five, it wouldn't matter. If this problem was prefixes divided by two, that would not be a single problem for us. It wouldn't matter. The fact that it's not is like imagine that shifting it to the left is getting rid of like 17 from the original number. Obviously, that's going to cause issues cuz that's not a multiple of five that we're getting rid of, which just cancels everything out. This is different. That has a remainder of two. That's going to mess things up. So, that's why. Anyways, I think most people probably don't really care at this point, but I find this stuff really interesting. I find it worth thinking about, I think. But anyways, if you found this useful, check out necode.io for a lot more. Thanks for watching.

Original Description

🚀 https://neetcode.io/yt - 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://leetcode.com/problems/binary-prefix-divisible-by-5/ 0:00 - Read the problem 0:30 - Drawing Explanation 10:05 - Coding Explanation leetcode 1018 #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 solve the Leetcode 1018 problem, Binary Prefix Divisible By 5, using Python, and explains the process of creating an array of binary prefixes and checking if each prefix is divisible by 5. The solution involves building integers from the binary prefixes and then checking if they are divisible by 5. The video also discusses how to prevent overflow when shifting numbers to the left.

Key Takeaways
  1. Build integers from the binary prefixes
  2. Take the current number modulo 5 to check if it is divisible by 5
  3. Replace the current number with 0 if it is divisible by 5
  4. Shift the current number to the left by one to prepare for the next iteration
  5. Add the next digit to the current number to update it for the next iteration
  6. Append to the result array based on whether the current number is divisible by 5
💡 The key insight is that shifting a number to the left doubles it, which does not cause problems when checking for divisibility by 5, and taking the remainder when divided by 5 prevents overflow.

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
10:05 Coding Explanation
Up next
Stump Grinder Carbide Wheel Grinds Hardwood To Chips
Innoforge Studio
Watch →