/

Arrays

An array is a fundamental data structure that stores elements in contiguous memory locations, enabling constant-time access by index and forming the backbone of most other data structures and algorithms.

Data Structure O(1) Access

What is an Array?

An array is a collection of elements stored at contiguous (adjacent) memory locations. Because the elements are packed together in sequence, the address of any element can be computed from its index using a simple formula: base_address + index * element_size. This is what gives arrays their hallmark O(1) random access.

Arrays are among the oldest and most widely used data structures in computer science. Nearly every programming language provides a built-in array type. They are the foundation on which many higher-level structures — such as dynamic arrays (Python lists, Java ArrayLists), heaps, hash tables, and matrices — are built.

Key characteristics of arrays:

  • Fixed size (static arrays): The size is determined at creation time and cannot change. Languages like C and Java (primitive arrays) use fixed-size arrays.
  • Dynamic resizing: Higher-level languages provide dynamic arrays (e.g., Python's list, C++'s std::vector, Java's ArrayList) that automatically grow when capacity is exceeded, typically doubling in size.
  • Homogeneous elements: In statically typed languages, all elements must be the same type. Dynamically typed languages like Python allow mixed types.
  • Zero-based indexing: Most languages index arrays starting from 0, so the first element is at index 0 and the last is at index n - 1.
  • Cache-friendly: Because elements are stored contiguously, arrays exhibit excellent spatial locality, making sequential access very fast on modern CPUs.

The main trade-off is that insertion and deletion in the middle of an array are expensive — O(n) — because elements must be shifted to maintain contiguity. When frequent insertions and deletions are needed, a linked list or other structure may be more appropriate.

Interactive Visualization

Choose an operation and click a button to begin.
No steps

Code Implementation

# --- Array Operations in Python ---

# Create an array (Python list)
arr = [5, 12, 8, 3, 19, 7]
print("Original:", arr)

# Access by index - O(1)
print("Element at index 2:", arr[2])  # 8

# Insert at a specific index - O(n)
def insert_at(array, index, value):
    """Insert value at the given index, shifting elements right."""
    array.insert(index, value)
    return array

insert_at(arr, 2, 99)
print("After insert 99 at index 2:", arr)

# Delete at a specific index - O(n)
def delete_at(array, index):
    """Remove element at the given index, shifting elements left."""
    if 0 <= index < len(array):
        array.pop(index)
    return array

delete_at(arr, 2)
print("After delete at index 2:", arr)

# Linear search - O(n)
def linear_search(array, target):
    """Return the index of target, or -1 if not found."""
    for i in range(len(array)):
        if array[i] == target:
            return i
    return -1

idx = linear_search(arr, 19)
print("Search for 19: found at index", idx)
import java.util.ArrayList;
import java.util.Arrays;

public class ArrayOperations {

    // Insert at a specific index - O(n)
    public static int[] insertAt(int[] arr, int index, int value) {
        int[] result = new int[arr.length + 1];
        for (int i = 0; i < index; i++) {
            result[i] = arr[i];
        }
        result[index] = value;
        for (int i = index; i < arr.length; i++) {
            result[i + 1] = arr[i];
        }
        return result;
    }

    // Delete at a specific index - O(n)
    public static int[] deleteAt(int[] arr, int index) {
        if (index < 0 || index >= arr.length) return arr;
        int[] result = new int[arr.length - 1];
        for (int i = 0; i < index; i++) {
            result[i] = arr[i];
        }
        for (int i = index + 1; i < arr.length; i++) {
            result[i - 1] = arr[i];
        }
        return result;
    }

    // Linear search - O(n)
    public static int linearSearch(int[] arr, int target) {
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == target) return i;
        }
        return -1;
    }

    public static void main(String[] args) {
        int[] arr = {5, 12, 8, 3, 19, 7};
        System.out.println("Original: " + Arrays.toString(arr));

        // Access by index - O(1)
        System.out.println("Element at index 2: " + arr[2]);

        // Insert
        arr = insertAt(arr, 2, 99);
        System.out.println("After insert: " + Arrays.toString(arr));

        // Delete
        arr = deleteAt(arr, 2);
        System.out.println("After delete: " + Arrays.toString(arr));

        // Search
        int idx = linearSearch(arr, 19);
        System.out.println("Search for 19: index " + idx);
    }
}
#include <iostream>
#include <vector>
using namespace std;

