Maximum Subarray Min-Product - Monotonic Increasing Stack - Leetcode 1856 - Python

Поделиться
HTML-код
  • Опубликовано: 9 ноя 2024

Комментарии • 60

  • @NeetCode
    @NeetCode  3 года назад +3

    💡 SIMILAR PROBLEM: ruclips.net/video/zx5Sw9130L0/видео.html

    • @hfeng1995
      @hfeng1995 2 года назад +1

      Leetcode has inflation issue. Used to be hard, now just medium :)

    • @halahmilksheikh
      @halahmilksheikh 2 года назад

      For anyone else wondering what the connection is between this problem and Largest Rectangle in Histogram. In the old problem, another way to think about it is "maximize the product of (the minimum value contained in a contiguous array) and (the length of the array)". We use the mono increasing stack to keep track of longest valid windows associated with each minimum value.
      Max MinProduct is an extension of Histogram so definitely understand Histo first if you're confused about MinProd.

    • @yichenyao5927
      @yichenyao5927 Год назад

      @@hfeng1995 for real! I feel like this is even trickier than the largest rectangle (which is Hard) by creating a prefix array. I got TLE for not creating that while the rest of the code following the exact structure of monotonic stack in largest rectangle (which I previously figured it out on my own)

  • @ziomalZparafii
    @ziomalZparafii Год назад +20

    I've solved dozen of leetcode and watched 3 times more of your solutions but this is the first one that I was unable to understand the problem and then also your explanation. Either it's too confused for me or I need to watch it again on some better day ;)

    • @alexeysubbota
      @alexeysubbota 11 месяцев назад +1

      You are not alone, me too!

    • @Alexander-zt9kz
      @Alexander-zt9kz 8 месяцев назад +1

      Stack problems are literally the hardest pattern on LC, much much harder than DP.

    • @dudeyouhavenoidea
      @dudeyouhavenoidea 7 месяцев назад +1

      I didn't get the explanation at first but I eventually did

    • @picturesqueedits3083
      @picturesqueedits3083 Месяц назад

      watch strivers video largest histogram, he hasn't explained well

  • @halahmilksheikh
    @halahmilksheikh 2 года назад +28

    These monotonic stack problems are more confusing than DP... at least with DP you can reason it out but here the logic is so confusing

    • @danielsun716
      @danielsun716 2 года назад +3

      My question is during the 30 mins interview, how does we decide to use DP or monotonic stack?

    • @tofahub
      @tofahub 2 года назад

      That’s what I came to say

    • @Alexander-zt9kz
      @Alexander-zt9kz 8 месяцев назад +1

      @@danielsun716really DP is for when you have a problem who can be solved by sub problems which are computed multiple times, so you cache them. Stack is used to emulate a callstack, reverse data, undo / check valid operations, or keeping items in monotonic order, either non decreasing or non increasing, sometimes with a twist. Harder monotonic stack questions are extremely difficult imo, much harder than DP or greedy questions.

  • @numberonep5404
    @numberonep5404 2 года назад +11

    This one definitely earned its unofficial "Hard" tag omg xD Crystal clear explanation as usual, thank you!

  • @mahesh_kok
    @mahesh_kok Год назад +1

    For people coming from largest rectangle in histogram
    below code explains the problem
    some modifications help avoid extra loops
    # this is my solution which is exactly the same as largest rectangle in histogram
    def maxSumMinProduct(nums) -> int:
    # add -1 to the end so that we can avoid extra while loop
    # for example when computing the last elemenet in nums
    # which is smallest and hence we will be computing the stack
    nums = nums + [-1]
    res = -1
    stack = []
    # adding 0 to the pre_comp_sum helps in calculating pre sum
    pre_comp_sum = [0]
    pre_comp_sum.extend(pre_comp_sum[-1] + n for n in nums)
    for index, ele in enumerate(nums):
    if stack and ele < stack[-1][1]:
    last_index = -1
    while stack and stack[-1][1] >= ele:
    last_index, last_ele = stack.pop()
    new_res = last_ele * (pre_comp_sum[index] - pre_comp_sum[last_index])
    res = max(res, new_res)
    stack.append((last_index, ele))
    else:
    stack.append((index, ele))
    return res

  • @oswald3042
    @oswald3042 3 года назад +20

    Intuition in one line: Use monotonic increasing stack to get the sorting order of elements without actually sorting the array.

  • @nithinbosej
    @nithinbosej 3 года назад +5

    Could have been better if explained with a bit bigger array like - [3, 1, 6, 4, 5, 2]. So some of the not-so-intuitive scenarios show up.
    But indeed a great explanation!
    Thanks!

  • @brieflyfun
    @brieflyfun Год назад +1

    It seems that having duplicated elements with the same value in stack is not useful. It is save to pop it out and put it back as newStart set to the original index. So change the while line condition stack[-1][1] > n to stack[-1][1] >= n will still work. So the stack would be strictly increasing.

  • @RomanChurganov
    @RomanChurganov Год назад

    In a first place you should show on examples what we should include to sub-array as much numbers as we can to increase Min-Product, unless next number is smaller then smallest of sub-array. So smallest number acts like a baseline of a hill, and traversing with a stack while going down from hill it allows us to just keep track other side of the hill

  • @mosaic34
    @mosaic34 3 года назад +8

    hey neetcode ! whenever i get stuck in a problem i always search you up first , you have an amazing and simple explanation which is always on point.
    i am trying to solve leetcode problem number 321 create maximum number and i couldnt find simple explanation to it anywhere on the internet , i am still stuck .....can you please make your next video solving that problem

    • @NeetCode
      @NeetCode  3 года назад +1

      Thanks, yes I will solve that problem soon!

  • @jdhp3696
    @jdhp3696 2 года назад

    Thank you for the explanation. The last part of popping of the remaining stack is something that I did not think about.

  • @DavidDLee
    @DavidDLee Год назад +6

    Unlike most of your videos, the explanation here is not clear.

  • @erdemtuna_me
    @erdemtuna_me 2 года назад +1

    IMHO, 1-indexing prefix array usage creates a big difference (from coding perspective) in this problem in compared to 0-indexing...

  • @zhangxinhello
    @zhangxinhello Год назад

    Actually, you should point out: the key to solve this problem is find the firstLeftMinValue and RightMinValue for index i, that's why we use the stack

  • @sarveshchavan4391
    @sarveshchavan4391 3 года назад +1

    Really appreciate your efforts for explaining !
    Need more of such explanation for Hard problems

  • @shrimpo6416
    @shrimpo6416 3 года назад

    This question is very complicated, but perfect explanation and I finally understand it!

  • @SRIDHARANBEE-jy9li
    @SRIDHARANBEE-jy9li 3 года назад +2

    Hii i just wanna thank you bro its literally amazing ❤️

  • @abhisheksaraf2616
    @abhisheksaraf2616 7 месяцев назад

    this problem is similar to Largest Rectangle in Histogram there we are multiplying by index, here sum within range

  • @quentinau7507
    @quentinau7507 2 года назад

    Watched it 5 times, finally understand the algorithm.

  • @s_rox5042
    @s_rox5042 7 месяцев назад

    sliding window does not work here since we cannot decide to go left or right if the num[let_pos] == nums[right_pos]

  • @SaurabhJeena-sh4gh
    @SaurabhJeena-sh4gh 8 дней назад

    easiest question of leetcode
    class Solution {
    public int maxSumMinProduct(int[] nums) {
    long max=Long.MIN_VALUE;
    Stack stack=new Stack();
    long [] prefixSum=new long [nums.length];
    int [] ns=new int [nums.length];
    int [] ps=new int [nums.length];
    long sum=0;
    for(int i=0;i=0;i--){
    while(!stack.isEmpty()&&nums[stack.peek()]>=nums[i]){
    stack.pop();
    }
    if(stack.isEmpty()){
    ns[i]=nums.length;
    }
    else{
    ns[i]=stack.peek();
    }
    stack.push(i);
    }
    stack.clear();
    for(int i=0;inums[i]){
    stack.pop();
    }
    if(stack.isEmpty()){
    ps[i]=-1;
    }
    else{
    ps[i]=stack.peek();
    }
    stack.push(i);
    }
    for(int i=0;i

  • @pranee31
    @pranee31 Год назад

    Neatly done

  • @sachinpaul2111
    @sachinpaul2111 Год назад

    This is the exact same pattern as that histogram rectangle problem

  • @VerzapierZyGaming
    @VerzapierZyGaming 3 года назад +1

    hey, what happens if the array is 1,2,3,1
    we would still get a 2, that starts from idx 1 in the stack right? but the minimum is 1 at the idx 3?

    • @NeetCode
      @NeetCode  3 года назад

      Before adding the 1, we would have to pop 3 and 2 from the stack. Once we pop those, we would compute if either 2 or 3 leads us to the max result.

    • @VerzapierZyGaming
      @VerzapierZyGaming 3 года назад +1

      @@NeetCode oh so we keep poping if its smaller than the peak of stack, got it thats where i had been mssinh
      great work!

  • @haoyuwang3243
    @haoyuwang3243 2 года назад

    I feel sad coz I still don't quite get it tho this is the clearest explanation on the planet of earth..This damn question..

  • @avanishgvyas1992
    @avanishgvyas1992 2 месяца назад

    One feedback for the solution videos, not just this one but in general for all video solutions:
    It would help tremendously if you could show animation of the running algorithm to explain how it works.

  • @Sulerhy
    @Sulerhy 4 месяца назад

    So confusing. Anyways thank you for your explain, it helps me step by step

  • @SunilJamkatelTrue
    @SunilJamkatelTrue 2 года назад

    Isn't this a O(n^2) solution with the while nested loop?

    • @vinayakgandhi5690
      @vinayakgandhi5690 2 года назад

      It is O(N) Amortized. It looks like O(N^2) as we run a while loop in each iteration, but the total run time of the while loop over all n iteration is only N because we pop an element at most once.

    • @vishnups
      @vishnups Год назад +1

      Each element will be added to the stack exactly once. You can think of it as iterating over the input list once and over the elements of the stack once, making it two linear passes.

  • @liftandshiftdev3222
    @liftandshiftdev3222 Год назад

    i solved it using segment tree

  • @amannegi8256
    @amannegi8256 3 года назад

    amazing mate!

  • @pramod3293
    @pramod3293 3 года назад

    What if the numbers can be negative?

  • @jianhaoluo9491
    @jianhaoluo9491 3 года назад

    Solid!

  • @yassineacherkouk
    @yassineacherkouk Год назад

    this is not something that you can come up with alone.

  • @piyushyadav9006
    @piyushyadav9006 3 года назад +1

    I solved this using recursion ..
    Basically first I search for the min index and then I divided given array into two subarray to check whether they could give me the max without the min element.
    But in this method I've to sum all the subarrays again and again and thus time complexity is similar to that of QuickSort which is O(nlogn)
    Could there be any optimisation done.

    • @chaoluncai4300
      @chaoluncai4300 2 года назад

      Your way is actually Divide&Conquer, gj! could use a prefix sum to conquer the repetitive sum, but again has to compute the min of subarrays again and again... btw for breakin ties do you just skip all the candidates that's equals to the current minimum candidate?

  • @naveen3192
    @naveen3192 2 года назад

    I can understand the steps in the problem and how it's solved but I don't quite get how these steps lead to generating all sub arrays. I don't get that connection. Can somebody help?

    • @sodiqyusuff8019
      @sodiqyusuff8019 2 года назад

      Looks like you haven't really understood the steps. So basically, you don't need to generate ALL sub arrays.
      Since you're multiplying all subarrays by the MIN val in the sub, that automatically means some sub arrays will be useless.
      Consider the array [1,2,5,1,0], and consider the element 2 at index 1.
      2 belongs to sub arrays like [2,5], [2,5,1] and [2,5,1,0] but only [2,5] is useful to 2 because that's the only one for which 2 is the minimum. You will never multiply 2 by the sum of the rest so it's pointless to generate them.
      The popping of the stack when you encounter a smaller number helps to ensure this.
      I hope my explanation helps a little.

    • @naveen3192
      @naveen3192 2 года назад

      @@sodiqyusuff8019 Hey, thanks for that. Rewatching the video now. I get why we don't need all sub-arrays. Thanks

  • @jonaskhanwald566
    @jonaskhanwald566 3 года назад +1

    Mission successfully faile

  • @jonaskhanwald566
    @jonaskhanwald566 3 года назад

    Need Combination sum IV - #377

  • @Philgob
    @Philgob 2 месяца назад

    this ain't no fucking medium

  • @shadowsw8020
    @shadowsw8020 3 месяца назад

    Badly explained