I m having a hard time calculating time complexity for this function since I used sum() for the first time, so sum takes a list sum(list[])
and returns the total sum of that list and has a time complexity of O(n)
. Also if it's greater than n^2 is there anything I can do to make it n^2 or lower.
def maxsubarray (inputlst):
size = len(inputlst)
minlist = [inputlst[0]]
globallist = [inputlst[0]]
for i in range(1,size):
minlist.insert(i,inputlst[i])
if (sum(minlist) > inputlst[i]):
if sum(minlist) > sum(globallist):
globallist = list(minlist)
if (sum(minlist) < inputlst[i]):
minlist = [inputlst[i]]
if sum(minlist) > sum(globallist):
globallist = list(minlist)
CodePudding user response:
Let's examine your code step by step to find the time complexity.
class Solution(object):
def maxSubArray(self, inputlst):
size = len(inputlst) # O(1)
minlist = [inputlst[0]] # O(1)
globallist = [inputlst[0]] # O(1)
for i in range(1,size): # O(len(inputlst)) = O(n)
minlist.insert(i,inputlst[i]) # O(n) --> insert time complexity
if (sum(minlist) > inputlst[i]): # O(n) --> sum
if sum(minlist) > sum(globallist): # O(n) --> sum
globallist = list(minlist) # O(n)
if (sum(minlist) < inputlst[i]): # O(n)
minlist = [inputlst[i]]
if sum(minlist) > sum(globallist): # O(n)
globallist = list(minlist) # O(n)
return sum(globallist)
In average, sum()
functions takes O(n)
time complexity since it traverses all the list. insert(index, element)
also takes O(n)
time complexity, because inserting to a specific index may require remaining elements to be shifted to the right. Creating a list using list()
takes O(n)
time complexity, since again you have to traverse through the list.
In overall, your code performs operations that require O(n)
time complexity within a for loop, that also requires O(n)
time complexity. Therefore time complexity of your solution will be O(n^2)
. It seems to be an inefficient solution for max subarray problem. Check the more simple, short solution below:
class Solution:
def maxSubArray(self, nums):
prev = nums[0]
max_ = prev
for i in range(1, len(nums)):
prev = max(prev nums[i], nums[i])
if(max_ < prev): max_ = prev
return max_
Logic is simple: You should either add the current item to your subarray, or not in order to find the maximum subarray. It's called Kadane's Algorithm.
Since you just iterate through the list once, time complexity is O(n)
. In addition, you don't create unnecessary lists, two variables (one for previous number, other for maximum sum) will be enough.
In addition to the sum, if you want to return the maximum subarray, you can hold two indices corresponding to starting and ending points.
class Solution:
def maxSubArray(self, nums):
prev = nums[0]
max_ = prev
start = 0
end = 0
start_max = 0
end_max = 0
for i in range(1, len(nums)):
if(prev nums[i] >= nums[i]):
prev = nums[i]
end = i
else:
prev = nums[i]
start = i
end = i
if(max_ < prev):
max_ = prev
start_max = start
end_max = end
print(nums[start_max:end_max 1])
return max_
Output for nums = [-2,1,-3,4,-1,2,1,-5,4]
:
[4,-1,2,1]