Search code examples
pythontreestacktraversalindexoutofrangeexception

IndexError: , How can I check if the last element in the list is null in this scenario without defining a method?


This is a leet code problem so there isn't a tree defined. But here's the TreeNode class definition: (not applicable for my question but here it is anyway):

Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
    self.val = val
    self.left = left
    self.right = right

So, this is the what I did which failed because the list could not be accessed when it was empty. The problem arises on the line indicated with ###.

class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
    stack=[]
    output=[]
    node = root
    while True:
        if node:
            if (node.right != None):
                stack.append(node.right)
            stack.append(node)
            node=node.left
        elif stack:
            check=stack.pop()
            if (check.right != None) & (check.right == stack[-1]):     ###
                node=stack.pop()
                stack.append(check)
            else:
                output.append(check.val)
                node=None
        else:
            break
    return output

Error:

IndexError: list index out of range
if (check.right != None) & (check.right == stack[-1]):
Line 27 in postorderTraversal (Solution.py)
ret = Solution().postorderTraversal(param_1)
Line 57 in _driver (Solution.py)
_driver()
Line 68 in <module> (Solution.py)

Thus, I added a method to perform the check for stack[-1] to avoid the out of range error, on the line indicated with #.

def check_stack(stack):
if stack:
    return stack[-1]
else:
    return None

class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
    stack=[]
    output=[]
    node = root
    while True:
        if node:
            if (node.right != None):
                stack.append(node.right)
            stack.append(node)
            node=node.left
        elif stack:
            check=stack.pop()
            if (check.right != None) & (check.right == check_stack(stack)): #
                node=stack.pop()
                stack.append(check)
            else:
                output.append(check.val)
                node=None
        else:
            break
    return output

Is there a simpler way(without creating a new method & less lines of code) to perform a stack[-1] check without affecting the order of the other conditional statements in this case ?


Solution

  • You can avoid the check_stack function by using slicing to get the last element of the stack instead of accessing specific index.

    In this case, if there is no elements in the stack, you will get empty list instead of None.

    For example:

    stack = [1,2]
    stack[-1:] # 2
    
    stack = []
    stack[-1:] # []