I have written a python program to Calculate the average word length and return the average word length.
def stringlength(A: List[str]) -> int:
average = sum(len(word) for word in A)/len(A)
return average
test_list = ['gfg', 'is', 'best', 'for', 'geeks']
print(stringlength(test_list))
Answer: 3.4
I am new to calculating time and space complexitities.
I am assuming the time complexity of this python program would be O(N) where N is the length of the list since it uses builtin function like len and for loop
and space complexity would be O(N) since len() in for loop would return a list of lengths.
Can anyone please clarify if my assumption is correct
You are right. Time complexity would be O(n) where n is length of your list.
This is because you are going over every element in your list.
Related
Problem: Given a string s, find the length of the longest substring
without repeating characters.
Example: Input: s = "abcabcbb" Output: 3 Explanation: The answer is
"abc", with the length of 3.
My solution:
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
seen = set()
l = r = curr_len = max_len = 0
n = len(s)
while l < n:
if r < n and s[r] not in seen:
seen.add(s[r])
curr_len += 1
max_len = max(curr_len, max_len)
r += 1
else:
l += 1
r = l
curr_len = 0
seen.clear()
return max_len
I know this is not an efficient solution, but I am having trouble figuring out its time complexity.
I visit every character in the string but, for each one of them, the window expands until it finds a repeated char. So every char ends up being visited multiple times, but not sure if enough times to justify an O(n2) time complexity and, obviously, it's way worse than O(n).
You could claim the algorithm to be O(n) if you know the size of the character set your input can be composed of, because the length your window can expand is limited by the number of different characters you could pass over before encountering a duplicate, and this is capped by the size of the character set you're working with, which itself is some constant independent of the length of the string. For example, if you are only working with lower case alphabetic characters, the algorithm is O(26n) = O(n).
To be more exact you could say that it runs in O(n*(min(m,n)) where n is the length of the string and m is the number of characters in the alphabet of the string. The reason for the min is that even if you're somehow working with an alphabet of unlimited unique characters, at worst you're doing a double for loop to the end of the string. That means however that if the number of possible characters you can encounter in the string exceeds the string's length you have a worst case O(n^2) performance (which occurs when every character of the string is unique).
t= total string and s= test string if its present in t
t=input() #main string
s=input() #check for substring
print(any(s==t[i:i+len(s)] for i in range(len(t)-len(s))))
the give time complexity is O( (s)(t-s) ) but i did't understand how
Your complexity is more O(len(s).(len(t)-len(s))) than O((s)(t-s)) because
The loop size is len(t)-len(s) because of the range(len(t)-len(s))
Then each round loop does s == t[i:i+len(s)] which is a string comparison where both part have a length of len(s), so len(s) char to compare
Multiply them : len(s).(len(t)-len(s))
When I plot the time taken for the following algorithm for different size input, the time complexity appears to be polynomial. I'm not sure which operations account for this.
I'm assuming it's to do with list(s), del l[i] and l[::-1], but I'm not clear what the complexity of these is individually. Can anyone please explain?
Also, is there a way to optimize the algorithm without completely changing the approach? (I know there is a way to bring it down to linear time complexity by using "double-ended pincer-movement".)
def palindrome_index(s):
for i, c in enumerate(s):
l = list(s)
del l[i]
if l[::-1] == l:
return i
return -1
Your algorithm indeed is quadratic in len(s):
In iteration i, you perform linear time operations in the length: creating the list, reversing it, and (on linear on average) erasing element i. Since you perform this len(s) times, it is quadratic in len(s).
I'm assuming it's to do with list(s), del l[i] and l[::-1], but I'm not clear what the complexity of these is individually. Can anyone please explain?
Each of these operations is linear time (at least on average, which is enough to analyze your algorithm). Constructing a list, either from an iterable, or by reversing an existing list, is linear in the length of the list. Deleting element i, at the very least, requires about n - i + 1 shifts of the elements, as each one is moved back once.
All of these are linear "O(n)":
list(s)
list(s) creates a new list from s. To do that, it has to go through all elements in s, so its time is proportional to the length of s.
l[::-1]
Just like list(s), l[::-1] creates a new list with the same elements as l, but in different order. It has to touch each element once, so its time is proportional to the length of l.
del l[i]
In order to delete an element at position i, the element which was at position i+1 has to be moved to position i, then element which was at i+2 has to be moved to position i+1 etc. So, if you are deleting the first element (del l[0]), it has to touch move elements of the list and if you are deleting the last (del l[-1]), it just has to remove the last. On average, it will move n/2 elements, so it is also linear.
def count(substring, string):
"""
>>> count("bc","abcabcabc")
3
"""
counter = 0
for i in range(len(string) - len(substring) + 1):
counter += string.startswith(substring, i)
return counter
This is a function to count the number of recurrence of a substring in the base string. I think the time complexity is O(n) since I only iterate the string once. I think the space complexity is O(n) as well because I increment the counter in the loop N times. Can someone tell me if I am right or wrong?
The time complexity is O(nm) where n=len(s) and m=len(t) for the reason you provide, but incrementing counter doesn't cause it take up more space, so the space complexity of this function is O(1). No matter how long the input string is, you still only store a single variable, count.
[Edited to correct egregious error pointed out by poster]
Input - array / list a, constant k
Output - Length of Longest sublist/subarray with sum <=k
E.g. given
I am Bob
i.e. array [1,2,3] and k=3
Sublists possible are [1],[2],[3],[1,2]
Longest sublist here is [1,2]
Length = 2
Issue - TimeOut error in Python on Hackerrank
Time Complexity - 1 for loop - O(n)
Space complexity O(n)
def maxLength(a, k):
lenmax=0
dummy=[]
for i in a:
dummy.append(i)
if sum(dummy)<=k:
lenmax=max(lenmax,len(dummy))
else:
del dummy[0]
return lenmax
Solved it by replacing the time-intensive operation
Time-out occurs when it exceeds the time limit set by HackerRank for every environment "HackerRank TimeOut"
Solution
Replace sum() function by a variable
In worst case, sum(list) would take O(n^2) time if the entire list was to be summed up all the time.
Instead, maintaining a variable would mean O(n) for the entire function as O(1) for updating a variable.
def maxLength(a, k):
lenmax=0
dummy=[]
sumdummy=0
for i in a:
dummy.append(i)
sumdummy+=i
if sumdummy<=k:
lenmax=max(lenmax,len(dummy))
else:
sumdummy-=dummy[0]
del dummy[0]
return lenmax