When a list is copied:
list.copy()list[:]list()
It iterates thorugh all elements. So the time complexity defined by thr size of the list i.e. O(n)
When a list is copied:
list.copy()list[:]list()
It iterates thorugh all elements. So the time complexity defined by thr size of the list i.e. O(n)
When you do a copy operation on mutable datatypes:
b = list(a)
a is b # False
It copies the whole data to another memory location and the time complexity is defined by the total size of the list i.e. O(n)
If you had assigned it like following (Aliasing):
b = a
a is b # True
Then the time complexity would be O(1)
For more detail look here
What is the runtime complexity of Python's deepcopy()? - Stack Overflow
How to copy python list in constant time?
arrays - Does creating a deep copy of a string of size N (in python) take space complexity O(N) or O(1)? - Computer Science Stack Exchange
What is the time complexity of slicing a list?
Looking at the code (you can too), it goes through every object in the tree of referenced objects (e.g. dict's keys and values, object member variables, ...) and does two things for them:
- see if it's already been copied, by looking it in id-indexed
memodict - copy of the object if not
The second one is O(1) for simple objects. For composite objects, the same routine handles them, so over all n objects in the tree, that's O(n). The first part, looking an object up in a dict, is O(1) on average, but O(n) amortized worst case.
So at best, on average, deepcopy is linear. The keys used in memo are id() values, i.e. memory locations, so they are not randomly distributed over the key space (the "average" part above) and it may behave worse, up to the O(n^2) worst case. I did observe some performance degradations in real use, but for the most part, it behaved as linear.
That's the complexity part, but the constant is large and deepcopy is anything but cheap and could very well be causing your problems. The only sure way to know is to use a profiler -- do it. FWIW, I'm currently rewriting terribly slow code that spends 98% of its execution time in deepcopy.
What are you using deepcopy for? As the name suggests, deepcopy copies the object, and all subobjects recursively, so it is going to take an amount of time proportional to the size of the object you are copying. (with a bit of overhead to deal with circular references)
There isn't really any way to speed it up, if you are going to copy everything, you need to copy everything.
One question to ask, is do you need to copy everything, or can you just copy part of the structure.
How to copy python list in constant time?
list.copy() takes O(n) time.
l1 = l2 takes O(1) but it will copy the reference.
If the output of the algorithm is the deep-copied string, the complexity is O(1), because you don't count the input nor output space.
If the copy is used for internal purposes, then the complexity is at least O(N).
But this is unrelated to the LeetCode question, which does not require a deep copy. (The required space is bounded by the alphabet size.)
I thought the space complexity of this solution is O(N), because if the string has all unique characters, we will need the hashmap to have N keys
Remember, big-O tells you the tendency as N goes to infinity. If a string has more than around 2^21 characters (assuming valid Unicode) they can't all be unique, by the pigeonhole principle, so as N increases beyond this point, the number of elements in the map stops growing — the definition of O(1).
I think it's O(1) but some sources online say O(n)
I have created a copy-method in the code. It creates and returns a copy of the LinkedList object. However, I have been asked to create a more efficient method. I have three questions:
1 - What is the complexity of my copy method? Do I have to take into account the complexity of the insert-method when calculating the complexity? 2 - How would you rewrite the code so it gets a better complexity! And which would be this complexity?
Code:
class LinkedList:
class Node:
def __init__(self, data, succ):
self.data = data
self.succ = succ
def __init__(self):
self.first = None
def insert(self, x):
if self.first is None or x <= self.first.data:
self.first = self.Node(x, self.first)
else:
f = self.first
while f.succ and x > f.succ.data:
f = f.succ
f.succ = self.Node(x, f.succ)
def copy(self):
result = LinkedList()
for x in self:
result.insert(x)
return result