Arrays

A contiguous block of memory that stores elements of the same type, accessible by index.

Definition

An array is a data structure that stores a collection of items of the same type, such as integers or strings. These items are stored contiguously, much like a row of numbered lockers. Each item in an array can be quickly accessed using its index, so reading or updating any element is fast.

Operations

Arrays support a handful of common operations. Because array elements are stored together in memory, some are very fast, while others take more work. Here is an overview of array operations:

OperationsTimeSpace
AppendO(1)O(1)
PopO(1)O(1)
AccessO(1)O(1)
InsertO(n)O(1)
DeleteO(n)O(1)
SearchO(n)O(1)
ResizeO(n)O(n)
Array Pointers

Pointers are useful because they let you directly access and modify array elements. That direct access is what makes arrays fast, especially when iterating through elements or building data structures like stacks and queues. Here is an example:

reverse_array.py

def reverse(array: List[int]) -> List[int]:
    left, right = 0, len(array) - 1
    while left < right:
        array[left], array[right] = array[right], array[left]
        left += 1
        right -= 1
    return array

# Example usage
my_array = [1, 2, 3, 4, 5, 6]
print(reverse(my_array))  # Output: [6, 5, 4, 3, 2, 1]
Animation of two pointers being used to reverse the elements of an array

The reverse() function above takes an array of integers and flips it in place, meaning the original array is modified without needing extra space for another array. It uses two pointers: left starts at the beginning, and right starts at the end. They walk toward each other, swapping elements along the way, until they meet in the middle.

Static Arrays

Static arrays have a fixed size, set when the program is compiled. This makes accessing elements very fast. The downside is that you can't add more elements once the array is full. Doing so causes an error or unexpected behavior. Python hides this from you, but the underlying concepts are still worth knowing.

Dynamic Arrays

Unlike static arrays, dynamic arrays can grow and shrink while the program is running. The tradeoff is that the computer has to track the array's size, and when the array outgrows its spot in memory, it has to be copied to a bigger one. That costs more time and memory than a static array. Luckily, smart resizing strategies make this amortized constant time.

dynamic_arrays.py

class DynamicArray:
    def __init__(self):
        self.array = [None]  # Start with an array of size 1
        self.size = 0

    def append(self, element):
        if self.size == len(self.array):
            # Array is full, time to resize
            new_array = [None] * (2 * len(self.array))
            # Copy elements to the new array
            for i in range(self.size):
                new_array[i] = self.array[i]
            self.array = new_array
            print(f"Array doubled. New capacity: {len(self.array)}")

        # Add the new element
        self.array[self.size] = element
        self.size += 1

# Example usage
dynamic_array = DynamicArray()
for i in range(5):
    dynamic_array.append(i)
    print(f"Added {i}. Current size: {dynamic_array.size}, Capacity: {len(dynamic_array.array)}")

Most languages have dynamic arrays built in. Python calls them List, and Java calls them ArrayList. Get comfortable with whatever your language offers, since you'll use them constantly.

Stacks

Stacks follow the LIFO principle. They aren't arrays themselves, but they're often built on top of one. Since stacks only add or remove from the end, arrays are a natural fit. They have two main operations: push adds an item on top, and pop removes the top item. Both run in constant time.

OperationsTimeSpace
PushO(1)O(1)
PopO(1)O(1)
PeekO(1)O(1)
Is EmptyO(1)O(1)
SizeO(1)O(1)
ClearO(1)O(1)
Animation of stacks and the operations that they support

The animation above shows how stacks work in practice. Just like a stack of plates where you can only add or remove from the top, each operation works with the most recently added element. This LIFO behavior makes stacks ideal when each element depends on the one that came before.

Best Practices

Arrays and stacks come up constantly in coding interviews. The tips below cover the patterns to watch for and the mistakes that trip people up most:


Arrays show up in sorting, searching, and iteration problems. They're also where you'll usually store the final result. Get fluent with the array functions your language offers, since you'll reach for them constantly.

Practice Problems

The patterns above show up everywhere on LeetCode. Work through these classic array and stack problems to practice in-place updates, single-pass scans, and the LIFO patterns you just learned about:


Arrays
Completed
Title
Notes
Solution
Easy
Easy
Easy
Easy
Medium
Medium
Medium
Medium
Hard
Hard
Hard
Hard