简体   繁体   中英

How do I compute the time and the space complexity of a recursive function?

I am currently practicing an interview question. The question is:

Given an integer array with no duplicates. A maximum tree building on this array is defined as follow: 
    1. The root is the maximum number in the array. 
    2. The left subtree is the maximum tree constructed from left part subarray divided by the maximum number.
    3. The right subtree is the maximum tree constructed from right part subarray divided by the maximum number.

Construct the maximum tree by the given array and output the root node of this tree. 

My solution to this question is:

def constructMaximumBinaryTree(nums):
        """
        :type nums: List[int]
        :rtype: TreeNode
        """
        if nums:
            maxIdx = nums.index(max(nums))
            root = TreeNode(nums[maxIdx])
            left = constructMaximumBinaryTree(nums[:maxIdx])
            right = constructMaximumBinaryTree(nums[maxIdx + 1:])
            root.left = left
            root.right = right
            return root

I get how it works, but I am not sure how to compute the time and space complexity. If I try to draw the solution out, the input array gets split into two, for each node until it gets empty. So, I guessed it would be something like O(log n) , but I am not sure about the exact reasoning. Same with the space complexity. Any tips?

No, it's not necessarily O(n log n) .

First, consider the recursion process itself: what is the worst-case (default interpretation of "complexity) position of the splitting decision? If the given array is sorted, then the maximum element is always at the end, and your recursion degenerates into a process of removing one element on each iteration.

Second, consider the complexity of one pass through the function, recursion aside. What is the complexity of each operation in your sequence?

  • find max of list
  • find element in list
  • construct node
  • slice list
  • function all
  • slice list
  • function call
  • assignment
  • assignment
  • return root node

Many of those are O(1) operations, but several are O(n) -- where n is the length of the current list, not the original.

This results in a worst-case O(n^2) . Best-case is O(n log n) , as you intuited, given a perfectly balanced tree as input. The average case ... you probably don't need that any more, but it's O(n log n) with less favorable constants.

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