Learning

Arrays & Dynamic Arrays

Arrays & Dynamic Arrays

Static Arrays (Concept)

python
# Python doesn't have true static arrays, but array module is close import array # Type-coded homogeneous array (compact storage) arr = array.array('i', [1, 2, 3, 4, 5]) # 'i' = signed int print(arr[0]) # 1 print(arr.buffer_info()) # (memory address, length) # Compared to list (which stores PyObject pointers) import sys py_list = [1, 2, 3, 4, 5] print(f'array: {sys.getsizeof(arr)} bytes') print(f'list: {sys.getsizeof(py_list)} bytes') # array is more compact for numeric data!

Python List Internals (Dynamic Array)

python
# CPython list is a dynamic array with over-allocation lst = [] print(f'Empty list: {sys.getsizeof(lst)} bytes') # 56 bytes for i in range(20): lst.append(i) size = sys.getsizeof(lst) if i < 5 or size != sys.getsizeof(lst[:-1]): print(f'len={i+1}: {size} bytes') # Notice: size jumps — over-allocation for amortized O(1) append # Growth pattern: ~0, 4, 8, 16, 25, 35, 46, 58, 72, 88...

Array Module Operations

python
import array arr = array.array('d', [1.0, 2.0, 3.0]) # 'd' = double # Append and extend arr.append(4.0) arr.extend([5.0, 6.0]) print(arr) # array('d', [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]) # Insert and delete arr.insert(0, 0.0) arr.remove(3.0) # Slice print(arr[1:4]) # array('d', [1.0, 2.0, 4.0]) # Type codes: 'b'=signed char, 'i'=int, 'f'=float, 'd'=double, 'u'=unicode

Common Operations Implementation

python
class SimpleArray: def __init__(self, capacity=10): self.data = [None] * capacity self.size = 0 self.capacity = capacity def append(self, value): if self.size >= self.capacity: self._resize(self.capacity * 2) self.data[self.size] = value self.size += 1 def _resize(self, new_capacity): new_data = [None] * new_capacity for i in range(self.size): new_data[i] = self.data[i] self.data = new_data self.capacity = new_capacity def insert(self, index, value): if self.size >= self.capacity: self._resize(self.capacity * 2) for i in range(self.size, index, -1): self.data[i] = self.data[i-1] self.data[index] = value self.size += 1 def delete(self, index): for i in range(index, self.size - 1): self.data[i] = self.data[i+1] self.data[self.size-1] = None self.size -= 1 def __str__(self): return f'[{", ".join(str(self.data[i]) for i in range(self.size))}]'

Two-Pointer Technique

python
def two_sum_sorted(arr, target): left, right = 0, len(arr) - 1 while left < right: current = arr[left] + arr[right] if current == target: return (left, right) elif current < target: left += 1 else: right -= 1 return None print(two_sum_sorted([1, 3, 5, 7, 9], 12)) # (1, 4)

Remove Duplicates (Two Pointer)

python
def remove_duplicates_sorted(arr): if not arr: return 0 write = 1 for read in range(1, len(arr)): if arr[read] != arr[read-1]: arr[write] = arr[read] write += 1 return write arr = [1, 1, 2, 2, 2, 3, 4, 4, 5] new_len = remove_duplicates_sorted(arr) print(arr[:new_len]) # [1, 2, 3, 4, 5]
Key Rules
  • •Python's list is a DYNAMIC ARRAY — contiguous memory with over-allocation strategy for O(1) amortized append
  • •array module stores typed values directly (compact), while list stores PyObject pointers (flexible but larger)
  • •list.append() is O(1) amortized, list.insert(0, x) is O(n) — shifts all elements
  • •list.pop() is O(1), list.pop(0) is O(n) — shifts all remaining elements
  • •Two-pointer technique solves many array problems in O(n) time and O(1) space
  • •When resizing, dynamic arrays typically grow by 1.5x-2x to keep amortized cost low
Your Task

Implement a `DynamicArray` class with `data` list, `size`, and `capacity`. Implement `append(value)` with auto-resize at 2x when full, `_resize(new_cap)` that creates new list and copies, `insert(index, value)` with shifting, `delete(index)` with shifting, `__getitem__`, `__len__`, and `__str__`. Then implement `remove_duplicates(arr)` using two-pointer technique for a sorted list. Demonstrate all operations.

EditorPython · JSX
PreviewUpdates on Run Tests
Loading preview…
Tests
Should define DynamicArray class
Should have _resize method
Should have insert with shifting loop
Should have delete with shifting loop
Should implement remove_duplicates with two pointers
Should implement __len__ and __getitem__