// Insert at a specific index - O(n)
void insertAt(vector<int>& arr, int index, int value) {
    arr.insert(arr.begin() + index, value);
}

// Delete at a specific index - O(n)
void deleteAt(vector<int>& arr, int index) {
    if (index < 0 || index >= (int)arr.size()) return;
    arr.erase(arr.begin() + index);
}

// Linear search - O(n)
int linearSearch(const vector<int>& arr, int target) {
    for (int i = 0; i < (int)arr.size(); i++) {
        if (arr[i] == target) return i;
    }
    return -1;
}

void printArray(const vector<int>& arr) {
    cout << "[";
    for (int i = 0; i < (int)arr.size(); i++) {
        if (i > 0) cout << ", ";
        cout << arr[i];
    }
    cout << "]" << endl;
}

int main() {
    vector<int> arr = {5, 12, 8, 3, 19, 7};
    cout << "Original: ";
    printArray(arr);

    // Access by index - O(1)
    cout << "Element at index 2: " << arr[2] << endl;

    // Insert
    insertAt(arr, 2, 99);
    cout << "After insert: ";
    printArray(arr);

    // Delete
    deleteAt(arr, 2);
    cout << "After delete: ";
    printArray(arr);

    // Search
    int idx = linearSearch(arr, 19);
    cout << "Search for 19: index " << idx << endl;

    return 0;
}

Complexity Analysis

Operation Time Complexity Explanation
Access O(1) Direct address calculation from base address and index.
Search O(n) Must scan elements one by one in the worst case (linear search).
Insertion O(n) Elements after the insertion point must be shifted right.
Deletion O(n) Elements after the deletion point must be shifted left.
Space O(n) Requires memory proportional to the number of elements stored.

Note: Appending to the end of a dynamic array (e.g., Python list.append()) is amortized O(1) because resizing doubles the capacity, so the expensive copy happens infrequently. However, inserting at an arbitrary position is always O(n) due to shifting.

Practice Problems

Easy Two Sum LeetCode #1 →
Easy Best Time to Buy and Sell Stock LeetCode #121 →
Easy Contains Duplicate LeetCode #217 →

Quiz

Q1. What is the time complexity of accessing an element in an array by its index?

O(n)
O(1)
O(log n)
O(n log n)
Accessing an array element by index is O(1) because the memory address is computed directly using the formula: base_address + index * element_size. No traversal is needed.

Q2. Why is inserting an element in the middle of an array O(n)?

Because the array must be searched first
Because a new array must always be allocated
Because all elements after the insertion point must be shifted right
Because elements must be sorted after insertion
To maintain contiguous storage, every element from the insertion index onward must be moved one position to the right. In the worst case (inserting at index 0), all n elements must be shifted, giving O(n) time.

Q3. What is the primary advantage of arrays over linked lists?

O(1) random access to any element by index
O(1) insertion at any position
Dynamic size without any overhead
Lower memory usage per element
Arrays provide O(1) random access because elements are stored contiguously and the address can be calculated directly. Linked lists require O(n) traversal to reach an arbitrary element. While arrays also tend to use less memory per element (no pointer overhead), the defining advantage is constant-time indexed access.

Q4. In a zero-indexed array of 8 elements, what is the index of the last element?

8
1
6
7
With zero-based indexing, the first element is at index 0 and the last element is at index n - 1. For 8 elements: the last index is 8 - 1 = 7.

Q5. What is the amortized time complexity of appending to the end of a dynamic array (e.g., Python list)?

O(n) always
O(1) amortized
O(log n)
O(n log n)
Dynamic arrays double their capacity when full. Most appends simply place the element at the end in O(1). Occasionally, the array must be resized (O(n) copy), but this happens so rarely that the average cost per operation, spread over a sequence of appends, is O(1) amortized.