Algorithms: Graph Search, DFS and BFS
Learn the basics of graph search and common operations; Depth First Search (DFS) and Breadth First Search (BFS). This video is a part of HackerRank's Cracking The Coding Interview Tutorial with Gayle Laakmann McDowell. http://www.hackerrank.com/domains/tutorials/cracking-the-coding-interview?utm_source=video&utm_medium=youtube&utm_campaign=ctci
What You'll Learn
Graph search algorithms including Depth First Search and Breadth First Search are demonstrated
Full Transcript
Hi, I'm Gail Lock McDow, author of Kraken Coding Interview. Today I want to talk about graphs and common operations like breath first search and depth first search. So to go back to the beginning, a graph is basically a collection of nodes where each node might point to other nodes and these these edges can be directed. So like one-way streets or undirected so kind of like two-way streets. Now suppose you want to go walk through this graph and specifically suppose you want to do something like figure out is there a path from one node to another. There are two common ways of doing this and we'll talk about both of them. The first one is a little bit more simplistic and it's called depth first search and it's a typically recursive algorithm. And the way it looks like is saying okay we h have this initial node that I'm going to call S. Now you basically are asking a question hey S do you have a path to node T? And S says hm I'm not sure. Let me go ask my children. And first S goes to node A and it says, "Hey A, do you have a path to um node T? If you do, then hey, I'm done. I can give you my answer." Um, if you don't, then let me go ask B and then C and then D. And so, but the very first person we ask is A. So A gets asked, hey, A, do you have a path to T? I'm not sure. Let me go ask my children. And eventually we might get to get to a node who says why yes of course I have a path I am T. And so then we go and sayoop boop all the way back up. Yes there's a path. And that's the basics of depth depth first search. It's called depth first search because we go deep into some node before we even ask any of the children. Now the problem with this is that we might run really really far away. So imagine for example that B actually has a path directly to node T has an edge directly to node T. A might go to all of its children, all of its children, all of its children before even get to B and T was right there. There could have been a really fast connection. So that's why we might often prefer to use breath first search instead. Breath first search says, hey, go level by level out. So, first we ask S, hey, do you have a a path to T? And S will say, well, let me check if any of my nodes are T. No, there's no edge right there. So, each of those get in line. And then we ask the second level out and then the third level out and the next level and next level, next level. And so, we go level by level breadth. We go wider before we go deep. And that's why it's called breath for search. So I want to talk at a high level about the implementation of each before I dive into some of the details. So depth for search is implemented with a recursive algorithm. It's probably the simpler algorithm to implement. The only little trick is that you have to make sure to use an isvisited flag so that you don't wind up in some sort of infinite loop where there is you know a cycle and you keep asking each note if it has you start one around running around in a circle. With breath first search, the main trick you need to remember is you want to use a Q. So when you look when you look at S, you say, "Hey, do you have a path to T, you're going to go add all of its children to the Q and rather than going recursively, you pull out the first element to from the Q, check if it has a P, you check if it is this final element, and if not, go add all of its children to it. So you use a Q so that you go go through things in the correct order. So that's a high level how it works. Let's turn to the real details of the implementation. Now, I've gotten a bit of a head start on the implementation, but I'll show you just quickly what I've done. So, first we have this uh node class here, and it it's going to have some sort of ID that represents the node ID. Uh, and what I've done is give ourselves a mapping of from node ID to the actual node. And this is mostly going to be used for things like get node and add edge. This way we can actually just go and get um get immediate access to the node with particular ID. And then I've also given us this uh has path depth first search method and it's going to call out to this recursive method. So if you remember with with depth first search we need to have a way of flagging nodes to say hey I've already visited this don't retry it. So one thing we could do is we could actually modify the node class to give ourselves an isvisited flag, but that requires then making sure we clear the that flag later on. Another way of doing it is giving ourselves a hashet uh that lists all of the IDs that I've already of the nodes that I've already visited. It's sort of a replacement for a flag. So I'm going to do it this way. This way I don't have to modify and add a whole bunch of flags in and then make sure to clear them later on. So I get the source node. I get the destination node and then I get this create this visited hash set and then I go out and call the this recursive method. So now is where the fun begins. So first if I've already visited this node if visited.contains contains this source ID then return false because there is no path then uh okay otherwise then what I want to do is so now I want to go and make sure I you know update this mark this node as visited and then I want to say okay if if I'm at my source then return if I'm at my destination rather then return true because yes there certainly does a path then otherwise go and check all my children see if any of them have a path because if there's a path from a child to me then then there's certainly a uh final then there's certainly a path from me to my destination. So for each ch node to child in source adjacent if there's a path from child to destination passing in again visited then return true and that'll bubble all the way up the stack. If I get down to the very end and I haven't found a path yet then there is no path for me to my destination. Now let's turn to how breath first search works. Okay. So, breath first search. So, what I need with breath first search is I need a link list of sort of what I'll call the like next up. So, these are the I'll call this next to visit. These are the nodes that I need to visit next. And just as before, I need this visited hash set that represents everything I've already visited. And then I want to say next to visit first thing because the first thing I need to visit is in fact my source then as long as there is nothing in this. So while visited sorry now I'll next to visit is empty. So while it's not empty, keep going. All right. So first thing, so I need to look gra my very first node to visit. So node node equals next to visit dot I'll call this remove. So remove the very first node in that that list. If this is my destination then there is certainly a path. Now I also want to do my visited checking. So if visited.contains um of node ID then actually just continue. Let's go to the next value. Uh otherwise visited.add add of node ID. So mark it as visited and then go and actually add my children. So for each node child in node.adjacent go and add each of those to my next to visit. So next to visit add of child. All right. And that's all there is to depth. uh to breath first search and then of course if I get down to the very end and I haven't found a path yet return false. Let's walk through this code again and make sure that this makes sense. So hazpath dfs takes in the source and destination ids and then I get those nodes and then I create this hash set that should be a hash set not a hashmap and then goes and actually does this recursive method. So the recursive method take has this visited thing. So we use the visited hash set instead of marking the actual nodes with a flag. So visited check if it checks if it contains a source ID. Uh if it does contain that if I've already visited this return false uh because there's no path then otherwise go and add this visited mark this node as visited re you know check check my source as my destination shows I'm already there return true. um otherwise go and search all of my children then so that and then if I haven't found a path go return false. So with BFS we are taking in a source and a destination. So here I've used nodes I'll switch this actually to be symmetric and use ids again and so I'll make that public and this private now. Okay. So I take in the source and destination ids and then I go and call this recursive method. So my recursive method or sorry this other just helper method. So this takes in the source and destination. I create this list of the next nodes I have to visit and this visited hashet that should be hashet again. Uh and this marks all the nodes that have already visited. So I say okay next one to visit is my source. Then as long as there's there's something left to visit, pull out the next node to visit. Check if I'm where I should be. If so, return true. Otherwise, check and update my visited my sort of who's who I visited. And then go and ceue up my children at the very end of the queue to be visited next. And those will and this will this will ensure that my children are not visited immediately but are visited once sort of everything in you know everything scheduled has already been visited. So it ensure it'll visit level by level by level and then if I get found the very end and I haven't found a destination after all of this then just return false. So that's how breath first search operates. In many cases when we want to find if there's actually a path breath first search is often the better approach because otherwise we could wind up searching really really far away when there's actually a very short connection and it's certainly better when we want to find the shortest path. So now that you've seen breath first and depth first search why don't you try these out on a new problem. Good luck.
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from HackerRank · HackerRank · 18 of 60
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
▶
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
HackerRank for Professors
HackerRank
Why CareerCup's Gayle Laakmann McDowell Loves HackerRank [Testimonial]
HackerRank
How to Leverage Data-Driven Insights to Improve Recruiting Results
HackerRank
Hire Top Linux Talent and System Admins with SudoRank [Webinar]
HackerRank
How Zenefits Hired 10 Engineers in 10 Days with HackerRank's CodeSprint
HackerRank
Hire the hottest SQL talent with DbRank from HackerRank [Tutorial]
HackerRank
How to Use HackerRank's CodePair Tool [Tutorial]
HackerRank
Find Linux Talent with SudoRank challenges [Tutorial]
HackerRank
VMware's Mat Connot details his favorite new way to engage top programmers
HackerRank
An Inside Look at Coinbase's Recruiting Strategy [webinar]
HackerRank
How Evernote Enhanced Their Tech Recruiting Process
HackerRank
5 strategies for being a tech recruiting champion with HackerRank [Webinar]
HackerRank
HackerRank Story - Lets make the world flat!
HackerRank
Data Structures: Hash Tables
HackerRank
Data Structures: Anagram Problem Solution
HackerRank
Algorithms: Solve 'Lonley Integer' Using Bit Manipulation
HackerRank
Big O Notation
HackerRank
Algorithms: Graph Search, DFS and BFS
HackerRank
Algorithms: Bit Manipulation
HackerRank
Data Structures: Solve 'Find the Running Median' Using Heaps
HackerRank
Data Structures: Heaps
HackerRank
Algorithms: Memoization and Dynamic Programming
HackerRank
Algorithms: Sort An Array with Comparator
HackerRank
Algorithms: Solve 'Coin Change' Using Memoization and DP
HackerRank
Data Structures: Solve 'Contacts' Using Tries
HackerRank
Data Structures: Tries
HackerRank
Algorithms: Bubble Sort
HackerRank
Algorithms: Merge Sort
HackerRank
Algorithms: Quicksort
HackerRank
Data Structures: Binary Search Tree
HackerRank
Data Structures: Trees
HackerRank
Algorithms: Solve 'Shortest Reach' Using BFS
HackerRank
Algorithms: Solve 'Connected Cells' Using DFS
HackerRank
Algorithms: Solve 'Recursive Staircase' Using Recursion
HackerRank
Algorithms: Binary Search
HackerRank
Algorithms: Solve 'Ice Cream Parlor' Using Binary Search
HackerRank
Data Structures: Linked Lists
HackerRank
Data Structures: Cycles in a Linked List
HackerRank
Data Structures: Stacks and Queues
HackerRank
Data Structures: Queue With Two Stacks
HackerRank
Data Structures: Balanced Parentheses in Expression
HackerRank
Algorithms: Recursion
HackerRank
How to Hire for Your Startup [Collision Panel Video]
HackerRank
HackerRank main() San Francisco | November 8, 2018
HackerRank
The Enterprise Playbook for Technical Hiring
HackerRank
Remote Hiring Colloquy with EY's Dipika Kapadia & BigBasket's Rupesh Kumar
HackerRank
Remote Hiring Colloquy with Hackerrank's Hari K, Akamai's Neha Akhouri & Infosys's Rafee Tarafdar
HackerRank
Building a Culture for Developer Innovation
HackerRank
Developer Trends in 2020 and Beyond
HackerRank
HackerRank's Livestream: Accelerating Developer Innovation at PhonePe
HackerRank
Aadil Bandukwala converses with Rahul Chari about HackerRank's upcoming livestream
HackerRank
Accelerating Developer Innovation at PhonePe with Rahul Chari
HackerRank
The Future of Work for Developers
HackerRank
Scaling AI from Proof of Concept to Production
HackerRank
The Secret Sauce to getting hired in Myntra’s Tech Team
HackerRank
Reimagining Money with Paypal
HackerRank
Engineering Predictions for 2021 and Beyond! 🎬
HackerRank
Future-forward Tech & Careers with BNY Mellon
HackerRank
How Atlassian Approaches Diversity and Inclusion with Balance & Belonging
HackerRank
Connecting Global Tech Ecosystems: Andela Shines a Light on Africa’s Developer Talent
HackerRank
More on: Algorithm Basics
View skill →Related AI Lessons
⚡
⚡
⚡
⚡
Bloom Filters, Explained Properly
Dev.to · Daksh Gargas
Prefix Sums: The Preprocessing Trick That Makes Range Queries Instant
Medium · Programming
I Thought I Was Ready for the Interview — Then One Simple Math Question Destroyed Me
Medium · Programming
Week 2(Day 10): LeetCode Two Pointers(slow & fast): Remove Duplicates from Sorted Array (Brute…
Medium · Python
🎓
Tutor Explanation
DeepCamp AI