amortized O(1) time, O(1) space when dealing with a dynamic array
because dynamic arrays are allocated almost double the memory size of what is actually required, adding new values to the end of the array only requires appending
only when the array memory has been filled up, would the array be copied and given double the memory slots that is newly required
during this case, time complexity becomes O(n)
however this can usually be ignored unless interviewer wants you to consider all cases
O(n) time, O(1) space when dealing with a static array
same concept as inserting a value at the beginning
removing a value at the beginning: O(n) time, O(1) space
time complexity is linear because you have to shift all of the affected elements
space is constant because no additional space is being created
removing a value in the middle: O(n) time, O(1) space
is an implementation of an array that allocates a fixed amount of memory to be used for storing the array's values
appending values to the array involves copying the entire array and allocating new memory for it, accounting for the extra space needed for the newly appended value