{"captions":[{"content":"[Seminar: Technical Interviews]","startTime":0,"duration":2640,"startOfParagraph":false},{"content":"[Kenny Yu, Harvard University]","startTime":2640,"duration":1990,"startOfParagraph":false},{"content":"[This is CS50.] [CS50.TV]","startTime":4630,"duration":4280,"startOfParagraph":false},{"content":"Hi everyone, I'm Kenny. I am currently a junior studying computer science. ","startTime":8910,"duration":3510,"startOfParagraph":false},{"content":"I'm a former CS TF, and I wish I had this when I was an underclassman, ","startTime":12420,"duration":4890,"startOfParagraph":false},{"content":"and that's why I'm giving this seminar.","startTime":17310,"duration":2070,"startOfParagraph":false},{"content":"So I hope you enjoy it. ","startTime":19380,"duration":1990,"startOfParagraph":false},{"content":"This seminar is about technical interviews, ","startTime":21370,"duration":2100,"startOfParagraph":false},{"content":"and all my resources can be found at this link, ","startTime":23470,"duration":3180,"startOfParagraph":false},{"content":"this link right here, a couple of resources.","startTime":26650,"duration":5700,"startOfParagraph":false},{"content":"So I made a list of problems, actually, quite a few problems.","startTime":32350,"duration":4200,"startOfParagraph":false},{"content":"Also a general resources page where we can find tips ","startTime":36550,"duration":4250,"startOfParagraph":false},{"content":"on how to prepare for an interview, ","startTime":40800,"duration":2070,"startOfParagraph":false},{"content":"tips on what you should do during an actual interview,","startTime":42870,"duration":3600,"startOfParagraph":false},{"content":"as well as how to approach problems and resources for future reference. ","startTime":46470,"duration":5440,"startOfParagraph":false},{"content":"It's all online. ","startTime":51910,"duration":2070,"startOfParagraph":false},{"content":"And just to preface this seminar, a disclaimer, ","startTime":53980,"duration":4310,"startOfParagraph":false},{"content":"like this should not--your interview preparation ","startTime":58290,"duration":2400,"startOfParagraph":false},{"content":"should not be limited to this list. ","startTime":60690,"duration":2110,"startOfParagraph":false},{"content":"This is only meant to be a guide, ","startTime":62800,"duration":1950,"startOfParagraph":false},{"content":"and you should definitely take everything I say with a grain of salt, ","startTime":64750,"duration":4140,"startOfParagraph":false},{"content":"but also use everything I used to help you in your interview preparation. ","startTime":68890,"duration":5730,"startOfParagraph":false},{"content":"I'm going to speed through the next few slides","startTime":74620,"duration":1780,"startOfParagraph":true},{"content":"so we can get to the actual case studies. ","startTime":76400,"duration":2250,"startOfParagraph":false},{"content":"The structure of an interview for a software engineering postion, ","startTime":78650,"duration":4980,"startOfParagraph":false},{"content":"typically it is 30 to 45 minutes, ","startTime":83630,"duration":2690,"startOfParagraph":false},{"content":"multiple rounds, depending on the company. ","startTime":86320,"duration":3490,"startOfParagraph":false},{"content":"Often you'll be coding on a white board. ","startTime":89810,"duration":3280,"startOfParagraph":false},{"content":"So a white board like this, but often on a smaller scale. ","startTime":93090,"duration":2870,"startOfParagraph":false},{"content":"If you're having a phone interview, you'll probably be using","startTime":95960,"duration":2580,"startOfParagraph":false},{"content":"either collabedit or a Google Doc so they can see you live coding ","startTime":98540,"duration":5490,"startOfParagraph":false},{"content":"while you're being interviewed over the phone. ","startTime":104030,"duration":2470,"startOfParagraph":false},{"content":"An interview itself is typically 2 or 3 problems ","startTime":106500,"duration":1990,"startOfParagraph":false},{"content":"testing your computer science knowledge. ","startTime":108490,"duration":2130,"startOfParagraph":false},{"content":"And it will almost definitely involve coding. ","startTime":110620,"duration":3870,"startOfParagraph":false},{"content":"The types of questions that you'll see are usually data structures and algorithms. ","startTime":114490,"duration":5050,"startOfParagraph":false},{"content":"And in doing these kinds of problems, ","startTime":119540,"duration":2670,"startOfParagraph":false},{"content":"they will ask you, like, what is the time and space complexity, big O?","startTime":122210,"duration":5620,"startOfParagraph":false},{"content":"Often they also ask higher-level questions, ","startTime":127830,"duration":1970,"startOfParagraph":false},{"content":"so, designing a system, ","startTime":129800,"duration":2730,"startOfParagraph":false},{"content":"how would you lay out your code? ","startTime":132530,"duration":2240,"startOfParagraph":false},{"content":"What interfaces, what classes, what modules do you have in your system, ","startTime":134770,"duration":3600,"startOfParagraph":false},{"content":"and how do these interact together?","startTime":138370,"duration":2530,"startOfParagraph":false},{"content":"So data structures and algorithms as well as designing systems. ","startTime":140900,"duration":5230,"startOfParagraph":false},{"content":"Some general tips before we dive in to our case studies. ","startTime":146130,"duration":3050,"startOfParagraph":true},{"content":"I think the most important rule is always be thinking out loud. ","startTime":149180,"duration":3120,"startOfParagraph":false},{"content":"The interview is supposed to be your chance to show off your thinking process. ","startTime":152300,"duration":4680,"startOfParagraph":false},{"content":"The point of the interview is for the interviewer to gauge ","startTime":156980,"duration":2840,"startOfParagraph":false},{"content":"how you think and how you go through a problem. ","startTime":159820,"duration":2840,"startOfParagraph":false},{"content":"The worst thing you can do is be silent throughout the whole interview. ","startTime":162660,"duration":2550,"startOfParagraph":false},{"content":"That's just no good. ","startTime":165210,"duration":4880,"startOfParagraph":false},{"content":"When you are given a question, you also want to make sure you understand the question. ","startTime":170090,"duration":3140,"startOfParagraph":false},{"content":"So repeat the question back in your own words ","startTime":173230,"duration":2120,"startOfParagraph":false},{"content":"and attempt to work thorough a few simple test cases ","startTime":175350,"duration":3570,"startOfParagraph":false},{"content":"to make sure you understand the question. ","startTime":178920,"duration":2610,"startOfParagraph":false},{"content":"Working through a few test cases will also give you an intuition on how to solve this problem. ","startTime":181530,"duration":3980,"startOfParagraph":false},{"content":"You might even discover a few patterns to help you solve the problem. ","startTime":185510,"duration":5700,"startOfParagraph":false},{"content":"Their big tip is to not get frustrated. ","startTime":191210,"duration":3290,"startOfParagraph":false},{"content":"Don't get frustrated. ","startTime":194500,"duration":2560,"startOfParagraph":false},{"content":"Interviews are challenging, but the worst thing you can do, ","startTime":197060,"duration":2000,"startOfParagraph":false},{"content":"in addition to being silent, is to be visibly frustrated. ","startTime":199060,"duration":4270,"startOfParagraph":false},{"content":"You do not want to give that impression to an interviewer. ","startTime":203330,"duration":4080,"startOfParagraph":false},{"content":"One thing that you--so, many people, when they go into an interview, ","startTime":207410,"duration":6550,"startOfParagraph":false},{"content":"they attempt to try to find the best solution first, ","startTime":213960,"duration":3190,"startOfParagraph":false},{"content":"when really, there's usually a glaringly obvious solution. ","startTime":217150,"duration":2800,"startOfParagraph":false},{"content":"It might be slow, it might be inefficient, but you should just state it, ","startTime":219950,"duration":3550,"startOfParagraph":false},{"content":"just so you have a starting point from which to work better. ","startTime":223500,"duration":2710,"startOfParagraph":false},{"content":"Also, pointing out the solution is slow, in terms of ","startTime":226210,"duration":2060,"startOfParagraph":false},{"content":"big O time complexity or space complexity, ","startTime":228270,"duration":3890,"startOfParagraph":false},{"content":"will demonstrate to the interviewer that you understand ","startTime":232160,"duration":2290,"startOfParagraph":false},{"content":"these issues when writing code. ","startTime":234450,"duration":3060,"startOfParagraph":false},{"content":"So don't be afraid to come up with the simplest algorithm first","startTime":237510,"duration":3930,"startOfParagraph":false},{"content":"and then work better from there. ","startTime":241440,"duration":3510,"startOfParagraph":false},{"content":"Any questions so far? Okay. ","startTime":244950,"duration":4860,"startOfParagraph":false},{"content":"So let's dive into our first problem. ","startTime":249810,"duration":1840,"startOfParagraph":true},{"content":"\"Given an array of n integers, write a function that shuffles the array","startTime":251650,"duration":3140,"startOfParagraph":false},{"content":"in place such that all permutations of the n integers are equally likely.\"","startTime":254790,"duration":5419,"startOfParagraph":false},{"content":"And assume you have available a random integer generator","startTime":260209,"duration":3261,"startOfParagraph":false},{"content":"that generates an integer in a range from 0 to i, half range. ","startTime":263470,"duration":7510,"startOfParagraph":false},{"content":"Does everyone understand this question? ","startTime":270980,"duration":1990,"startOfParagraph":false},{"content":"I give you an array of n integers, and I want you to shuffle it. ","startTime":272970,"duration":6690,"startOfParagraph":false},{"content":"In my directory, I wrote a few programs to demonstrate what I mean. ","startTime":279660,"duration":6390,"startOfParagraph":false},{"content":"I'm going to shuffle an array of 20 elements, ","startTime":286050,"duration":2860,"startOfParagraph":false},{"content":"from -10 to +9, ","startTime":288910,"duration":3580,"startOfParagraph":false},{"content":"and I want you to output a list like this. ","startTime":292490,"duration":4560,"startOfParagraph":false},{"content":"So this is my sorted input array, and I want you to shuffle it. ","startTime":297050,"duration":5840,"startOfParagraph":false},{"content":"We'll do it again. ","startTime":302890,"duration":4180,"startOfParagraph":false},{"content":"Does everyone understand the question? Okay. ","startTime":307070,"duration":6710,"startOfParagraph":false},{"content":"So it's up to you. ","startTime":313780,"duration":2950,"startOfParagraph":false},{"content":"What are some ideas? Can you do it as n^2, n log n, n?","startTime":316730,"duration":4490,"startOfParagraph":false},{"content":"Open to suggestions. ","startTime":321220,"duration":13180,"startOfParagraph":false},{"content":"Okay. So one idea, suggested by Emmy, ","startTime":334400,"duration":3330,"startOfParagraph":false},{"content":"is first compute a random number, random integer, in a range from 0 to 20. ","startTime":337730,"duration":7570,"startOfParagraph":false},{"content":"So assume our array has a length of 20. ","startTime":345300,"duration":4540,"startOfParagraph":false},{"content":"In our diagram of 20 elements, ","startTime":349840,"duration":4960,"startOfParagraph":false},{"content":"this is our input array. ","startTime":354800,"duration":3760,"startOfParagraph":false},{"content":"And now, her suggestion is to create a new array, ","startTime":358560,"duration":6030,"startOfParagraph":false},{"content":"so this will be the output array. ","startTime":364590,"duration":3850,"startOfParagraph":false},{"content":"And based on the i returned by rand--","startTime":368440,"duration":4440,"startOfParagraph":false},{"content":"so if i was, let's say, 17, ","startTime":372880,"duration":4700,"startOfParagraph":false},{"content":"copy the 17th element into the first position. ","startTime":377580,"duration":8060,"startOfParagraph":false},{"content":"Now we need to delete--we need to shift all the elements here ","startTime":385640,"duration":4660,"startOfParagraph":false},{"content":"over so that we have a gap at the end and no holes in the middle. ","startTime":390300,"duration":6620,"startOfParagraph":false},{"content":"And now we repeat the process. ","startTime":396920,"duration":2940,"startOfParagraph":false},{"content":"Now we pick a new random integer between 0 and 19. ","startTime":399860,"duration":6500,"startOfParagraph":false},{"content":"We have a new i here, and we copy this element into this position. ","startTime":406360,"duration":6150,"startOfParagraph":false},{"content":"Then we shift items over and we repeat the process until we have our full new array. ","startTime":412510,"duration":8450,"startOfParagraph":false},{"content":"What is the run time of this algorithm? ","startTime":420960,"duration":4930,"startOfParagraph":false},{"content":"Well, let's consider the impact of this. ","startTime":425890,"duration":2220,"startOfParagraph":false},{"content":"We are shifting every element. ","startTime":428110,"duration":2270,"startOfParagraph":false},{"content":"When we remove this i, we are shifting all the elements after it to the left. ","startTime":430380,"duration":6420,"startOfParagraph":false},{"content":"And that is an O(n) cost","startTime":436800,"duration":4800,"startOfParagraph":false},{"content":"because what if we remove the first element?","startTime":441600,"duration":4500,"startOfParagraph":false},{"content":"So for each removal, we remove--","startTime":446100,"duration":3570,"startOfParagraph":false},{"content":"each removal incurs an O(n) operation, ","startTime":449670,"duration":2500,"startOfParagraph":false},{"content":"and since we have n removals, this leads to an O(n^2) shuffle. ","startTime":452170,"duration":9350,"startOfParagraph":false},{"content":"Okay. So good start. Good start. ","startTime":461520,"duration":8030,"startOfParagraph":false},{"content":"Another suggestion is to use something known as the Knuth shuffle, ","startTime":469550,"duration":5740,"startOfParagraph":true},{"content":"or the Fisher-Yates shuffle. ","startTime":475290,"duration":2250,"startOfParagraph":false},{"content":"And it's actually a linear time shuffle. ","startTime":477540,"duration":2090,"startOfParagraph":false},{"content":"And the idea is very similar.","startTime":479630,"duration":2570,"startOfParagraph":false},{"content":"Again, we have our input array, ","startTime":482200,"duration":2960,"startOfParagraph":false},{"content":"but instead of using two arrays for our input/output, ","startTime":485160,"duration":3420,"startOfParagraph":false},{"content":"we use the first portion of the array to keep track of our shuffled portion, ","startTime":488580,"duration":5010,"startOfParagraph":false},{"content":"and we keep track, and then we leave the rest of our array for the unshuffled portion. ","startTime":493590,"duration":4810,"startOfParagraph":false},{"content":"So here's what I mean. We start off with--we choose an i, ","startTime":498400,"duration":5930,"startOfParagraph":false},{"content":"an array from 0 to 20. ","startTime":504330,"duration":6580,"startOfParagraph":false},{"content":"Our current pointer is pointing to the first index.","startTime":510910,"duration":5240,"startOfParagraph":false},{"content":"We choose some i here","startTime":516150,"duration":3440,"startOfParagraph":false},{"content":"and now we swap. ","startTime":519590,"duration":3150,"startOfParagraph":false},{"content":"So if this was 5 and this was 4, ","startTime":522740,"duration":4950,"startOfParagraph":false},{"content":"the resulting array will have 5 here and 4 here. ","startTime":527690,"duration":9460,"startOfParagraph":false},{"content":"And now we note a marker here. ","startTime":537150,"duration":3240,"startOfParagraph":false},{"content":"Everything to the left is shuffled, ","startTime":540390,"duration":5380,"startOfParagraph":false},{"content":"and everything to the right is unshuffled. ","startTime":545770,"duration":9390,"startOfParagraph":false},{"content":"And now we can repeat the process. ","startTime":555160,"duration":2100,"startOfParagraph":false},{"content":"We choose a random index between 1 and 20 now. ","startTime":557260,"duration":7950,"startOfParagraph":false},{"content":"So suppose our new i is here. ","startTime":565210,"duration":5440,"startOfParagraph":false},{"content":"Now we swap this i with our current new position here. ","startTime":570650,"duration":8720,"startOfParagraph":false},{"content":"So we do a swapping back and forth like this. ","startTime":579370,"duration":5420,"startOfParagraph":false},{"content":"Let me bring up the code to make it more concrete. ","startTime":584790,"duration":6840,"startOfParagraph":false},{"content":"We start with our choice of i--","startTime":591630,"duration":3660,"startOfParagraph":false},{"content":"we start with i equal to 0, we pick a random location j ","startTime":595290,"duration":3080,"startOfParagraph":false},{"content":"in the unshuffled portion of the array, i to n-1. ","startTime":598370,"duration":4050,"startOfParagraph":false},{"content":"So if I'm here, choose a random index between here and the rest of the array, ","startTime":602420,"duration":4860,"startOfParagraph":false},{"content":"and we swap. ","startTime":607280,"duration":5130,"startOfParagraph":false},{"content":"This is all the code necessary to shuffle your array. ","startTime":612410,"duration":5140,"startOfParagraph":false},{"content":"Any questions? ","startTime":617550,"duration":4120,"startOfParagraph":false},{"content":"Well, one needed question is, why is this correct? ","startTime":621670,"duration":3860,"startOfParagraph":true},{"content":"Why is every permutation equally likely? ","startTime":625530,"duration":2830,"startOfParagraph":false},{"content":"And I won't go through the proof of this, ","startTime":628360,"duration":2050,"startOfParagraph":false},{"content":"but many problems in computer science can be proven through induction. ","startTime":630410,"duration":5560,"startOfParagraph":false},{"content":"How many of you are familiar with induction? ","startTime":635970,"duration":2550,"startOfParagraph":false},{"content":"Okay. Cool. ","startTime":638520,"duration":2070,"startOfParagraph":false},{"content":"So you can prove the correctness of this algorithm by simple induction, ","startTime":640590,"duration":3020,"startOfParagraph":false},{"content":"where your induction hypothesis would be, assume that","startTime":643610,"duration":5930,"startOfParagraph":false},{"content":"my shuffle returns every permutation equally likely ","startTime":649540,"duration":3750,"startOfParagraph":false},{"content":"up to the first i elements. ","startTime":653290,"duration":2830,"startOfParagraph":false},{"content":"Now, consider i + 1. ","startTime":656120,"duration":2180,"startOfParagraph":false},{"content":"And by the way we choose our index j to swap, ","startTime":658300,"duration":4250,"startOfParagraph":false},{"content":"this leads to--and then you work out the details, ","startTime":662550,"duration":2680,"startOfParagraph":false},{"content":"at least a full proof of why this algorithm returns","startTime":665230,"duration":2160,"startOfParagraph":false},{"content":"every permutation with equally likely probability. ","startTime":667390,"duration":5410,"startOfParagraph":false},{"content":"All right, next problem. ","startTime":672800,"duration":3140,"startOfParagraph":true},{"content":"So \"given an array of integers, postive, zero, negative, ","startTime":675940,"duration":3230,"startOfParagraph":false},{"content":"write a function that calculates the maximum sum","startTime":679170,"duration":2120,"startOfParagraph":false},{"content":"of any continueous subarray of the input array.\" ","startTime":681290,"duration":3430,"startOfParagraph":false},{"content":"An example here is, in the case where all numbers are positive, ","startTime":684720,"duration":3650,"startOfParagraph":false},{"content":"then currently the best choice is to take the whole array. ","startTime":688370,"duration":2950,"startOfParagraph":false},{"content":"1, 2, 3, 4, equals 10. ","startTime":691320,"duration":3370,"startOfParagraph":false},{"content":"When you have some negatives in there, ","startTime":694690,"duration":2090,"startOfParagraph":false},{"content":"in this case we just want the first two","startTime":696780,"duration":1910,"startOfParagraph":false},{"content":"because choosing -1 and/or -3 will bring our sum down. ","startTime":698690,"duration":5900,"startOfParagraph":false},{"content":"Sometimes we might have to start in the middle of the array. ","startTime":704590,"duration":3530,"startOfParagraph":false},{"content":"Sometimes we want to choose nothing at all; it's best to not take anything. ","startTime":708120,"duration":5380,"startOfParagraph":false},{"content":"And sometimes it's better to take the fall, ","startTime":713500,"duration":2990,"startOfParagraph":false},{"content":"because the thing after it is super big. So any ideas? ","startTime":716490,"duration":11020,"startOfParagraph":false},{"content":"(student, unintelligible) >>Yeah. ","startTime":727510,"duration":3460,"startOfParagraph":false},{"content":"Suppose I don't take -1. ","startTime":730970,"duration":2590,"startOfParagraph":false},{"content":"Then either I choose 1,000 and 20,000, ","startTime":733560,"duration":2610,"startOfParagraph":false},{"content":"or I just choose the 3 billion. ","startTime":736170,"duration":2460,"startOfParagraph":false},{"content":"Well, the best choice is to take all the numbers. ","startTime":738630,"duration":2130,"startOfParagraph":false},{"content":"This -1, despite being negative, ","startTime":740760,"duration":3590,"startOfParagraph":false},{"content":"the whole sum is better than were I not to take -1. ","startTime":744350,"duration":6990,"startOfParagraph":false},{"content":"So one of the tips I mentioned earlier was to state the clearly obvious","startTime":751340,"duration":5120,"startOfParagraph":false},{"content":"and the brute force solution first.","startTime":756460,"duration":4080,"startOfParagraph":false},{"content":"What is the brute force solution in this problem? Yeah? ","startTime":760540,"duration":3800,"startOfParagraph":false},{"content":"[Jane] Well, I think the brute force solution ","startTime":764340,"duration":2550,"startOfParagraph":false},{"content":"would be to add up all the possible combinations (unintelligible). ","startTime":766890,"duration":5710,"startOfParagraph":false},{"content":"[Yu] Okay. So Jane's idea is to take every possible--","startTime":772600,"duration":5650,"startOfParagraph":false},{"content":"I'm paraphrasing--is to take every possible continuous subarray, ","startTime":778250,"duration":3220,"startOfParagraph":false},{"content":"compute its sum, and then take the maximum of all the possible continuous subarrays. ","startTime":781470,"duration":6370,"startOfParagraph":false},{"content":"What uniquely identifies a subarray in my input array?","startTime":787840,"duration":5470,"startOfParagraph":false},{"content":"Like, what two things do I need? Yeah? ","startTime":793310,"duration":4070,"startOfParagraph":false},{"content":"(student, unintelligible) >>Right. ","startTime":797380,"duration":2590,"startOfParagraph":false},{"content":"A lower bound on the index and an upper bound index ","startTime":799970,"duration":2160,"startOfParagraph":false},{"content":"uniquely determines a continuous subarray. ","startTime":802130,"duration":6170,"startOfParagraph":false},{"content":"[Female student] Are we estimating it's an array of unique numbers? ","startTime":808300,"duration":3100,"startOfParagraph":false},{"content":"[Yu] No. So her question is, are we assuming our array--","startTime":811400,"duration":2880,"startOfParagraph":false},{"content":"is our array all unique numbers, and the answer is no. ","startTime":814280,"duration":4720,"startOfParagraph":false},{"content":"If we use our brute force solution, then the start/end indices","startTime":819000,"duration":4390,"startOfParagraph":true},{"content":"uniquely determines our continuous subarray. ","startTime":823390,"duration":3810,"startOfParagraph":false},{"content":"So if we iterate for all possible start entries, ","startTime":827200,"duration":4480,"startOfParagraph":false},{"content":"and for all end entries > or = to start, and < n, ","startTime":831680,"duration":6640,"startOfParagraph":false},{"content":"you compute the sum, and then we take the maximum sum we've seen so far. ","startTime":838320,"duration":7250,"startOfParagraph":false},{"content":"Is this clear? ","startTime":845570,"duration":2310,"startOfParagraph":false},{"content":"What is the big O of this solution? ","startTime":847880,"duration":4350,"startOfParagraph":false},{"content":"Timewise. ","startTime":852230,"duration":4430,"startOfParagraph":false},{"content":"Not quite n^2. ","startTime":856660,"duration":2200,"startOfParagraph":false},{"content":"Note that we iterate from 0 to n, ","startTime":858860,"duration":6390,"startOfParagraph":false},{"content":"so that's one for loop. ","startTime":865250,"duration":2270,"startOfParagraph":false},{"content":"We iterate again from almost the beginning to the end, another for loop. ","startTime":867520,"duration":7600,"startOfParagraph":false},{"content":"And now, within that, we have to sum up every entry, ","startTime":875120,"duration":2520,"startOfParagraph":false},{"content":"so that's another for loop. So we have three nested for loops, n^3. ","startTime":877640,"duration":6170,"startOfParagraph":false},{"content":"Okay. This goes as a starting point. ","startTime":883810,"duration":2750,"startOfParagraph":false},{"content":"Our solution is no worse than n^3. ","startTime":886560,"duration":6620,"startOfParagraph":false},{"content":"Does everyone understand the brute force solution? ","startTime":893180,"duration":2300,"startOfParagraph":false},{"content":"Okay. A better solution is using an idea called dynamic programming. ","startTime":895480,"duration":4470,"startOfParagraph":true},{"content":"If you take CS124, which is Algorithms and Data Structures, ","startTime":899950,"duration":3090,"startOfParagraph":false},{"content":"you will become very familiar with this technique. ","startTime":903040,"duration":2640,"startOfParagraph":false},{"content":"And the idea is, try to build up solutions to smaller problems first. ","startTime":905680,"duration":6510,"startOfParagraph":false},{"content":"What I mean by this is, we currently have to worry about two things: start and end. ","startTime":912190,"duration":5800,"startOfParagraph":false},{"content":"And that's annoying. What if we could get rid of one of those parameters? ","startTime":917990,"duration":11350,"startOfParagraph":false},{"content":"One idea is to--we're given our original problem, ","startTime":929340,"duration":3310,"startOfParagraph":false},{"content":"find the maximum sum of any subarray in a range [O,n-1]. ","startTime":932650,"duration":4820,"startOfParagraph":false},{"content":"And now we have a new subproblem, where we know, in our current index i, ","startTime":937470,"duration":9930,"startOfParagraph":false},{"content":"we know we must conclude there. Our subarray must end at the current index. ","startTime":947400,"duration":5120,"startOfParagraph":false},{"content":"So the remaining problem is, where should we start our subarray? ","startTime":952520,"duration":5120,"startOfParagraph":false},{"content":"Does this make sense? Okay. ","startTime":957640,"duration":7520,"startOfParagraph":false},{"content":"So I've coded this up, and let's look at what this means. ","startTime":965160,"duration":6870,"startOfParagraph":false},{"content":"In the codirectory, there's a program called subarray, ","startTime":972030,"duration":4200,"startOfParagraph":false},{"content":"and it takes number of items, ","startTime":976230,"duration":3240,"startOfParagraph":false},{"content":"and it returns the maximal subarray sum in my shuffled list. ","startTime":979470,"duration":6080,"startOfParagraph":false},{"content":"So in this case, our maximal subarray is 3. ","startTime":985550,"duration":4370,"startOfParagraph":false},{"content":"And that's taken by just using 2 and 1. ","startTime":989920,"duration":4930,"startOfParagraph":false},{"content":"Let's run it again. It's also 3. ","startTime":994850,"duration":3200,"startOfParagraph":false},{"content":"But this time, note how we got the 3. ","startTime":998050,"duration":2900,"startOfParagraph":false},{"content":"We took the--we just take the 3 itself","startTime":1000950,"duration":5740,"startOfParagraph":false},{"content":"because it's surrounded by negatives on both sides, ","startTime":1006690,"duration":3290,"startOfParagraph":false},{"content":"which will bring a sum < 3. ","startTime":1009980,"duration":5100,"startOfParagraph":false},{"content":"Let's run on 10 items. ","startTime":1015080,"duration":2740,"startOfParagraph":false},{"content":"This time it's 7, we take the leading 3 and 4.","startTime":1017820,"duration":5380,"startOfParagraph":false},{"content":"This time it's 8, and we obtain that by taking 1, 4 and 3. ","startTime":1023200,"duration":6250,"startOfParagraph":false},{"content":"So to give you an intuition on how we can solve this transformed problem, ","startTime":1029450,"duration":6860,"startOfParagraph":false},{"content":"let's take a look at this subarray. ","startTime":1036310,"duration":2580,"startOfParagraph":false},{"content":"We're given this input array, and we know the answer is 8. ","startTime":1038890,"duration":4570,"startOfParagraph":false},{"content":"We take the 1, 4, and 3. ","startTime":1043460,"duration":2899,"startOfParagraph":false},{"content":"But let's look at how we actually got that answer. ","startTime":1046359,"duration":2731,"startOfParagraph":false},{"content":"Let's look at the maximal subarray that ended at each of these indices. ","startTime":1049090,"duration":5070,"startOfParagraph":false},{"content":"What's the maximal subarray that has to end at the first position? ","startTime":1054160,"duration":6620,"startOfParagraph":false},{"content":"[Student] Zero. >>Zero. Just don't take the -5. ","startTime":1060780,"duration":5530,"startOfParagraph":false},{"content":"Here it's going to be 0 as well. Yeah? ","startTime":1066310,"duration":3900,"startOfParagraph":false},{"content":"(student, unintelligible)","startTime":1070210,"duration":6260,"startOfParagraph":false},{"content":"[Yu] Oh, sorry, it is a -3. ","startTime":1076470,"duration":2490,"startOfParagraph":false},{"content":"So this is a 2, this is a -3. ","startTime":1078960,"duration":4260,"startOfParagraph":false},{"content":"Okay. So -4, what's the maximal subarray to end that position ","startTime":1083220,"duration":5470,"startOfParagraph":false},{"content":"where -4 is at? Zero. ","startTime":1088690,"duration":4220,"startOfParagraph":false},{"content":"One? 1, 5, 8. ","startTime":1092910,"duration":9660,"startOfParagraph":false},{"content":"Now, I must end at the location where -2 is at. ","startTime":1102570,"duration":5490,"startOfParagraph":false},{"content":"So 6, 5, 7, and the last one is 4. ","startTime":1108060,"duration":11270,"startOfParagraph":false},{"content":"Knowing that these are my entries","startTime":1119330,"duration":4150,"startOfParagraph":false},{"content":"for the transformed problem where I must end at each of these indices, ","startTime":1123480,"duration":4650,"startOfParagraph":false},{"content":"then my final answer is just, take a sweep across, ","startTime":1128130,"duration":3280,"startOfParagraph":false},{"content":"and take the maximum number. ","startTime":1131410,"duration":2170,"startOfParagraph":false},{"content":"So in this case it's 8. ","startTime":1133580,"duration":2040,"startOfParagraph":false},{"content":"This implies that the maximal subarray ends at this index, ","startTime":1135620,"duration":4390,"startOfParagraph":false},{"content":"and started somewhere before it. ","startTime":1140010,"duration":4960,"startOfParagraph":false},{"content":"Does everyone understand this transformed subarray?","startTime":1144970,"duration":4660,"startOfParagraph":false},{"content":"Okay. Well, let's figure out the recurrence for this. ","startTime":1149630,"duration":12530,"startOfParagraph":true},{"content":"Let's consider just the first few entries. ","startTime":1162160,"duration":5830,"startOfParagraph":false},{"content":"So here it was 0, 0, 0, 1, 5, 8. ","startTime":1167990,"duration":7940,"startOfParagraph":false},{"content":"And then there was a -2 here, and that brought it down to 6. ","startTime":1175930,"duration":3860,"startOfParagraph":false},{"content":"So if I call the entry at position i subproblem(i), ","startTime":1179790,"duration":11010,"startOfParagraph":false},{"content":"how can I use the answer to a previous subproblem","startTime":1190800,"duration":4110,"startOfParagraph":false},{"content":"to answer this subproblem? ","startTime":1194910,"duration":4450,"startOfParagraph":false},{"content":"If I look at, let's say, this entry. ","startTime":1199360,"duration":5190,"startOfParagraph":false},{"content":"How can I compute the answer 6 by looking at ","startTime":1204550,"duration":4640,"startOfParagraph":false},{"content":"a combination of this array and the answers to previous subproblems in this array? Yes?","startTime":1209190,"duration":9590,"startOfParagraph":false},{"content":"[Female student] You take the array of sums","startTime":1218780,"duration":4020,"startOfParagraph":false},{"content":"in the position right before it, so the 8, ","startTime":1222800,"duration":2630,"startOfParagraph":false},{"content":"and then you add the current subproblem.","startTime":1225430,"duration":6740,"startOfParagraph":false},{"content":"[Yu] So her suggestion is to look at these two numbers, ","startTime":1232170,"duration":4290,"startOfParagraph":false},{"content":"this number and this number. ","startTime":1236460,"duration":3630,"startOfParagraph":false},{"content":"So this 8 refers to the answer for the subproblem (i - 1). ","startTime":1240090,"duration":10040,"startOfParagraph":false},{"content":"And let's call my input array A. ","startTime":1250130,"duration":7170,"startOfParagraph":false},{"content":"In order to find a maximal subarray that ends at position i, ","startTime":1257300,"duration":4170,"startOfParagraph":false},{"content":"I have two choices: I can either continue the subarray ","startTime":1261470,"duration":2510,"startOfParagraph":false},{"content":"that ended at the previous index, or start a new array. ","startTime":1263980,"duration":5810,"startOfParagraph":false},{"content":"If I were to continue the subarray that started at the previous index, ","startTime":1269790,"duration":4400,"startOfParagraph":false},{"content":"then the maximum sum I can achieve is the answer to the previous subproblem","startTime":1274190,"duration":5070,"startOfParagraph":false},{"content":"plus the current array entry. ","startTime":1279260,"duration":4860,"startOfParagraph":false},{"content":"But, I also have the choice of starting a new subarray, ","startTime":1284120,"duration":3430,"startOfParagraph":false},{"content":"in which case the sum is 0. ","startTime":1287550,"duration":3280,"startOfParagraph":false},{"content":"So the answer is max of 0, subproblem i - 1, plus the current array entry. ","startTime":1290830,"duration":12030,"startOfParagraph":false},{"content":"Does this recurrence make sense? ","startTime":1302860,"duration":3290,"startOfParagraph":false},{"content":"Our recurrence, as we just discovered, is subproblem i ","startTime":1306150,"duration":4690,"startOfParagraph":false},{"content":"is equal to the maximum of the previous subproblem plus my current array entry, ","startTime":1310840,"duration":3900,"startOfParagraph":false},{"content":"which means continue the previous subarray,","startTime":1314740,"duration":6750,"startOfParagraph":false},{"content":"or 0, start a new subarray at my current index. ","startTime":1321490,"duration":5760,"startOfParagraph":false},{"content":"And once we have built up this table of solutions, then our final answer, ","startTime":1327250,"duration":2810,"startOfParagraph":false},{"content":"just do a linear sweep across the subproblem array","startTime":1330060,"duration":3890,"startOfParagraph":false},{"content":"and take the maximum number. ","startTime":1333950,"duration":5940,"startOfParagraph":false},{"content":"This is an exact implementation of what I just said. ","startTime":1339890,"duration":3440,"startOfParagraph":false},{"content":"So we create a new subproblem array, subproblems. ","startTime":1343330,"duration":3990,"startOfParagraph":false},{"content":"The first entry is either 0 or the first entry, the maximum of those two. ","startTime":1347320,"duration":5010,"startOfParagraph":false},{"content":"And for the rest of the subproblems ","startTime":1352330,"duration":3340,"startOfParagraph":false},{"content":"we use the exact recurrence we just discovered. ","startTime":1355670,"duration":4140,"startOfParagraph":false},{"content":"Now we compute the maximum of our subproblems array, and that's our final answer. ","startTime":1359810,"duration":10150,"startOfParagraph":false},{"content":"So how much space are we using in this algorithm?","startTime":1369960,"duration":4170,"startOfParagraph":true},{"content":"If you've only taken CS50, then you might not have discussed space very much. ","startTime":1374130,"duration":7340,"startOfParagraph":false},{"content":"Well, one thing to note is that I called malloc here with size n. ","startTime":1381470,"duration":6280,"startOfParagraph":false},{"content":"What does that suggest to you?","startTime":1387750,"duration":5840,"startOfParagraph":false},{"content":"This algorithm uses linear space. ","startTime":1393590,"duration":3860,"startOfParagraph":false},{"content":"Can we do better?","startTime":1397450,"duration":3580,"startOfParagraph":false},{"content":"Is there anything that you notice that is unnecessary to compute the final answer? ","startTime":1401030,"duration":9750,"startOfParagraph":false},{"content":"I guess a better question is, what information","startTime":1410780,"duration":2510,"startOfParagraph":false},{"content":"do we not need to carry all the way through to the end?","startTime":1413290,"duration":7390,"startOfParagraph":false},{"content":"Now, if we look at these two lines, ","startTime":1420680,"duration":3600,"startOfParagraph":false},{"content":"we only care about the previous subproblem, ","startTime":1424280,"duration":3440,"startOfParagraph":false},{"content":"and we only care about the maximum we've ever seen so far. ","startTime":1427720,"duration":3190,"startOfParagraph":false},{"content":"To compute our final answer, we don't need the entire array. ","startTime":1430910,"duration":2700,"startOfParagraph":false},{"content":"We only need the last number, last two numbers. ","startTime":1433610,"duration":3840,"startOfParagraph":false},{"content":"Last number for the subproblem array, and last number for the maximum. ","startTime":1437450,"duration":5180,"startOfParagraph":false},{"content":"So, in fact, we can fuse these loops together","startTime":1442630,"duration":4750,"startOfParagraph":false},{"content":"and go from linear space to constant space. ","startTime":1447380,"duration":3080,"startOfParagraph":false},{"content":"Current sum so far, here, replaces the role of subproblem, our subproblem array. ","startTime":1450460,"duration":5370,"startOfParagraph":false},{"content":"So current sum, so far, is the answer to the previous subproblem. ","startTime":1455830,"duration":4190,"startOfParagraph":false},{"content":"And that sum, so far, takes the place of our max. ","startTime":1460020,"duration":3430,"startOfParagraph":false},{"content":"We compute the maximum as we go along. ","startTime":1463450,"duration":4650,"startOfParagraph":false},{"content":"And so we go from linear space to constant space, ","startTime":1468100,"duration":2790,"startOfParagraph":false},{"content":"and we also have a linear solution to our subarray problem. ","startTime":1470890,"duration":5760,"startOfParagraph":false},{"content":"These kinds of questions you will get during an interview. ","startTime":1476650,"duration":4090,"startOfParagraph":true},{"content":"What is the time complexity; what is the space complexity? ","startTime":1480740,"duration":3710,"startOfParagraph":false},{"content":"Can you do better? Are there things that are unnecessary to keep around? ","startTime":1484450,"duration":6150,"startOfParagraph":false},{"content":"I did this to highlight analyses that you should take on your own ","startTime":1490600,"duration":4670,"startOfParagraph":false},{"content":"as you're working through these problems. ","startTime":1495270,"duration":2130,"startOfParagraph":false},{"content":"Always be asking yourself, \"Can I do better?\" ","startTime":1497400,"duration":4310,"startOfParagraph":false},{"content":"In fact, can we do better than this? ","startTime":1501710,"duration":6090,"startOfParagraph":false},{"content":"Sort of a trick question. You can't, because you need to ","startTime":1507800,"duration":2930,"startOfParagraph":false},{"content":"at least read the input to the problem. ","startTime":1510730,"duration":2860,"startOfParagraph":false},{"content":"So the fact that you need to at least read the input to the problem ","startTime":1513590,"duration":1980,"startOfParagraph":false},{"content":"means that you can't do better than linear time, ","startTime":1515570,"duration":4010,"startOfParagraph":false},{"content":"and you can't do better than constant space. ","startTime":1519580,"duration":3290,"startOfParagraph":false},{"content":"So this is, in fact, the best solution to this problem. ","startTime":1522870,"duration":4190,"startOfParagraph":false},{"content":"Questions? Okay. ","startTime":1527060,"duration":5980,"startOfParagraph":false},{"content":"Stock market problem: ","startTime":1533040,"duration":2150,"startOfParagraph":true},{"content":"\"Given an array of n integers, positive, zero, or negative, ","startTime":1535190,"duration":3160,"startOfParagraph":false},{"content":"that represent the price of a stock over n days, ","startTime":1538350,"duration":3330,"startOfParagraph":false},{"content":"write a function to compute the maximum profit you can make","startTime":1541680,"duration":2400,"startOfParagraph":false},{"content":"given that you buy and sell exactly 1 stock within these n days.\"","startTime":1544080,"duration":5270,"startOfParagraph":false},{"content":"Essentially, we want to buy low, sell high. ","startTime":1549350,"duration":2340,"startOfParagraph":false},{"content":"And we want to figure out the best profit we can make. ","startTime":1551690,"duration":6890,"startOfParagraph":false},{"content":"Going back to my tip, what is the immediately clear, simplest answer, but it's slow?","startTime":1558580,"duration":12920,"startOfParagraph":false},{"content":"Yes? (student, unintelligible) >>Yes. ","startTime":1571500,"duration":6190,"startOfParagraph":false},{"content":">>So you would just go though and look at the stock prices ","startTime":1577690,"duration":3780,"startOfParagraph":false},{"content":"at each point in time, (unintelligible).","startTime":1581470,"duration":9080,"startOfParagraph":false},{"content":"[Yu] Okay, so her solution--her suggestion of computing ","startTime":1590550,"duration":3440,"startOfParagraph":false},{"content":"the lowest and computing the highest doesn't necessarily work","startTime":1593990,"duration":3390,"startOfParagraph":false},{"content":"because the highest might occur before the lowest. ","startTime":1597380,"duration":5090,"startOfParagraph":false},{"content":"So what is the brute force solution to this problem? ","startTime":1602470,"duration":4870,"startOfParagraph":false},{"content":"What are the two things that I need to uniquely determine the profit I make? Right. ","startTime":1607340,"duration":5810,"startOfParagraph":false},{"content":"The brute force solution is--oh, so, George's suggestion is we only need two days","startTime":1613150,"duration":6260,"startOfParagraph":false},{"content":"to uniquely determine the profit of those two days. ","startTime":1619410,"duration":3470,"startOfParagraph":false},{"content":"So we compute every pair, like buy/sell, ","startTime":1622880,"duration":3780,"startOfParagraph":false},{"content":"compute the profit, which could be negative or positive or zero. ","startTime":1626660,"duration":6190,"startOfParagraph":false},{"content":"Compute the maximum profit that we make after iterating over all pairs of days. ","startTime":1632850,"duration":5150,"startOfParagraph":false},{"content":"That will be our final answer. ","startTime":1638000,"duration":2330,"startOfParagraph":false},{"content":"And that solution will be O(n^2), because there is n choose two pairs--","startTime":1640330,"duration":5400,"startOfParagraph":false},{"content":"of days that you can choose among end days. ","startTime":1645730,"duration":4540,"startOfParagraph":false},{"content":"Okay, so I'm not going to go over the brute force solution here. ","startTime":1650270,"duration":2310,"startOfParagraph":false},{"content":"I'm going to tell you that there's an n log n solution. ","startTime":1652580,"duration":4840,"startOfParagraph":false},{"content":"What algorithm do you currently know that is n log n?","startTime":1657420,"duration":8130,"startOfParagraph":false},{"content":"It's not a trick question. ","startTime":1665550,"duration":5180,"startOfParagraph":false},{"content":"Merge sort. Merge sort is n log n, ","startTime":1670730,"duration":4060,"startOfParagraph":true},{"content":"and in fact, one way of solving this problem is to use","startTime":1674790,"duration":2970,"startOfParagraph":false},{"content":"a merge sort kind of idea called, in general, divide and conquer. ","startTime":1677760,"duration":6640,"startOfParagraph":false},{"content":"And the idea is as follows. ","startTime":1684400,"duration":3170,"startOfParagraph":false},{"content":"You want to compute the best buy/sell pair in the left half. ","startTime":1687570,"duration":4830,"startOfParagraph":false},{"content":"Find the best profit you can make, just with the first n over two days. ","startTime":1692400,"duration":4080,"startOfParagraph":false},{"content":"Then you want to oompute the best buy/sell pair on the right half, ","startTime":1696480,"duration":3300,"startOfParagraph":false},{"content":"so the last n over two days. ","startTime":1699780,"duration":4150,"startOfParagraph":false},{"content":"And now the question is, how do we merge these solutions back together? ","startTime":1703930,"duration":8470,"startOfParagraph":false},{"content":"Yes? (student, unintelligible)","startTime":1712400,"duration":3920,"startOfParagraph":false},{"content":">>Okay. So let me draw a picture. ","startTime":1716320,"duration":13570,"startOfParagraph":false},{"content":"Yes? (George, unintelligible)","startTime":1729890,"duration":13980,"startOfParagraph":false},{"content":">>Exactly. George's solution is exactly right. ","startTime":1743870,"duration":2580,"startOfParagraph":false},{"content":"So his suggestion is, first compute the best buy/sell pair, ","startTime":1746450,"duration":3590,"startOfParagraph":false},{"content":"and that occurs in the left half, so let's call that left, left. ","startTime":1750040,"duration":6010,"startOfParagraph":false},{"content":"Best buy/sell pair that occurs in the right half. ","startTime":1756050,"duration":4740,"startOfParagraph":false},{"content":"But if we only compared these two numbers, we're missing the case","startTime":1760790,"duration":4390,"startOfParagraph":false},{"content":"where we buy here and sell somewhere in the right half. ","startTime":1765180,"duration":5280,"startOfParagraph":false},{"content":"We buy in the left half, sell in the right half. ","startTime":1770460,"duration":3350,"startOfParagraph":false},{"content":"And the best way to compute the best buy/sell pair that spans both halves","startTime":1773810,"duration":4680,"startOfParagraph":false},{"content":"is to compute the minimum here and compute the maximum here","startTime":1778490,"duration":4990,"startOfParagraph":false},{"content":"and take their difference. ","startTime":1783480,"duration":2100,"startOfParagraph":false},{"content":"So the two cases where the buy/sell pair occurs only here, ","startTime":1785580,"duration":5270,"startOfParagraph":false},{"content":"only here, or on both halves is defined by these three numbers. ","startTime":1790850,"duration":11060,"startOfParagraph":false},{"content":"So our algorithm to merge our solutions back together, ","startTime":1801910,"duration":4540,"startOfParagraph":false},{"content":"we want to compute the best buy/sell pair ","startTime":1806450,"duration":1900,"startOfParagraph":false},{"content":"where we buy on the left half and sell on the right half. ","startTime":1808350,"duration":4770,"startOfParagraph":false},{"content":"And the best way to do that is to compute the lowest price in the first half, ","startTime":1813120,"duration":3620,"startOfParagraph":false},{"content":"the highest price in the right half, and take their difference. ","startTime":1816740,"duration":3620,"startOfParagraph":false},{"content":"The resulting three profits, these three numbers, you take the maximum of the three, ","startTime":1820360,"duration":5030,"startOfParagraph":false},{"content":"and that's the best profit you can make over these first and end days. ","startTime":1825390,"duration":7330,"startOfParagraph":false},{"content":"Here the important lines are in red. ","startTime":1832720,"duration":4220,"startOfParagraph":false},{"content":"This is a recursive call to compute the answer in the left half. ","startTime":1836940,"duration":4220,"startOfParagraph":false},{"content":"This is a recursive call to compute the answer in the right half. ","startTime":1841160,"duration":3600,"startOfParagraph":false},{"content":"These two for loops compute the min and the max on the left and right half, respectively. ","startTime":1844760,"duration":5960,"startOfParagraph":false},{"content":"Now I compute the profit that spans both halves, ","startTime":1850720,"duration":4250,"startOfParagraph":false},{"content":"and the final answer is the maximum of these three. ","startTime":1854970,"duration":5560,"startOfParagraph":false},{"content":"Okay. ","startTime":1860530,"duration":3590,"startOfParagraph":false},{"content":"So, sure, we have an algorithm, but the bigger question is, ","startTime":1864120,"duration":2300,"startOfParagraph":true},{"content":"what is the time complexity of this? ","startTime":1866420,"duration":1870,"startOfParagraph":false},{"content":"And the reason why I mentioned merge sort is that this form of divide the answer","startTime":1868290,"duration":7900,"startOfParagraph":false},{"content":"into two and then merging our solutions back together","startTime":1876190,"duration":3010,"startOfParagraph":false},{"content":"is exactly the form of merge sort. ","startTime":1879200,"duration":4380,"startOfParagraph":false},{"content":"So let me go through the duration.","startTime":1883580,"duration":9780,"startOfParagraph":false},{"content":"If we defined a function t(n) to be the number of steps ","startTime":1893360,"duration":7980,"startOfParagraph":false},{"content":"for n days, ","startTime":1901340,"duration":8670,"startOfParagraph":false},{"content":"our two recursive calls ","startTime":1910010,"duration":4340,"startOfParagraph":false},{"content":"are each going to cost t(n/2), ","startTime":1914350,"duration":6110,"startOfParagraph":false},{"content":"and there's two of these calls. ","startTime":1920460,"duration":3080,"startOfParagraph":false},{"content":"Now I need to compute the minimum of the left half, ","startTime":1923540,"duration":6480,"startOfParagraph":false},{"content":"which I can do in n/2 time, plus the maximum of the right half. ","startTime":1930020,"duration":7030,"startOfParagraph":false},{"content":"So this is just n. ","startTime":1937050,"duration":3770,"startOfParagraph":false},{"content":"And then plus some constant work. ","startTime":1940820,"duration":4230,"startOfParagraph":false},{"content":"And this recurrence equation ","startTime":1945050,"duration":2720,"startOfParagraph":false},{"content":"is exactly the recurrence equation for merge sort. ","startTime":1947770,"duration":7790,"startOfParagraph":false},{"content":"And we all know that merge sort is n log n time. ","startTime":1955560,"duration":3610,"startOfParagraph":false},{"content":"Therefore, our algorithm is also n log n time. ","startTime":1959170,"duration":7710,"startOfParagraph":false},{"content":"Does this iteration make sense? ","startTime":1966880,"duration":5340,"startOfParagraph":false},{"content":"Just a brief recap of this: ","startTime":1972220,"duration":3560,"startOfParagraph":false},{"content":"T(n) is the number of steps to compute the maximum profit","startTime":1975780,"duration":3390,"startOfParagraph":false},{"content":"over the course of n days. ","startTime":1979170,"duration":3580,"startOfParagraph":false},{"content":"The way we split up our recursive calls ","startTime":1982750,"duration":3260,"startOfParagraph":false},{"content":"is by calling our solution on the first n/2 days, ","startTime":1986010,"duration":5970,"startOfParagraph":false},{"content":"so that's one call, ","startTime":1991980,"duration":2510,"startOfParagraph":false},{"content":"and then we call again on the second half. ","startTime":1994490,"duration":2450,"startOfParagraph":false},{"content":"So that's two calls. ","startTime":1996940,"duration":3500,"startOfParagraph":false},{"content":"And then we find a minimum on the left half, which we can do in linear time,","startTime":2000440,"duration":4870,"startOfParagraph":false},{"content":"find the maximum of the right half, which we can do in linear time. ","startTime":2005310,"duration":3700,"startOfParagraph":false},{"content":"So n/2 + n/2 is just n. ","startTime":2009010,"duration":2560,"startOfParagraph":false},{"content":"Then we have some constant work, which is like doing arithmetic. ","startTime":2011570,"duration":4450,"startOfParagraph":false},{"content":"This recurrence equation is exactly the recurrence equation for merge sort. ","startTime":2016020,"duration":3840,"startOfParagraph":false},{"content":"Hence, our shuffle algorithm is also n log n. ","startTime":2019860,"duration":15630,"startOfParagraph":false},{"content":"So how much space are we using? ","startTime":2035490,"duration":3030,"startOfParagraph":false},{"content":"Let's go back to the code. ","startTime":2038520,"duration":6390,"startOfParagraph":false},{"content":"A better question is, how many stack frames do we ever have at any given moment? ","startTime":2044910,"duration":4510,"startOfParagraph":true},{"content":"Since we're using recursion, ","startTime":2049420,"duration":2029,"startOfParagraph":false},{"content":"the number of stack frames determines our space usage. ","startTime":2051449,"duration":12081,"startOfParagraph":false},{"content":"Let's consider n = 8. ","startTime":2063530,"duration":5910,"startOfParagraph":false},{"content":"We call shuffle on 8, ","startTime":2069440,"duration":7449,"startOfParagraph":false},{"content":"which will call shuffle on the first four entries, ","startTime":2076889,"duration":4691,"startOfParagraph":false},{"content":"which will call a shuffle on the first two entries. ","startTime":2081580,"duration":4670,"startOfParagraph":false},{"content":"So our stack is--this is our stack. ","startTime":2086250,"duration":5300,"startOfParagraph":false},{"content":"And then we call shuffle again on 1, ","startTime":2091550,"duration":3430,"startOfParagraph":false},{"content":"and that's what our base case is, so we return immediately. ","startTime":2094980,"duration":3090,"startOfParagraph":false},{"content":"Do we ever have more than this many stack frames? ","startTime":2098070,"duration":6630,"startOfParagraph":false},{"content":"No. Because each time we do an invocation, ","startTime":2104700,"duration":4180,"startOfParagraph":false},{"content":"a recursive invocation to shuffle, ","startTime":2108880,"duration":1890,"startOfParagraph":false},{"content":"we divide our size in half. ","startTime":2110770,"duration":3180,"startOfParagraph":false},{"content":"So the maximum number of stack frames we ever have at any given moment ","startTime":2113950,"duration":3070,"startOfParagraph":false},{"content":"is on the order of log n stack frames. ","startTime":2117020,"duration":11440,"startOfParagraph":false},{"content":"Each stack frame has constant space, ","startTime":2128460,"duration":14000,"startOfParagraph":false},{"content":"and therefore the total amount of space, ","startTime":2142460,"duration":1950,"startOfParagraph":false},{"content":"the maximum amount of space we ever use is O(log n) space","startTime":2144410,"duration":4830,"startOfParagraph":false},{"content":"where n is the number of days. ","startTime":2149240,"duration":13800,"startOfParagraph":false},{"content":"Now, always ask yourself, \"Can we do better?\"","startTime":2163040,"duration":4190,"startOfParagraph":true},{"content":"And in particular, can we reduce this to a problem we've already solved? ","startTime":2167230,"duration":5160,"startOfParagraph":false},{"content":"A hint: we only discussed two other problems before this, and it's not going to be shuffle. ","startTime":2172390,"duration":7650,"startOfParagraph":false},{"content":"We can convert this stock market problem into the maximal subarray problem. ","startTime":2180040,"duration":6160,"startOfParagraph":false},{"content":"How can we do this?","startTime":2186200,"duration":13900,"startOfParagraph":false},{"content":"One of you? Emmy? ","startTime":2200100,"duration":2470,"startOfParagraph":false},{"content":"(Emmy, unintelligible)","startTime":2202570,"duration":5110,"startOfParagraph":false},{"content":"[Yu] Exactly. ","startTime":2207680,"duration":6180,"startOfParagraph":false},{"content":"So the maximal subarray problem, ","startTime":2213860,"duration":6080,"startOfParagraph":false},{"content":"we're looking for a sum over a continuous subarray. ","startTime":2219940,"duration":10670,"startOfParagraph":false},{"content":"And Emmy's suggestion for the stocks problem, ","startTime":2230610,"duration":5620,"startOfParagraph":false},{"content":"consider the changes, or the deltas. ","startTime":2236230,"duration":14490,"startOfParagraph":false},{"content":"And a picture of this is--this is the price of a stock, ","startTime":2250720,"duration":6720,"startOfParagraph":false},{"content":"but if we took the difference between each consecutive day--","startTime":2257440,"duration":5170,"startOfParagraph":false},{"content":"so we see that the maximum price, maximum profit we could make ","startTime":2262610,"duration":2590,"startOfParagraph":false},{"content":"is if we buy here and sell here. ","startTime":2265200,"duration":4870,"startOfParagraph":false},{"content":"But let's look at the continuous--let's look at the subarray problem. ","startTime":2270070,"duration":4170,"startOfParagraph":false},{"content":"So here, we can make--going from here to here, ","startTime":2274240,"duration":8270,"startOfParagraph":false},{"content":"we have a positive change, and then going from here to here we have a negative change. ","startTime":2282510,"duration":5900,"startOfParagraph":false},{"content":"But then, going from here to here we have a huge positive change. ","startTime":2288410,"duration":5810,"startOfParagraph":false},{"content":"And these are the changes that we want to sum up to get our final profit. ","startTime":2294220,"duration":6710,"startOfParagraph":false},{"content":"Then we have more negative changes here. ","startTime":2300930,"duration":4230,"startOfParagraph":false},{"content":"The key to reducing our stock problem into our maximal subarray problem","startTime":2305160,"duration":4830,"startOfParagraph":false},{"content":"is to consider the deltas between days. ","startTime":2309990,"duration":6640,"startOfParagraph":false},{"content":"So we create a new array called deltas, ","startTime":2316630,"duration":4000,"startOfParagraph":false},{"content":"initialize the first entry to be 0, ","startTime":2320630,"duration":2370,"startOfParagraph":false},{"content":"and then for each delta(i), let that be the difference","startTime":2323000,"duration":3380,"startOfParagraph":false},{"content":"of my input array(i), and array(i - 1). ","startTime":2326380,"duration":6450,"startOfParagraph":false},{"content":"Then we call our routine procedure for a maximal subarray","startTime":2332830,"duration":2700,"startOfParagraph":false},{"content":"passing in a delta's array. ","startTime":2335530,"duration":5970,"startOfParagraph":false},{"content":"And because maximal subarray is linear time, ","startTime":2341500,"duration":4940,"startOfParagraph":false},{"content":"and this reduction, this process of creating this delta array,","startTime":2346440,"duration":2930,"startOfParagraph":false},{"content":"is also linear time,","startTime":2349370,"duration":2410,"startOfParagraph":false},{"content":"then the final solution for stocks is O(n) work plus O(n) work, is still O(n) work. ","startTime":2351780,"duration":7280,"startOfParagraph":false},{"content":"So we have a linear time solution to our problem. ","startTime":2359060,"duration":4840,"startOfParagraph":false},{"content":"Does everyone understand this transformation? ","startTime":2363900,"duration":5710,"startOfParagraph":false},{"content":"In general, a good idea that you should always have ","startTime":2369610,"duration":2530,"startOfParagraph":true},{"content":"is try to reduce a new problem that you're seeing.","startTime":2372140,"duration":2150,"startOfParagraph":false},{"content":"If it looks familiar to an old problem, ","startTime":2374290,"duration":3410,"startOfParagraph":false},{"content":"try reducing it to an old problem. ","startTime":2377700,"duration":1890,"startOfParagraph":false},{"content":"And if you can use all the tools that you've used on the old problem ","startTime":2379590,"duration":2360,"startOfParagraph":false},{"content":"to solve the new problem. ","startTime":2381950,"duration":4500,"startOfParagraph":false},{"content":"So to wrap up, technical interviews are challenging. ","startTime":2386450,"duration":2560,"startOfParagraph":false},{"content":"These problems are probably some of the more difficult problems","startTime":2389010,"duration":3270,"startOfParagraph":false},{"content":"that you might see in an interview, ","startTime":2392280,"duration":2420,"startOfParagraph":false},{"content":"so if you don't understand all the problems that I just covered, it's okay. ","startTime":2394700,"duration":2990,"startOfParagraph":false},{"content":"These are some of the more challenging problems. ","startTime":2397690,"duration":3390,"startOfParagraph":false},{"content":"Practice, practice, practice. ","startTime":2401080,"duration":1970,"startOfParagraph":false},{"content":"I gave a lot of problems in the handout, so definitely check those out. ","startTime":2403050,"duration":5120,"startOfParagraph":false},{"content":"And good luck on your interviews. All my resources are posted at this link, ","startTime":2408170,"duration":3520,"startOfParagraph":false},{"content":"and one of my senior friends has offered to do mock technical interviews, ","startTime":2411690,"duration":3530,"startOfParagraph":false},{"content":"so if you're interested, email Will Yao at that email address. ","startTime":2415220,"duration":6830,"startOfParagraph":false},{"content":"If you have some questions, you can ask me. ","startTime":2422050,"duration":4020,"startOfParagraph":false},{"content":"Do you guys have specific questions related to technical interviews","startTime":2426070,"duration":2710,"startOfParagraph":false},{"content":"or any problems we've seen so far? ","startTime":2428780,"duration":9660,"startOfParagraph":false},{"content":"Okay. Well, good luck on your interviews. ","startTime":2438440,"duration":11470,"startOfParagraph":false},{"content":"[CS50.TV]","startTime":2449910,"duration":3000,"startOfParagraph":false}]}