LARGEST RECTANGLE IN HISTOGRAM - Leetcode 84 - Python

Поділитися
Вставка
  • Опубліковано 3 лют 2025

КОМЕНТАРІ • 238

  • @NeetCode
    @NeetCode  4 роки тому +51

    🚀 neetcode.io/ - I created a FREE site to make interview prep a lot easier, hope it helps! ❤

  • @technophile_
    @technophile_ 10 місяців тому +21

    I think this is one of those problems that can be solved in an interview setting if, and only if you've solved it before. There's no way someone would be able to come up with this solution in an interview 😮‍💨

  • @kunlintan6511
    @kunlintan6511 2 роки тому +23

    Thanks! Your explaination helps a lot!

  • @xingdi986
    @xingdi986 3 роки тому +437

    Even with the video, this problem is still hard for me to understand and solve. but, anyway, thanks for explaining

    • @Chansd5
      @Chansd5 2 роки тому +18

      Samesies.

    • @harpercfc_
      @harpercfc_ 2 роки тому +56

      feel a little bit relieved seeing your comment :( it is so hard

    • @chaoluncai4300
      @chaoluncai4300 2 роки тому +32

      its also me for the first time touching the concept of mono stack. For those who's also struggling to interpret mono-stack thoroughly for the 1st time, I recommend just move on to BFS/DFS, DP, hard array problems etc. and come back to this once you are comfortable with those other skills. Then you'll notice the way you see mono-stack is much more clear and different, trust me:))

    • @carl_84
      @carl_84 2 роки тому +7

      It is hard. If they ask me this on an interview, I doubt I'll come up with this eficient solution 😅😅😅
      Maybe with a lot of hints!

    • @ethanperry8
      @ethanperry8 Рік тому +2

      When I see the monotonic stack tag on leetcode my hope of solving the problem dissipates

  • @bchen1403
    @bchen1403 2 роки тому +25

    Bumped into one of your earliest uploads and I am amazed at your progress. You improvements in tone is impressive!

  • @pl5778
    @pl5778 Рік тому +80

    this is awesome. I don't know how someone can come up with the solution in an interview for the first time.

    • @B3TheBand
      @B3TheBand Рік тому +9

      I came up with a solution by building a rectangle from each index, going left until you reach a smaller value and right until you reach a smaller value. The rectangle is the sum of those two, minus the current rectangle height (because you counted it twice, once going left and once going right).
      For an array where every value is the same, this is O(n^2), so it timed out! I think an interviewer would accept it anyway though.

    • @eloinpuga
      @eloinpuga 11 місяців тому +7

      Either you have lot's of experience with similar problems, or you already solved this one. Sometimes I have to accept that I am not a genious that comes up with solutions like this on the spot, let alone being a jr, but with enough time problems become repetitive and with that experience I might come up with that solution one day.

    • @B3TheBand
      @B3TheBand 11 місяців тому +5

      @@eloinpuga It comes with practice. You can't assume that just because a solution seems new to you now, that it's not a standard algorithm or approach.

    • @gorgolyt
      @gorgolyt 10 місяців тому +5

      @@B3TheBand Coming up with an O(n2) brute force solution is easy. Sorry but if you think the interviewer is not interested in finding the O(n) solution then you're kind of missing the point.

    • @B3TheBand
      @B3TheBand 10 місяців тому +10

      @@gorgolyt Cool. I'm a Software Engineer at Amazon. You?

  • @mandy1339
    @mandy1339 3 роки тому +18

    Repetition really helps nail down the point into my head till it clicks. Liked and subscribed. Thank you!

  • @abhilashpadmanabhan6096
    @abhilashpadmanabhan6096 2 роки тому +92

    Dude's awesome as he always is! Just a suggestion, if we add a dummy [0] to the right of heights, the extra handling for right boundary can be avoided. I tried that and got accepted. :)

    • @carl_84
      @carl_84 2 роки тому +3

      This is done in Elements of Programming Interviews in Python book.

    • @kobebyrant9483
      @kobebyrant9483 Рік тому +6

      to be honest, I found solution in the video is more intuitive and easier to understand

  • @protyaybanerjee5051
    @protyaybanerjee5051 3 роки тому +8

    What an intuitive way to handle the left boundary . Kudos!

  • @justinUoL
    @justinUoL 3 роки тому +55

    sincerely the best explanation for lc questions in 21st century. thank you!

    • @jackieli1724
      @jackieli1724 Рік тому

      I agree with you

    • @Ahmed.Shaikh
      @Ahmed.Shaikh Рік тому +7

      Nah lc explanations of the 17th century were bangers.

    • @gorgolyt
      @gorgolyt 10 місяців тому +1

      LeetCode was founded in 2011. 🙄

  • @ammarqureshi2155
    @ammarqureshi2155 3 роки тому +10

    man you are underrated, such a clear explanation. keep it up my guy!

  • @michaelsafwat1953
    @michaelsafwat1953 8 днів тому

    OG video, you can hear the keyboard clicks, the background noise, perfect just perfect, Thanks for the explanation

  • @xiaonanwang192
    @xiaonanwang192 2 роки тому +19

    It's a pretty hard question. But NeetCode explained it in a pretty good way. At first, I couldn't understand it. But in the end, I found it a very good video.

  • @fattysun1121
    @fattysun1121 8 місяців тому +21

    I would've never come up with that good of a solution with my abilities right now. Leetcode has humbled me a lot since I am an almost straight A student in college. I trip up on mediums and hard easily, it shows that GPA doesn't mean anything and I still have a long way to go with my problem solving skills.

    • @rishabharora2887
      @rishabharora2887 6 місяців тому

      All the best! :)

    • @Thanos-hp1mw
      @Thanos-hp1mw 4 місяці тому +1

      You do realize that leetcode is a completely different skill on its own right? College's alrotithms course is completely different from LC. Only some transferrable skill.

  • @danninx-rf
    @danninx-rf Рік тому +19

    This was my first ever hard problem, and I was so close to solving it-
    I hadn't considered the fact that I could leave some stacks until the end to calculate them using [ h * (len(height)-i)], so I had that for loop nested inside the original one, which gave me some time limit issues.
    These videos explain things super well, thanks 👍

  • @tarunchabarwal7726
    @tarunchabarwal7726 4 роки тому +26

    I watched couple of videos, but this one does the job :)

  • @chenhaibin2010
    @chenhaibin2010 3 роки тому +9

    The stack O(N) method deserves to be a hard problem. But you explained it so well, it did not feel that difficult after watching your video. thank you

  • @harishsn4866
    @harishsn4866 2 роки тому +2

    Such a clever solution with minimal usage of extra space and minimal function calls. Love it.

  • @-_____-
    @-_____- 2 роки тому +7

    Good stuff. I came up with a solution that used a red black tree (TreeMap in Java), but the use of a monotonic stack is brilliant and much easier to reason with.

  • @stella123www
    @stella123www 3 роки тому +2

    I like the intuition part to clear up why stack is being used, thanks!

  • @MaheshT101
    @MaheshT101 4 роки тому +5

    This is the best explanation I found for this problem. Thank you

  • @quirkyquester
    @quirkyquester 26 днів тому

    watched it twice, and the second time, it seems more clear that why and how the monotonic increasing stack came out to be the solution, and it's well explained, and its proven that it works too. thank you! definitely a really hard problem.

  • @80kg
    @80kg 3 роки тому +6

    Thank you for the most clear explanation and code as always!

  • @rushilv4102
    @rushilv4102 2 роки тому +2

    Blown away by the logic!
    Thankyou for the clear and concise explanation.

  • @andreytamelo1183
    @andreytamelo1183 2 роки тому +1

    Thanks!

  • @Rob-147
    @Rob-147 Рік тому +5

    Got to 96/98 then got time limit exceeded. Now time to watch your approach :D. Wow, that approach was much better, was able to code it up no problem. Thanks again!!!

    • @cgcrack4672
      @cgcrack4672 Рік тому

      I was able to come up with brute force and the test cases are like 87, can you please share your approach.

  • @for_whom_the_bell_tolls
    @for_whom_the_bell_tolls 2 місяці тому

    Man you are the best across UA-cam in this, by far!

  • @gregoryvan9474
    @gregoryvan9474 2 роки тому +8

    you made it easy to understand but I dont think I could come up with that answer in an interview setting if I have never seen the problem before....

  • @TechOnScreen
    @TechOnScreen 2 роки тому +3

    ultimate solution! no other explanation can beat this.

  • @gugolinyo
    @gugolinyo 2 роки тому +4

    You could use the trick to iterate for(int i = 0; i

  • @chriss6114
    @chriss6114 4 роки тому +4

    amazing algorithm and explanation. Really great solution you got.

  • @niraiarasu131
    @niraiarasu131 Рік тому +5

    I solved the problem by myself and cameup with this intutive approach, just find next smaller and prev smaller element
    class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
    n = len(heights)
    nse = [n]*n
    pse = [-1]*n
    ans = 0
    #nse
    stack = [0]
    for i in range(1,n):
    while stack and heights[i]

    • @harshasshet6755
      @harshasshet6755 28 днів тому

      brother this is just the naive approach having a time complexity of O(4N),though great you solved it on your own appreciate it man cos i couldnt on my own

  • @gaurishaaaa
    @gaurishaaaa Рік тому

    with every video the respect for you just increases. Great work navdeep!

  • @get_out_it
    @get_out_it 9 місяців тому

    first i didn't catch this solution but now i understand. You have topnotch skills.

  • @DonTaldo
    @DonTaldo 3 роки тому +1

    Just awesome man, such a nice explanation! I needed only the first ten minutes to figure it out what I was missing

  • @abdulnarimanov2256
    @abdulnarimanov2256 4 роки тому +4

    best explanator in youtube

  • @B3TheBand
    @B3TheBand Рік тому +3

    This is the last problem in the Grind 75. I solved it with O(n^2) but the time limit exceeded. You're gonna help me complete the Grind 75 let's goooooo

  • @suhaneemavar5573
    @suhaneemavar5573 2 роки тому +1

    This is the best optimized solution I've seen till now..👌🏻👏🏻 Thank you so much for the best explanation.❤Your solutions are always optimal and also get to learn complete thought process step by step . I always watch solution from this channel first. This channel is amazing, I follow all the playlist of this channel. I feel fortunate that I got this channel when I started preparing DSA.

  • @jingwenren8157
    @jingwenren8157 3 роки тому +2

    Very clear explanation on the example!! Thank you very much!!👍

  • @therealg9542
    @therealg9542 Рік тому

    Your explanation is so good, I didn't even have to look at the code solution!

  • @inderwool
    @inderwool Рік тому

    thanks, bud. stuck on this for hours trying to over engineer a solution using sorting + linked list but it kept failing because TLE. I like your approach so much better.

  • @binilg
    @binilg 2 роки тому

    This was a hard problem for me and this video is the one which worked out best for me. Thanks for this video.

  • @shubhamkaudewar7297
    @shubhamkaudewar7297 Місяць тому

    The explanation is so nice I am able to solve question just by listening approach. So simple

  • @davidsha
    @davidsha 7 місяців тому

    For anyone who wants a simpler solution to the example in the video, you can simply add another height to the input with `height.append(0)`:
    class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
    stack = []
    res = 0
    heights.append(0)
    for i in range(len(heights)):
    j = i
    while stack != [] and stack[-1][1] > heights[i]:
    popped = stack.pop()
    j = popped[0]
    area = (i - j) * popped[1]
    res = max(area, res)
    stack.append((j, heights[i]))
    return res

  • @n1724k
    @n1724k Рік тому

    Watched 3 times, now it really clicked!
    If two consecutive bars have the same height it will be hard to do expanding to left, but the first one will take care of the rectangle anyway.

  • @JamesBond-mq7pd
    @JamesBond-mq7pd Рік тому

    Thank you. So easy to write code after explanation.

  • @BloobUbloobok
    @BloobUbloobok 11 місяців тому

    Elegant and effective solution, explanation helped me to understand what am I missing in my way of thinking, thank you! 👍

  • @cccccbgkv
    @cccccbgkv Рік тому

    This is an excellent explanation! Thank you so much for these videos!

  • @securelyinsaycure
    @securelyinsaycure 5 місяців тому

    Thank you Neetcode, this was helpful!

  • @PallNPrash
    @PallNPrash 4 роки тому +2

    very nice...Thanks for a detailed, clear explanation

  • @anujchoudhary5645
    @anujchoudhary5645 2 роки тому +2

    Thank you so much for the video. You make hard questions easy
    :)

  • @JannibalForKing
    @JannibalForKing 2 роки тому

    Wow. This is so intuitive. Thanks man, you're helping me out a lot!!

  • @jegadheeswarank6290
    @jegadheeswarank6290 11 місяців тому +1

    Awesome explanation

  • @afzhalahmed1210
    @afzhalahmed1210 2 роки тому

    Took me hours to get this one. Nice explanation NeetCode.

  • @guambomber448
    @guambomber448 7 днів тому

    Awesome video. This would be worth re-recording. 1 feedback is to visualize the stack in the opposite order where last in is at the top instead of the bottom. That would make it slightly easier to follow.

  • @weraponpat1913
    @weraponpat1913 Рік тому +1

    Imagine if this is the coding interview problem that you need to solve under 1 hour for the job

  • @ygwg6145
    @ygwg6145 Рік тому

    This algorithm is pretty intuitive from the point of view that, in order to calculate the effect of each additional vertical bar the information needed from existing bars is exactly the stack.

  • @WorkAccountTalha
    @WorkAccountTalha 8 місяців тому

    beautiful drawing and great explanation!!!!!!

  • @adityatiwari2412
    @adityatiwari2412 7 місяців тому

    Thanks for a clear explanation!

  • @konradhunter1407
    @konradhunter1407 7 місяців тому +1

    I used recursion and partitioning by the min element. It worked but was too slow for large lists.

  • @jasminehuang7748
    @jasminehuang7748 9 місяців тому

    i spend over an hour on this problem and got this O(n^2) divide and conquer solution that finds the lowest height, updates maxarea based on a rectangle using that lowest height, and then splits the array into more subarrays deliminated by that lowest height and repeats. i thought i was so smart lol

    • @krishivgubba2861
      @krishivgubba2861 9 місяців тому

      i did the same thing but got a time limit exceeded error on leetcode. did your solution pass?

    • @jasminehuang7748
      @jasminehuang7748 9 місяців тому

      @@krishivgubba2861 nope haha that's why i had to come here to see the solution

  • @yuchenwang-
    @yuchenwang- Рік тому

    Thank you so so much!! I finally understand how to solve it

  • @demaxl732
    @demaxl732 Рік тому

    I was so close to solving my first hard problem, One day i will become just as good as this guy

  • @ronniey4231
    @ronniey4231 Рік тому

    beautiful drawing and explanation❤❤

  • @kucukozturk
    @kucukozturk 9 місяців тому

    Thanks for the clear explanation.

  • @kunalkheeva
    @kunalkheeva 2 роки тому

    The Best explanation but I needed the solution in java. Thank you anyways.

  • @MotleyVideos
    @MotleyVideos 3 роки тому

    Thanks for the explanation with illustration!

  • @kingKabali
    @kingKabali 2 роки тому +1

    अद्भुत, अकल्पनीय, अविश्वसनीय

  • @arthurmorgan332
    @arthurmorgan332 4 роки тому +1

    Thanks a lot buddy, you explanation was really good. 😘

  • @deepanshuhardaha5750
    @deepanshuhardaha5750 4 роки тому

    Just Amazing algorithm and explanation...Thank a lot

  • @strayedaway19
    @strayedaway19 3 роки тому

    Awesome explanation, finally understood it.

  • @amruthammohan1667
    @amruthammohan1667 2 роки тому

    The best ever explaination ..💞

  • @maganaluis92
    @maganaluis92 4 роки тому +2

    Great explanation.

  • @shubhankarsingh8456
    @shubhankarsingh8456 2 роки тому

    Best explanation, helped a lot. Thanks a lot!!!

  • @mapo5959
    @mapo5959 2 роки тому +10

    how do you come up with this in an interview. just knowing monotonic stack isn't enough, must be legit einstein's cousin

    • @aabhishek4911
      @aabhishek4911 2 роки тому

      you cant do this in an interview unless you know the answer , or as you said you must have einsteins genes

    • @mwave3388
      @mwave3388 2 роки тому +1

      Even SWEs usually get easy/medium leetcode questions. This is just for training. And I didn't understand the explanation.

  • @ruiqiliu3114
    @ruiqiliu3114 3 роки тому

    A super hard problem...but good explanation, thx so much.

  • @dhruvgarg722
    @dhruvgarg722 4 роки тому +2

    great explanation!

  • @vietnamesedragonprince
    @vietnamesedragonprince 2 роки тому +4

    Java Code:
    if (heights.length == 1) return heights[0];
    int area = 0;
    Stack st = new Stack();

    for (int i = 0; i < heights.length; i++) {
    int[] curr = new int[] {i, heights[i]};
    while (!st.isEmpty() && st.peek()[1] > curr[1]) {
    int[] popped = st.pop();
    // Calculate height of this block only
    area = Math.max((i-popped[0]) * popped[1], area);
    curr[0] = popped[0];
    }
    st.push(curr);
    }
    int len = heights.length;
    while (!st.isEmpty()) {
    int[] curr = st.pop();
    area = Math.max(area, (len-curr[0]) * curr[1]);
    }

    return area;

  • @Arunnn241
    @Arunnn241 4 місяці тому

    A much better explanation and reasoning for this solution is this:
    We want to keep track of all rectangles we can create from left to right. How can we keep track of these rectangles? Well, if we iterate through the heights, we could add every rectangle to a list. Lets choose to store the index of the heights. But then this would be the same as our heights list except just indices (i.e. {0,1,2,3,4,5...}) and not give us any new information. So we need a way to remove elements in a way that allows us to retain knowledge of all rectangles we could create.
    What if we remove rectangles from our list when we know we reached their maximum limit? In other words, we know when a rectangle cant grow anymore which is when it meets another height that is lower (or when it meets the end of the heights i.e. an edge case), so whenever we meet a lower height lets remove the previous rectangle, calculate the largest area we could make with that rectangle, and finally update our max.
    But wait, what if we had a sequence of increasing heights that were all larger than the lower (i.e. {4,6,7,3}? They would all cant grow any further past the height 3. So we need to keep removing previous values too. Since we want to remove the sequence of last inputted heights, we should use a stack as the implementation for this list. We can keep removing/popping the last heights as long as they are larger than the height we just stopped at.
    Ok so at this point lets review. We have a list of heights:
    Heights = {1,4,2,4,6,7,3}
    We go through the list, add indices to our stack and remove them when we meet a lower height. Which means our stack should look like this {0,2,6} by the end of our passthrough. We end up popping the following indices {1,3,4,5} corresponding to the heights {4,4,6,7}. We can see easily how to calculate the area of these rectangles. Lets take the second height of 4. When we add it to the stack, we add its index of 3. When we start popping off values, we reached index 6 with height 3. By merely multiplying the height of 4 by the difference in our stopping index (6) and our start index of (3) we get the max area of that rectangle (i.e. 12).
    But now our final stack still has rectangles and they can keep going till the end of the list. Our stack is {0,2,6} corresponding to heights {1,2,3}. How do we calculate their area? If we visualize the heights, then intuitively we can see 1 can go throughout the list so we can merely take the list length and multiply it by 1. But for 2 and 3 we can't bc they cant extend throughout the list. They have different starting points. The height of 2 starts at index 1 and 3 starts at index 3. Both of these start when they meet a height lower than it. One way we can solve this is by merely iterating backwards through the heights from our indices until we find a height lower than each. This would be our stopping point. This would theoretically be amortized O(n) operation since a monotonically increasing heights list {1,2,3,4,5,6} would yield the worst possible final stack of {0,1,2,3,4,5} and we would only iterate once through the list of heights. Ill leave this as an exercise for you to reason through.
    Another way to answer that final question is the way NeetCode did it, which is quite intelligent and relies on you being able to answer one question: how can we utilize the prior work we did so we can know when each of these indices start their rectangles? This is a part of the reasoning process that you'll just have to hope you realize on an interview bc i dont believe this can be taught. To realize how to solve this problem, you simply need to keep doing these types of problems and reason it out yourself. So ill leave this part as an exercise for you, and you can use the video to see the answer.

    • @Arunnn241
      @Arunnn241 4 місяці тому

      Not amortized o(n) in cases of duplicate heights however.

  • @whonayem01
    @whonayem01 2 роки тому

    Thanks NeetCode!

  • @KermitDominicano
    @KermitDominicano 5 місяців тому

    Makes sense, but there's no way I woulda figured this out in an interview without having seen the problem before lol

  • @yakovkemer5062
    @yakovkemer5062 3 роки тому

    Thank you for brilliant explanation

  • @georgejoseph2601
    @georgejoseph2601 2 роки тому +1

    I get it every time I watch it and then I forget it after a few weeks, lmao

  • @dera_ng
    @dera_ng 9 місяців тому +1

    Imagine if your Kryptonite was a leetcode question. Well, ladies and gentlemen, I present to you....

  • @gmhussein
    @gmhussein 6 місяців тому

    I honestly got this entire solution except for the part where you extend the start index back to where it couldve started, couldnt find the efficient way to do it

  • @syafzal273
    @syafzal273 Рік тому

    I finally understood how to solve largest rectangle in histogram after watching this video

  • @Famelhaut
    @Famelhaut Рік тому

    the monotonic stack is genius

  • @yaminireddy3321
    @yaminireddy3321 11 днів тому

    I can't stop mySelf without commenting "No one can explain better than this"

  • @chits006
    @chits006 2 роки тому +2

    Good Video: one suggestion , if we push -INT_MAX extra height to the input , we dont have to bother about elements remaining in stack after the iteration.

    • @ゾカリクゾ
      @ゾカリクゾ Рік тому

      We don't necessarily have the option to add elements to the input, especially if it's a fixed size array (C / Java)

  • @SaisankarGochhayat
    @SaisankarGochhayat 2 роки тому

    So well explained!

  • @soojy
    @soojy Рік тому

    @NeetCode what keyboard & switch are you using? the clacky sound as you type is so satisfying. And thanks for the excellent content!

  • @anybody413
    @anybody413 3 роки тому

    Thanks!! Super helpful!

  • @edwardteach2
    @edwardteach2 3 роки тому

    U a God.
    Never thought about saving the indexes into the stack and then calculating the width by len(heights) or the current index we are on. Very smart.

  • @Goodboybiubiu
    @Goodboybiubiu 2 роки тому

    Amazing explanation!

  • @sapnavats9105
    @sapnavats9105 3 роки тому +3

    Can't we use Kadane's algorithm for this problem? I tried it with Kadane's algorithm and it passes most of the test cases except when the horizontal and vertical area are same. Here's my code:
    class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
    if not heights:
    return 0
    ans=float('-inf')
    heights=[0]+heights
    dim=[0,1] #dimension=[height,length]
    for i in range(1,len(heights)):
    temp1=[heights[i],1] #vertical area considering the current bar only
    temp2=[min(heights[i],dim[0]),dim[1]+1] #horizontal area
    dim=temp1 if temp1[0]*temp1[1]>=temp2[0]*temp2[1] else temp2
    ans=max(dim[0]*dim[1],ans)
    return ans

  • @fastlaner7746
    @fastlaner7746 5 місяців тому

    only missed the id extension trick on pop ... hope that simply gets me a hint from the interviewer it I ever get this asked

  • @christopherconcepcion9000
    @christopherconcepcion9000 Рік тому

    Hey, love your videos.
    Was stuck on this problem and rewrote your solution in ruby and broke down each part to understand it. It failed on test [2,1,2] which was 87/98. Looking through the comments of this video I saw someone suggested appending 0 to heights to prevent traversing the stack and this solution actually can pass [2,1,2]. Video might require a small update, just informing you.

  • @PippyPappyPatterson
    @PippyPappyPatterson Рік тому +1

    Where did Neetcode learn these solutions?

  • @swagatochakraborty6043
    @swagatochakraborty6043 Рік тому

    Intuition -
    • If current item is lesser than previous => pop the previous item
    • Maintain a stack with 2 tuple => [index, height]

  • @BBRR442
    @BBRR442 7 місяців тому

    Playing the end at 0.5x while still trying to understand it and he's sounds drunk and saying " this is the most intuitive solution at least from my perspective " loll