Hands down the best explanation for linked list. It finally clicked on me after 3 days banging my head against the wall. His algorithms are way more intuitive, both iterative and recursive versions, much much more than what other instructors talked about. Thank you!
08:25 one small correction, the order of inserting a node to a linkedlist is that the node you wish to enter has to point first to the node and then you have to take node b to point on node q, if you start by pointing b to q first you will lose all the data of c and d. Great video !! loved it
Bro you explain so good that i've been able to perform the tasks without watching the whole video. Just got the idea and solved it by myself. I love you, Alvin. Happy New Year, mate!
This is all you need to learn about linked-list. This is my fifth time viewing and I always seem to comeback and learn something new. It is such an amazing resource. Thanks @Alvin
Thank you for this Alvin. I had a hard time refreshing linked list by watching countless tutorials and I can't understand why I can't move on with problems. While you are explaining, I am able to answer problems!
For the iterative Zipper implementation, we need a null check for head1 (ideally for head2 as well). if(head1 === null) return head2; if(head2 === null) return head1;
I just realized watching theory tutorials in other languages actually makes learning so much more intuitive, since you can't just blindly copy. You're forced to understand how your language works, and you're forced to implement those ideas without really being able to "cheat". Wow. I'm gonna start watching C tutorials and do them in python. I'm about to hit 10x developer once I understand all this
This is a very good point. I never realized this. This whole time I was trying to avoid tutorials in different languages, not realizing that they were the key to helping my solidify my understanding. Good observation!
I wish you had Java as one of the programming languages, but I still loved your course and was able to interpret everything in Java because of how you explained the algorithms, it was so simple to even understand recursive, something I always mess up. Thank you!!
Awesome vids helping me with my uni subject Foundations of Programming, they give us 15 small programming exercises every week for points that count to final mark and also credit and they gave us exercises such as programm ringbuffer using linked list, program queues and stack using linked list. Merge two ordered linked lists and so on xd
The best I have seen so far...Thank you so much... I just checked your platform to make a purchase to go deeper but I couldn't find C# language option (that's my core language). I don't know if there will be room for that in the future? I greatly benefited from this JavaScript version.
for zipperlist iterative approach, when you add the rest of the list that is leftover tail isn't reassigned to be the new tail. In this case, you're just using "tail" as a pointer to the current end of the constructed list. And tail isnt assigned at all in the recursive solution. Would there be an extra step to iterate through the leftover list to the end and reassign tail? Thanks for your great videos 🔥🔥🔥
At least one error you will get is that you will be stuck in a loop. ptrA and ptrB are pointers and not booleans. Their values will likely be non-zero which will be interpreted as true. You need " While (ptrA != nullptr &&...) ". Something like that. Here is my code which I think works how you intended. /// Assumes that neither list is empty. void * zip(Node* f, Node* s){ while(f != nullptr && s != nullptr){ // Save next pointer. Node* n = f->next; // Point element from this list to other list. f->next = s; // Update first and second node. f = s; s = n; } }
not gonne lie thought this video was gonna be a waste of my time but I learned linked lists in just the first 15 mins of the video and was able to swift by these easily.
I solved ZipperList iteratively without a counter to toggle between the two lists because at the start, i position the tail at the end of the initially constructed zipped list then within the while loop i construct the next node as a linkedlist of two nodes (current1.val) -> (current2.val) and then i update the tail and set the constructed two-nodes-list as its next then i refer to the last node of two-nodes-list i have just added as the new tail. private static Node zipListsIterative(Node head1, Node head2) { Node zipped = new Node(head1.getVal(), new Node(head2.getVal())); Node tail = zipped.getNext(); Node current1 = head1.getNext(); Node current2 = head2.getNext(); while (current1 != null && current2 != null) { Node next = new Node(current1.getVal(), new Node(current2.getVal())); tail.setNext(next); tail = next.getNext(); current1 = current1.getNext(); current2 = current2.getNext(); } if (current1 == null) tail.setNext(current2); if (current2 == null) tail.setNext(current1); return zipped; } and recursively, i wrote the recursive case as one liner by making use of the constructor: Node(String val, Node next) private static Node zipListsRecursive(Node head1, Node head2) { //base cases if (head1 == null && head2 == null) return null; if (head1 == null) return head2; if (head2 == null) return head1; //recursive case return new Node(head1.getVal(), new Node(head2.getVal(), zipListsRecursive(head1.getNext(), head2.getNext()))); }
My Recursive Solution for Zipper List is MORE concise and easier to learn: const zipperLinkedListRec = (head1, head2) => { if (!head2) return; let temp = head1.next; head1.next = head2; zipperLinkedListRec(head2, temp); return head1; }; *This assumes that both lists are non-empty like in video
Yup, and because you're hopping through so many pointers, you get a lot more cache misses than an array, more often than not making it slower than an array in practice.
this is literally the best video I seen on this. However, you said it can be anything in the data. However, in C# and Java would be different. it would have to be what you choose it to be because you have to initialize the type of data it has to enter so all the nodes would have integers. Am I right or am I wrong?
i think insertion in time complexity is O(n) in worst case this is most significant for linked list because we cant reach index till we reach the previous one and so on .. that's right ?
Realy nice teaching style. Just one question. @ 37:00 it says the space is O(n) for the recursive sumList function. That is true for how it is implemented. But couldn't we also achieve O(1) by passing the sum variable into every recursion like it's done with the recursive linkedListValues? Wouldn't hat be much more optimised?
From what I understand, space complexity of O(n) means, in the worst case there will be 'n' call stacks ( i.e when we reach the tail of the linklist), thus passing the integer as a argument will still create n call stacks, hence O(n).
@@iamlookto Must be a mistake, because the memory complexity is determined by the number of return statements because each function call will be stored on the program stack. To generalize, a recursive function's memory complexity is O(recursion depth). As our tree depth suggests, we will have n total return statements and thus the memory complexity is O(n).
I've watched sooooooooo many UA-cam tutorials - this guy is legit the best teacher I've come across so far! Very clear. Thank you so much Alvin
I love Alvin's way of teaching. I loved his Dynamic programming video. Please ask him to make some more videos like Graphs and Trees.
He already made videos on those topics bruh
Graphs: ua-cam.com/video/2_Uuixtc5i0/v-deo.html
Same here
@@spaceface2288 He's going to love them.
Hands down the best explanation for linked list. It finally clicked on me after 3 days banging my head against the wall. His algorithms are way more intuitive, both iterative and recursive versions, much much more than what other instructors talked about. Thank you!
08:25 one small correction, the order of inserting a node to a linkedlist is that the node you wish to enter has to point first to the node and then you have to take node b to point on node q, if you start by pointing b to q first you will lose all the data of c and d. Great video !! loved it
yup, q.next = c then b.next = q
Oof, hate when people teach wrong things, they should have re edited the video
This is the only programming video I watched from start to finish with one sitting and I clearly understood LinkedList. Thank you Alvin!
Started learning linked list this week and could not understand the code for it at all until this video... Super appreciative, this community exists.
Bro you explain so good that i've been able to perform the tasks without watching the whole video. Just got the idea and solved it by myself. I love you, Alvin. Happy New Year, mate!
same!
This is all you need to learn about linked-list. This is my fifth time viewing and I always seem to comeback and learn something new. It is such an amazing resource. Thanks @Alvin
Alvin is so to the point and voice is good to hear 🙌
Thank you for this Alvin. I had a hard time refreshing linked list by watching countless tutorials and I can't understand why I can't move on with problems. While you are explaining, I am able to answer problems!
your courses're amazing!! I have an interview with google in a couple of hour, I hope your courses work for me !!!
did they
Best explanation ever Now I'm much more confidence writing link list problem.
Best video on LL’s that I’ve seen. Thank you, Teacher Alvin!
Absolutely the best tutorial video on linked lists. Thank you so much, Alvin! Fantastic teacher.
I love that you said "A"'s next is "B". That makes link list much easier to conceptualize than other sources which overly complicate it.
That's exactly how I see it
Given a blind like because of Alvin👍…and added to my “Immediate watch” list 😀
I love the way he explain and able to grasp things even though I am a beginner.
I love Alvin's way of teaching! He's really a master! Thank you very much!
man this is the best explanation ever.
seeing alvin puts a smile on my face :)
Same.
For the iterative Zipper implementation, we need a null check for head1 (ideally for head2 as well). if(head1 === null) return head2; if(head2 === null) return head1;
Alvin you are the best programming sensei. This Linked List tutorial is just ridiculously good...
I just realized watching theory tutorials in other languages actually makes learning so much more intuitive, since you can't just blindly copy. You're forced to understand how your language works, and you're forced to implement those ideas without really being able to "cheat". Wow. I'm gonna start watching C tutorials and do them in python. I'm about to hit 10x developer once I understand all this
This is a very good point. I never realized this. This whole time I was trying to avoid tutorials in different languages, not realizing that they were the key to helping my solidify my understanding. Good observation!
same I was forced to code this in my learning language and I was surprised to see how quickly I learned
Alvin we need more of you guys. Grow up your channel. You are a hero
You are amazing Alvin! I've learned a lot from you🙌
His tutorial are pure 💎
I wish you had Java as one of the programming languages, but I still loved your course and was able to interpret everything in Java because of how you explained the algorithms, it was so simple to even understand recursive, something I always mess up. Thank you!!
No
Really cool to see you here Alvin. Great explanations as usual
Trust me, I was searching for an hour yesterday to find a good resource to learn Linked Lists. Thank you, FCC.
I like the way Alwin simplifies the concepts and problems. learnt a lot. Thanks
Your videos are awesome..Saw your video on Dynamic programming and since then i am not facing any problem in solving such questions.
what an excellent teacher!
loved the explanation! Though I knew all these concepts before, I just watched anyway.
Amazing, this guy is dynamic and engaging
Bro your research and best way of analysis is amazing.
Who else find this list helpful ❣️❣️
I love the way you teach 😍.
Please create a course on Backtracking.
omg who is this guy? He has the best algor interview videos !!
Alvin! Ex Google engineer. He also put out a new React + Tailwind course
What a co-incidence .tomorrow we have a amazon technical interview , hope It would help.
Awesome vids helping me with my uni subject Foundations of Programming, they give us 15 small programming exercises every week for points that count to final mark and also credit and they gave us exercises such as programm ringbuffer using linked list, program queues and stack using linked list. Merge two ordered linked lists and so on xd
Thank you very much. The best explanaition of js linked lists
The best I have seen so far...Thank you so much... I just checked your platform to make a purchase to go deeper but I couldn't find C# language option (that's my core language).
I don't know if there will be room for that in the future?
I greatly benefited from this JavaScript version.
All the members of your department are great
welcome back Alvin!
for zipperlist iterative approach, when you add the rest of the list that is leftover tail isn't reassigned to be the new tail. In this case, you're just using "tail" as a pointer to the current end of the constructed list. And tail isnt assigned at all in the recursive solution. Would there be an extra step to iterate through the leftover list to the end and reassign tail? Thanks for your great videos 🔥🔥🔥
i rlly like the way you explain the problem step by step.
Best video on LL for beginner
Alvin you are a great teacher.
Completed watching this tutorial, very informative, thanks a lot 🎉😊
Bro your research and best way of analysis is amazing.
Who else find this list helpful ️️
Best teacher ever!!!
Smooth Explanation.
BEST LINKEDLIST VIDEO EVER
The way Alvin teaches linked lists makes these concepts NOde big deal. Haaa
Love it as always! Big kudos!
Excellent explanation
I think it's much elegent this way. Anyway it was superb tutorial, Thanks Alwin!
node *ZippedLL(node *A, node *B){
if(!A) return B;
if(!B) return A;
node *ptrA = A;
node *ptrB = B;
while(ptrA && ptrB){
node *nextA = ptrA->next;
node *nextB = ptrB->next;
if(ptrB) ptrA->next = ptrB;
if(nextA) ptrB->next = nextA;
ptrA = nextA;
ptrB = nextB;
}
return A;
}
At least one error you will get is that you will be stuck in a loop. ptrA and ptrB are pointers and not booleans. Their values will likely be non-zero which will be interpreted as true. You need " While (ptrA != nullptr &&...) ". Something like that. Here is my code which I think works how you intended.
/// Assumes that neither list is empty.
void * zip(Node* f, Node* s){
while(f != nullptr && s != nullptr){
// Save next pointer.
Node* n = f->next;
// Point element from this list to other list.
f->next = s;
// Update first and second node.
f = s;
s = n;
}
}
@@nonconsensualopinion it works the way it is intended, NULL will be treated as false. Your code it correct, but I am not quite sure where am' wrong
Thank you, bro!
The way you explain the link list, even a foolish can understand it. Thanks a lot 😊
Thank you!
Thanks. This is top notch. On my way to subscribe. Frankly best content ever. Quick and eloquent.
last zipper recursion was awesome beauty
My dude is back!!!
ALVIN the GOAT!
Great video Alvin!
The Dynammic programming one was a blockbuster hence m here cheer
you have saved my life
The video that I had been searching. Thank you so much
not gonne lie thought this video was gonna be a waste of my time but I learned linked lists in just the first 15 mins of the video and was able to swift by these easily.
Thank you so much. You're the best!!!!
Thanks!
Great teacher!
kinda cool that i found different (tho worse) solutions to some of the problems on my own :D
I solved ZipperList iteratively without a counter to toggle between the two lists because at the start, i position the tail at the end of the initially constructed zipped list then within the while loop i construct the next node as a linkedlist of two nodes (current1.val) -> (current2.val) and then i update the tail and set the constructed two-nodes-list as its next then i refer to the last node of two-nodes-list i have just added as the new tail.
private static Node zipListsIterative(Node head1, Node head2) {
Node zipped = new Node(head1.getVal(), new Node(head2.getVal()));
Node tail = zipped.getNext();
Node current1 = head1.getNext();
Node current2 = head2.getNext();
while (current1 != null && current2 != null) {
Node next = new Node(current1.getVal(), new Node(current2.getVal()));
tail.setNext(next);
tail = next.getNext();
current1 = current1.getNext();
current2 = current2.getNext();
}
if (current1 == null) tail.setNext(current2);
if (current2 == null) tail.setNext(current1);
return zipped;
}
and recursively, i wrote the recursive case as one liner by making use of the constructor: Node(String val, Node next)
private static Node zipListsRecursive(Node head1, Node head2) {
//base cases
if (head1 == null && head2 == null) return null;
if (head1 == null) return head2;
if (head2 == null) return head1;
//recursive case
return new Node(head1.getVal(),
new Node(head2.getVal(),
zipListsRecursive(head1.getNext(), head2.getNext())));
}
My Recursive Solution for Zipper List is MORE concise and easier to learn:
const zipperLinkedListRec = (head1, head2) => {
if (!head2) return;
let temp = head1.next;
head1.next = head2;
zipperLinkedListRec(head2, temp);
return head1;
};
*This assumes that both lists are non-empty like in video
cooooooooool
Excellent!
Good job.
thanks ...appreciate it
great help! thank you
Alvin the boss
muchas gracias !!!
As Always, Thanks a Trillion.....
♥️♥️♥️♥️♥️♥️♥️♥️🌿🌿🌿🌿🌿🌿
Beautiful!
Alvin the boss is back in the hood!!!!!!
9:07 Linked list insertion at an index which is not at the head or the tail should be O(k) Time right?
Yup, and because you're hopping through so many pointers, you get a lot more cache misses than an array, more often than not making it slower than an array in practice.
Thanks a lot!!!
Amazing !
Helpful always 👍
True
@@mrrishiraj88 This_Reply = True;
this is literally the best video I seen on this. However, you said it can be anything in the data. However, in C# and Java would be different. it would have to be what you choose it to be because you have to initialize the type of data it has to enter so all the nodes would have integers. Am I right or am I wrong?
best teacher :DD
thank you! needed this video!
Awesome Video!!! thanks for the detail explanations.
Thankyou Very Very Much🙂🙂🙂🙂🙂🙂
Fantastic!!!
i think insertion in time complexity is O(n) in worst case this is most significant for linked list because we cant reach index till we reach the previous one and so on .. that's right ?
Thanks
19:15: great advice not to premature checking on linked list
Hands down the best algorithm explanations. $ Structy purchase.
Realy nice teaching style. Just one question. @ 37:00 it says the space is O(n) for the recursive sumList function. That is true for how it is implemented. But couldn't we also achieve O(1) by passing the sum variable into every recursion like it's done with the recursive linkedListValues? Wouldn't hat be much more optimised?
From what I understand, space complexity of O(n) means, in the worst case there will be 'n' call stacks ( i.e when we reach the tail of the linklist), thus passing the integer as a argument will still create n call stacks, hence O(n).
@@atharvarane6165 then why is it different in the recursive version of linkedListValues?
@@iamlookto Must be a mistake, because the memory complexity is determined by the number of return statements because each function call will be stored on the program stack. To generalize, a recursive function's memory complexity is O(recursion depth). As our tree depth suggests, we will have n total return statements and thus the memory complexity is O(n).
@1:21:40 Unless I'm missing an edge case, there's no need for the count variable in the iterative zigzag solution. Just move tail twice in each while loop. C++ code below
Node* zigzag3(Node* head1, Node* head2) {
Node* tail = head1;
Node* cur1 = head1->next;
Node* cur2 = head2;
while(cur1 && cur2) {
tail->next = cur2;
cur2 = cur2->next;
tail = tail->next;
tail->next = cur1;
cur1 = cur1->next;
tail = tail->next;
}
if (cur1) tail->next = cur1;
if (cur2) tail->next = cur2;
return head1;
}
this was my solution: template
Node* zipper(Node* head1, Node*head2) {
auto current1 = head1;
auto current2= head2;
while(current1 != nullptr && current2 != nullptr) {
auto next1 = current1->next;
auto next2 = current2->next;
current1->next = current2;
current2->next = next1==nullptr?next2:next1;
current1=next1;
current2 = next2;
}
return head1;
}
I love this channel