简体   繁体   中英

LeetCode expects null instead of None. How to do this in python?

I'm currently working on LeetCode problem 108. Convert Sorted Array to Binary Search Tree :

Given an integer array nums where the elements are sorted in ascending order , convert it to a height-balanced binary search tree .

A height-balanced binary tree is a binary tree in which the depth of the two subtrees of every node never differs by more than one.

My code seems to be working fine but I don't know how to display the value null instead of None in my list. I need to print the BST in level order traversal. I'm looking for advice, hints or suggestions.

Input:

[-10,-3,0,5,9]

My current output:

[0, -3, 9, -10, None, 5, None]

Accepted output:

[0,-3,9,-10,null,5]

Here is my code:

from queue import Queue
from typing import Optional

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def sortedArrayToBST(nums: [int]) -> Optional[TreeNode]:
    nbNodes = len(nums)

    if nbNodes == 1:
        root = TreeNode()
        root.val = nums[0]
        return root
    elif nbNodes == 0:
        root = TreeNode()
        root.val = None
        return root

    middle = int(nbNodes / 2)
    root = TreeNode()
    root.val = nums[middle]
    leftList = []
    rightList = []
    j = middle + 1

    for i in range(middle):
        leftList.append(nums[i])

        if j != nbNodes:
            rightList.append(nums[j])
        j += 1

    root.left = sortedArrayToBST(leftList)
    root.right = sortedArrayToBST(rightList)
    return root

def levelorder(root):
    if root==None:
        return
    Q=Queue()
    Q.put(root)
    level_order_list = []
    while(not Q.empty()):
        node=Q.get()
        if node==None:
            continue
        level_order_list.append(node.val)
        Q.put(node.left)
        Q.put(node.right)
    print(level_order_list)

if __name__ == "__main__":
    container = [-10,-3,0,5,9]
    levelorder(sortedArrayToBST(container))

This is kind of a weird requirement that has nothing to do with the apparent main point of the problem and I suspect it's a result of the description being copied over from one that's aimed at another language (like Javascript, which uses null instead of None ).

You can, however, format your list however you like when you print it; here's an example where we print a list by joining each item with "," (instead of the default ", " ) and replace None with "null" :

>>> my_list = [0, -3, 9, -10, None, 5, None]
>>> print("[" + ",".join("null" if i is None else str(i) for i in my_list) + "]")
[0,-3,9,-10,null,5,null]

Since JSON renders None as null , another option would be to dump the list to JSON and remove the " " characters:

>>> import json
>>> print(json.dumps(my_list).replace(' ', ''))
[0,-3,9,-10,null,5,null]

The problem is not related to null or None . LeetCode is a platform for taking code challenges in many different languages and they use JSON style to describe input/output, and in JSON notation None translates to null .

Not to worry about that . However, when you look at your output, there is a trailing None that should not be there. That means that you returned a BST that has a node with a None value. This should not happen.

The code that creates this None valued node is easy to identify... it is here:

    elif nbNodes == 0:
        root = TreeNode()
        root.val = None
        return root
        return

When you think of it, this cannot be right: the number of nodes to generate ( nbNodes ) is 0, yet your code creates 1 node -- and that is one too many! In this case you should just return None to indicate that the parent node has no child here.

So replace with:

    elif nbNodes == 0:
        return

This fixes the issue you mentioned, and your code will now pass all tests on LeetCode.

Here is your code with the above corrections and with the self parameter restored (which you had removed to run it without the need to create a class instance):

class Solution:
    def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
        nbNodes = len(nums)

        if nbNodes == 1:
            root = TreeNode()
            root.val = nums[0]
            return root
        elif nbNodes == 0:
            return

        middle = int(nbNodes / 2)
        root = TreeNode()
        root.val = nums[middle]
        leftList = []
        rightList = []
        j = middle + 1

        for i in range(middle):
            leftList.append(nums[i])

            if j != nbNodes:
                rightList.append(nums[j])
            j += 1

        root.left = self.sortedArrayToBST(leftList)
        root.right = self.sortedArrayToBST(rightList)
        return root

Other improvements

Unrelated to your question, but there are several things you can optimise:

  • Try to avoid creating new lists ( leftList , rightList ): copying values into them takes time and space. Instead use start/end indices in the original list to denote which sublist is currently processed.

  • Make use of the additional arguments you can pass to the TreeNode constructor. That way you don't have to assign to attributes after the constructor has run.

  • Use the integer division operator instead of the floating point division operator.

  • One of the two base cases is not needed as it would be dealt with correctly by the next recursive calls.

Here is a spoiler solution that applies those remarks:

class Solution: def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]: def recur(start: int, end: int): if start < end: middle = (start + end) // 2 return TreeNode(nums[middle], recur(start, middle), recur(middle + 1, end)) return recur(0, len(nums))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM