Evaluate Reverse Polish Notation - Leetcode 150 - Python

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

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

  • @NeetCode
    @NeetCode  2 года назад +8

    Java Code (by a viewer): github.com/ndesai15/coding-java/blob/master/src/com/coding/patterns/stacks/ReversePolishNotation.java

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

      The division operator requires the numerator to be converted to float in leetcode for the solution to be accepted, which is kind of weird

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

      @@TheAdityabhandari Did you solve in Java? Maybe bc Java requires explicit typing and float division is needed for possible decimals? My JS & Py3 solutions were just accepted a few mins ago and no floats were needed.

  • @saisrinivas9489
    @saisrinivas9489 2 года назад +147

    Thank you so much for your videos, I got a job offer from Microsoft, without your videos this is not possible.

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

      Hi bro can we connect by any chance on linkedin, if so can you plz drop your linkedin

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

      Hi,
      If you don't mind, can we connect on LinkedIn?

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

      How did you get the interview in the first place?

    • @dumbfailurekms
      @dumbfailurekms Год назад +5

      @@nokigaming6651 well the market was pretty shit 5 months ago and it's getting better but if any new grad reads this in the future:
      If u want to get an interview opportunity during a bad market u will probably need 2-3 personal projects that are more robust than a calculator or a pong game

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

      @@dumbfailurekms Have you got a job recently as well?

  • @harika28
    @harika28 2 года назад +7

    I admire how you breakdown a problem into smaller ones and make it look simple!

  • @amandaflood
    @amandaflood 2 года назад +96

    Int divisions work differently in Python and Python3 - if you have a failing case try replacing int(b/a) with int(float(b)/ a)

    • @latinochild3131
      @latinochild3131 2 года назад +2

      can you explain why this works? i just want to have a better understanding of it

    • @amandaflood
      @amandaflood 2 года назад +8

      @@latinochild3131 in Python, using / with two integers gives an integer result - eg 4/3 = 1. If you want to get a float answer you have to specify that your input is a float.
      That could cause some problems if a user wasn't aware of it! Python 3 a gives a more expected result - 1.3333.

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

      Your such a life saver thanks a lot mate

    • @nnam_nnam2391
      @nnam_nnam2391 2 года назад +6

      Thank you! I was failing the third case on LC but your recommendation fixed my issue.

    • @ThePacemaker45
      @ThePacemaker45 Год назад +7

      almost wanted to smash my laptop till I saw this. Thank you.

  • @tahirraza2590
    @tahirraza2590 2 года назад +2

    thanks a lot! the explanation before the code is always on point 👍
    I tried to do it a bit differently
    class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
    stack = []
    for t in tokens:
    if t in ['/', '-', '+', '*']:
    rOp = stack.pop()
    lOp = stack.pop()
    expression = lOp + t + rOp
    stack.append(str(int(eval(expression))))
    continue
    stack.append(t)
    return stack.pop()

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

      wouldn't this result in more overall comparisons?

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

      Using eval is quite interesting. I rarely use it myself.

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

      the use of 'eval' is not secure in the real world. if the expression can be controlled by a user facing the application, it can be crafted into a malicious input and will be run as a Python expression.

    • @diasutsman
      @diasutsman 11 месяцев назад

      ​@@deepb5204then sanitize your input

  • @hwang1607
    @hwang1607 Год назад +11

    Note that using a//b in python is not the same as using int(a/b). Double slash is floor division which will also round down with negative numbers. int(a/b) will round toward zero

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

      That was pretty useful. Thanks for explaining it .

    • @RM-xr8lq
      @RM-xr8lq 11 месяцев назад

      and round() in python rounds to nearest even number
      round(5.5) -> 6
      round(4.5) -> 4

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

    The explanation is so good I understood the whole algorithm just by watching till 2:59😂

  • @nucleartide
    @nucleartide Год назад +4

    Another solution would be to define a recursive function `evaluate(stack)` that calls itself when another operator is encountered. You'd effectively still be using the stack data structure, only that your stack is the call stack's stack frames!

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

      That was the solution I came up with on my own. I thought it was clever but it also looks way more complex compared to this solution. On the other hand my memory came through in the top 98.5% so it's clearly a good approach on that front lol

  • @The6thProgrammer
    @The6thProgrammer Год назад +2

    I love your videos. Minor issue was the explanation of popping the stack to assign values to a and b. You say that we want to “subtract the one that was popped second from the one that was popped first”. I believe you just mixed up the words, but in case others got slightly confused, b actually gets the value that is popped first and a gets the value popped second. This is clear if you take an input example [2, 1, -], which you actually discussed at 4:30 in the video, this would be 2 - 1. Therefore you would want to subtract the one popped first from the one popped second. And in python, because tuple unpacking is done right to left, b did indeed get the first popped value, so your solution is still valid despite mixing up the words.

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

    how did you add right bracket using keyboard shortcut at timestamp 7:28 ?

  • @evannoronha3261
    @evannoronha3261 2 года назад +46

    This could have been a good opportunity to introduce lambda syntax:
    ```
    class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
    operatorMap = {
    "+": lambda l,r: l + r,
    "*": lambda l,r: l * r,
    "-": lambda l,r: l - r,
    "/": lambda l,r: int(l / r),
    }
    stack = []
    for token in tokens:
    if token in operatorMap:
    right = stack.pop()
    left = stack.pop()
    token = operatorMap[token](left, right)
    stack.append(int(token))
    return stack.pop()
    ```

    • @NeetCode
      @NeetCode  2 года назад +5

      Clean!

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

      Thank you! I like this solution better :) One suggestion: for integer division in python you can use a // b instead of int(a / b)

    • @evannoronha3261
      @evannoronha3261 2 года назад +12

      @@vasudhajha9115 Almost! The spec includes this note: "Note that division between two integers should truncate toward zero." a//b will always truncate downwards so it does not work for negative operands.

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

      @@evannoronha3261 Oh nice. I learned two new things from your answers :) Thanks!

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

      can you please provide leetcode lists of 150 neetcode Qs

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

    should the space complexity be O(1) since at any point in program execution we are going to store at most 2 values ?

  • @whimsicalkins5585
    @whimsicalkins5585 5 месяцев назад

    I came with my own solution for this question (felt very proud). But my solution is not even half efficient as yours. Thanks for sharing.

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

    No need to do the a, b to do a swap for subtraction. Worst case every operator is “-“ and you made new a,b objects each time in the for loop.
    Instead notice that “b - a” is equal to “-a + b”.
    Thus you can write it in one line with no a and b needed:
    stack.append(-stack.pop()+stack.pop())
    Likewise, we can assume this is a valid RPN per the problem description, which your solution correctly assumes. Thus we can avoid the temp a,b for division as well using the 0 and 1 index for denominator and numerator respectively.
    Thanks for the videos. Only trying to help simplify things.

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

    I have not tried this one, but if the statement is always valid, would it work if we don’t use stack but just 2 number var?
    First 2 tokens always assign to 2 int var.
    Next is operator, apply then assign to int1.
    Next is number, assign to int2.
    Repeat the above 2 for every subsequent operator & number.
    Return int1 value.

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

      "1 1 1 1 + + +" this is a valid statement so unless you backtrack in the input I dont think you can solve it with O(1) space

  • @xiuzhenyang8047
    @xiuzhenyang8047 Год назад +2

    Can anyone explain why I cannot use b//a to substitute int(b/a) ? I still got 0 from b//a but cannot pass below test case.
    Input
    tokens =
    ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]
    Output
    12
    Expected
    22

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

      for negative operations, // will round downwards (i.e -1.2 will round to -2) while the spec says it should round closest to zero (so it should round to -1 in this case). You use int(b/a) for that.

    • @BetterBirdMan
      @BetterBirdMan 9 месяцев назад

      i believe truncation or something regarding division changed from python to python3. try your solution with python3 and not just python on leetcode

  • @user-zx2gp2hh7m
    @user-zx2gp2hh7m 2 года назад +1

    what's the difference in int(a/b) and a//b in python3? I used the latter one and it was wrong. Searched on stackoverflow but still confused

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

      a//b rounds the float number to the floor value. For example 22//7 is 3.14 so it will be rounded of to 3

  • @OwenWu-f9t
    @OwenWu-f9t Год назад

    so we know that the array must have at least 2 integers before a division or plus or minus or times operator?

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

    thank you so much, your explanation that very easy to understand this problem

  • @mire5234
    @mire5234 Год назад +2

    I felt the problem is very hard until I saw this video.

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

    Why you still can + - * / after you pop the number? Isn't a number vanish?

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

    Thank you. This was really helpful

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

    Curious as to how this works since the input values in the array are strings and there's no sort of type casting happening. ("2" * "2") for example should fail.

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

      The casting is being done in the else block of the code -- stack.append(int(c))

  • @jonathanst.hilaire5025
    @jonathanst.hilaire5025 2 года назад +3

    When I copy your code from git hub I'm getting a failing case on Leetcode, just a heads up.

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

      Hmm, I tried it and it's working for me now. Maybe there was an extra indent when you pasted

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

      Same here

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

      @@loraigwe9285 Are you trying to Java code or Python?

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

      @NeetCode python

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

      it passes in python3 but not in python2. i don't know why though.

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

    at 5:13, you are adding from the right side and popping from the left, that has became a queue, and not a stack,

  • @poptart007-b2r
    @poptart007-b2r 2 года назад

    Delightful explanation as usual! :)

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

    I solved this problem by making a dictionary with the values being the operators and checking to see if c = an operation in the dictionary. If it does pop right pop left then left (insert operant) right =

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

    I think you need to strongly emphasize the correct way to approach the division and what it means to round towards zero. I'm assuming many people in the comments are having trouble between floor division and truncating. I think talking about this conceptually would help many of us especially if coding it up in a different language

  • @RM-xr8lq
    @RM-xr8lq 11 месяцев назад

    this problem could be renamed: implement basic calculator
    you will find that in trying to implement a basic calculator to parse a string, it is much easier to do it with prefix notation isntead of infix ( + a b vs. a + b). at that point you are doing reverse polish notation as the problem specifies...

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

    I like to avoid the "elif" statements by storing the operators in a dict (the deque can ofc just be a list):
    d = {"+": operator.add, "-": operator.sub, "/": operator.truediv, "*": operator.mul}
    l = ["+", "-", "*", "/"]
    def reverse_polish_notation(tokens):
    s = deque()
    for token in tokens:
    if token not in l:
    s.append(int(token))
    else:
    second, first = s.pop(), s.pop()
    s.append(int(d[token](first, second)))
    return s.pop()

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

    If I am using javascript what can i do when declaring [a, b] ? I try to do const [a, b] and const [c, d] so avoid having the same variable declaring twice. Its there a better way to do this? Thanks a lot for the video as always! learning so much!

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

      If you are declaring the variables inside different if statements then it's fine, variable [a, b] will only be scoped for that particular code block

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

    For some reason solution was not working, it works if you convert b in the / case to a float using float(b)/a.

    • @Daniel-fn6tj
      @Daniel-fn6tj 2 года назад

      Was running into the same issue. Do u know why this happens?

  • @Nick-uo2bi
    @Nick-uo2bi 2 года назад +8

    Please introduce DSA and DP playlist so we can get all the concepts as well before practicing question.

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

    you didnt explain the second example and third one?? they are quite complex and they also needs to be decoded.

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

    please do Next Permutation, I think this question bothers lots of us!

  • @Ken-rj5xi
    @Ken-rj5xi 2 года назад

    Can someone tell me that why are we subtracting number that was popped 2nd with the number that was popped first? How do we know that the 2nd popped number is the biggest of them.

    • @dusvn1484
      @dusvn1484 6 месяцев назад

      I know it's long time when you commented this but I will explain.This is becouse we have something like 5 4 - and we want to do 5-4 becouse this is representation for reverse polish notation.We have 2 numbers and this 2 numbers is in relation with this first sign.
      When we push on stack that means we go over array and push it like first me push 5 [5] ,after we push 4 and this is how look like list [5,4] and when we do .pop() this first number will be 4,second pop is 5 and now you can figure out.

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

    Does not work in Python3. It keeps giving me ValError.

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

    for anyone debugging, you have to do int(b / a) because b // a will not work!

    • @souperman6406
      @souperman6406 10 месяцев назад

      spent like 15 mins debugging this error loll

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

    awesome explanation!

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

    Would this be doable in O(n) instead of O(2n)? Yes I know technically they're the same but practically they aren't. The way I have it figured in my head is that you could store the first digit of the array. Then every two elements after would be a digit and an operator. This would let you iterate through the array only once.
    My other instinct to solving it would have been with leading/trailing pointer style. Trailing pointer to keep track of the numbers, leading pointer to find the operators

    • @ChrisCox-wv7oo
      @ChrisCox-wv7oo 2 года назад +2

      They gave an incomplete example of RPN. There is no guarantee of alternating digits and symbols.
      123+- = 1 - (2 + 3)

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

      why are you talking about O(2n), the array is iterated only once, so it is O(n) :/

    • @ChrisCox-wv7oo
      @ChrisCox-wv7oo 2 года назад

      @@frankl1 to be fair, NeetCode said it ran in O(2n)...

    • @chrischika7026
      @chrischika7026 5 месяцев назад

      @@ChrisCox-wv7oo its between 1n and 2n

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

    We can do it in place and return that last index value as result

  • @hamza-chaudhry
    @hamza-chaudhry 4 месяца назад

    0:55 Yeah I think it does

  • @Charmask_creation
    @Charmask_creation 11 дней назад

    best stack problem everrr

  • @BBRR442
    @BBRR442 8 месяцев назад +3

    Doesnt work.. misses on the last test case

  • @nguyen-dev
    @nguyen-dev 2 года назад

    Not code yet, but my solution before watch this video is to use pointers to have time complexity O(n) but space complexity is O(1).

    • @nguyen-dev
      @nguyen-dev 2 года назад +1

      I am wrong, using pointers will still need O(n) space if there are multiple complex expressions, which become operands of outer operator. Therefore, using stack is the best solution.

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

    How can you pop if the stack is empty?

    • @dusvn1484
      @dusvn1484 6 месяцев назад

      Stack never be empty becouse they clear this edge case(and other) every input in problem is good.
      Everything what you need to do is to do this callculation on polish way :)

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

    thank you sir

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

    Wait but you don't need a stack, you can just make an inOrder traversal by popping the values from the end of tokens

  • @s8x.
    @s8x. Год назад +2

    the code doesn't pass one test case

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

    Thanks

  • @loncharnettcr7044
    @loncharnettcr7044 9 месяцев назад

    thanks goat

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

    for subtracting can't we multiply -1 to the result in the default order?

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

    Copying this comment from Leetcode for anyone confused about int(b / a) and why (b // a) doesn't work. Credit to user A_R_K for the comment.
    "// is the floor function. / is the divide function.
    By definition floor function would round the number to the smallest integer lesser than or equal to it. Hence, -17//6 is -3. This is because -3 is the smallest integrer lesser than or equal to -2.833..
    One should ideally use int() to truncate the decimals."

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

    Genius!

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

    class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
    stack = []
    for t in tokens:
    if t not in '+-*/':
    stack.append(int(t))
    else:
    v2, v1 = stack.pop(), stack.pop()
    if t == "+":
    stack.append(v1 + v2)
    elif t == '-':
    stack.append(v1 - v2)
    elif t == '*':
    stack.append(v1 * v2)
    else:
    stack.append(int(v1 / v2))
    return stack[-1]

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

    Seems like a queue is needed here instead of a stack

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

    If the stack will always have at most 2 elements, the the space complexity is technically O(1) no matter how large the input array, it will always be constant. Right?

    • @chrischika7026
      @chrischika7026 5 месяцев назад +1

      it can have more than two elements

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

    i have no clue why I thought RPN was so much harder than it really is

  • @Dhruvbala
    @Dhruvbala 9 месяцев назад

    Thanks. A more terse way of writing this :
    '
    def evalRPN(self, tokens: List[str]) -> int:
    ops = {
    '+' : (lambda a,b : a+b),
    '-' : (lambda a,b : a-b),
    '*' : (lambda a,b : a*b),
    '/' : (lambda a,b : int(float(a)/b))
    }
    stack = []
    for c in tokens:
    if c in ops:
    b, a = int(stack.pop()), int(stack.pop())
    stack.append(ops[c](a,b))
    else:
    stack.append(int(c))
    return stack.pop()

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

    This really helped, the problem looked unsolvable at first to be honest 😊

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

    GOAT

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

    Will you post code in C or Java also🥺 either in video or atleast in description/website 🥺

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

    Dude, you didn't try 847?

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

    I found a way to improve the time complexity by using the operator library.The logic is still the same but cut down the runtime by 50%
    import operator
    class Solution(object):
    def evalRPN(self, tokens):
    """
    :type tokens: List[str]
    :rtype: int
    """
    stack = []
    op = {
    "+": operator.add,
    "-": operator.sub,
    "*": operator.mul,
    "/": operator.truediv
    }
    for x in tokens:
    if x in op:
    a,b = stack.pop(), stack.pop()
    stack.append(int(op[x](b,a)))
    else:
    stack.append(int(x))
    print(stack)
    return stack[0]

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

    Is there any channel who do like this in java or C

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

      I have implemented the same problem in Java. But youtube is not allowing me to add a link to implementation of it in comment so I have requested @neetcode, to post a link of my java implementation to here as well.

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

      @@neeldesai108 thank you!❤️

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

    delicious

  • @veedhiabhhirram4121
    @veedhiabhhirram4121 5 месяцев назад

    us

  • @adampajda3204
    @adampajda3204 5 месяцев назад

    Polska gUrom! :D