Arrays in Python – DSA

    Table of Contents

    1. Introduction
    2. Arrays vs Lists in Python
    3. Python Array Module
    4. NumPy Arrays
    5. Common Array Operations
    6. Time and Space Complexity
    7. Common Array Patterns
    8. Important Array Algorithms
    9. Practice Problems
    10. Tips and Best Practices

    Introduction

    An array is a data structure that stores a collection of elements, typically of the same data type, in contiguous memory locations. Arrays provide efficient access to elements using indices and are fundamental to many algorithms and data structures.

    Key Characteristics:

    • Fixed or Dynamic Size: Arrays can have fixed size (array module) or dynamic size (lists)
    • Index-based Access: Elements accessed via zero-based indexing
    • Contiguous Memory: Elements stored in adjacent memory locations
    • Homogeneous (array module) or Heterogeneous (lists): Same or different data types

    Arrays vs Lists in Python

    Python Lists (Most Common)

    # Lists are dynamic arrays that can hold mixed data types
    my_list = [1, 2, 3, "hello", 4.5, True]
    Python

    Advantages:

    • Dynamic sizing (can grow/shrink)
    • Can hold different data types
    • Rich built-in methods
    • More flexible

    Disadvantages:

    • Slightly more memory overhead
    • Slower for large numerical computations

    Python Array Module

    import array
    
    # Arrays are more memory-efficient but restricted to one data type
    int_array = array.array('i', [1, 2, 3, 4, 5])
    Python

    Advantages:

    • More memory-efficient
    • Faster for basic operations
    • Type safety

    Disadvantages:

    • Limited to single data type
    • Fewer built-in methods
    • Less flexible

    Comparison Table

    FeatureListArray ModuleNumPy Array
    Type SafetyNoYesYes
    MemoryHigherLowerLowest
    PerformanceGoodBetterBest (for numerical)
    FlexibilityHighMediumHigh
    Use CaseGeneral purposeBasic arraysScientific computing

    Python Array Module

    Creating Arrays

    import array
    
    # Syntax: array.array(typecode, [elements])
    # Common typecodes:
    # 'i' - signed int
    # 'I' - unsigned int
    # 'f' - float
    # 'd' - double
    # 'b' - signed byte
    # 'u' - unicode character
    
    # Integer array
    int_array = array.array('i', [1, 2, 3, 4, 5])
    
    # Float array
    float_array = array.array('f', [1.5, 2.5, 3.5])
    
    # From list
    numbers = [10, 20, 30, 40, 50]
    num_array = array.array('i', numbers)
    Python

    Basic Operations

    import array
    
    arr = array.array('i', [1, 2, 3, 4, 5])
    
    # Access element
    print(arr[0])  # Output: 1
    
    # Modify element
    arr[0] = 10
    
    # Append element
    arr.append(6)
    
    # Insert at index
    arr.insert(2, 15)  # Insert 15 at index 2
    
    # Remove element
    arr.remove(15)  # Remove first occurrence of 15
    
    # Pop element
    arr.pop()  # Remove and return last element
    arr.pop(0)  # Remove and return element at index 0
    
    # Extend array
    arr.extend([7, 8, 9])
    
    # Get length
    print(len(arr))
    
    # Convert to list
    list_version = arr.tolist()
    
    # Reverse
    arr.reverse()
    Python

    NumPy Arrays

    NumPy provides powerful n-dimensional arrays optimized for numerical computations.

    import numpy as np
    
    # Create arrays
    arr1 = np.array([1, 2, 3, 4, 5])
    arr2 = np.array([[1, 2, 3], [4, 5, 6]])  # 2D array
    
    # Special arrays
    zeros = np.zeros(5)  # [0. 0. 0. 0. 0.]
    ones = np.ones((3, 3))  # 3x3 matrix of ones
    arange = np.arange(0, 10, 2)  # [0 2 4 6 8]
    linspace = np.linspace(0, 1, 5)  # 5 evenly spaced values between 0 and 1
    
    # Array operations
    arr = np.array([1, 2, 3, 4, 5])
    print(arr + 10)  # Add 10 to each element
    print(arr * 2)   # Multiply each element by 2
    print(arr ** 2)  # Square each element
    
    # Statistical operations
    print(np.mean(arr))
    print(np.median(arr))
    print(np.std(arr))
    print(np.sum(arr))
    Python

    Common Array Operations

    1. Traversal

    # Using for loop
    arr = [1, 2, 3, 4, 5]
    for element in arr:
        print(element)
    
    # Using index
    for i in range(len(arr)):
        print(f"Index {i}: {arr[i]}")
    
    # Using enumerate
    for index, value in enumerate(arr):
        print(f"Index {index}: {value}")
    
    # Reverse traversal
    for i in range(len(arr) - 1, -1, -1):
        print(arr[i])
    Python

    2. Insertion

    arr = [1, 2, 3, 4, 5]
    
    # Insert at end - O(1)
    arr.append(6)
    
    # Insert at beginning - O(n)
    arr.insert(0, 0)
    
    # Insert at specific index - O(n)
    arr.insert(3, 10)
    
    # Extend with another array - O(k) where k is length of new array
    arr.extend([7, 8, 9])
    Python

    3. Deletion

    arr = [1, 2, 3, 4, 5, 3]
    
    # Remove by value - O(n)
    arr.remove(3)  # Removes first occurrence
    
    # Remove by index - O(n)
    del arr[0]
    
    # Pop (remove and return) - O(1) for last, O(n) for others
    arr.pop()      # Remove last element
    arr.pop(0)     # Remove first element
    
    # Clear all elements
    arr.clear()
    Python

    4. Searching

    arr = [10, 20, 30, 40, 50]
    
    # Linear search - O(n)
    def linear_search(arr, target):
        for i in range(len(arr)):
            if arr[i] == target:
                return i
        return -1
    
    # Binary search (for sorted arrays) - O(log n)
    def binary_search(arr, target):
        left, right = 0, len(arr) - 1
    
        while left <= right:
            mid = (left + right) // 2
            if arr[mid] == target:
                return mid
            elif arr[mid] < target:
                left = mid + 1
            else:
                right = mid - 1
        return -1
    
    # Using built-in methods
    if 30 in arr:
        index = arr.index(30)
        print(f"Found at index {index}")
    Python

    5. Sorting

    arr = [64, 34, 25, 12, 22, 11, 90]
    
    # Built-in sort - O(n log n)
    arr.sort()  # In-place sorting
    sorted_arr = sorted(arr)  # Returns new sorted array
    
    # Reverse sort
    arr.sort(reverse=True)
    
    # Custom sorting
    arr.sort(key=lambda x: -x)  # Sort in descending order
    
    # Bubble Sort - O(n²)
    def bubble_sort(arr):
        n = len(arr)
        for i in range(n):
            swapped = False
            for j in range(0, n - i - 1):
                if arr[j] > arr[j + 1]:
                    arr[j], arr[j + 1] = arr[j + 1], arr[j]
                    swapped = True
            if not swapped:
                break
        return arr
    
    # Quick Sort - O(n log n) average
    def quick_sort(arr):
        if len(arr) <= 1:
            return arr
        pivot = arr[len(arr) // 2]
        left = [x for x in arr if x < pivot]
        middle = [x for x in arr if x == pivot]
        right = [x for x in arr if x > pivot]
        return quick_sort(left) + middle + quick_sort(right)
    
    # Merge Sort - O(n log n)
    def merge_sort(arr):
        if len(arr) <= 1:
            return arr
    
        mid = len(arr) // 2
        left = merge_sort(arr[:mid])
        right = merge_sort(arr[mid:])
    
        return merge(left, right)
    
    def merge(left, right):
        result = []
        i = j = 0
    
        while i < len(left) and j < len(right):
            if left[i] <= right[j]:
                result.append(left[i])
                i += 1
            else:
                result.append(right[j])
                j += 1
    
        result.extend(left[i:])
        result.extend(right[j:])
        return result
    Python

    6. Reversing

    arr = [1, 2, 3, 4, 5]
    
    # Method 1: Using reverse() - O(n)
    arr.reverse()
    
    # Method 2: Using slicing - O(n)
    reversed_arr = arr[::-1]
    
    # Method 3: Manual reversal
    def reverse_array(arr):
        left, right = 0, len(arr) - 1
        while left < right:
            arr[left], arr[right] = arr[right], arr[left]
            left += 1
            right -= 1
        return arr
    Python

    7. Rotation

    # Left rotation by d positions
    def rotate_left(arr, d):
        n = len(arr)
        d = d % n  # Handle case where d > n
        return arr[d:] + arr[:d]
    
    # Right rotation by d positions
    def rotate_right(arr, d):
        n = len(arr)
        d = d % n
        return arr[-d:] + arr[:-d]
    
    # In-place rotation using reversal
    def rotate_left_inplace(arr, d):
        n = len(arr)
        d = d % n
    
        # Reverse first d elements
        reverse(arr, 0, d - 1)
        # Reverse remaining elements
        reverse(arr, d, n - 1)
        # Reverse entire array
        reverse(arr, 0, n - 1)
        return arr
    
    def reverse(arr, start, end):
        while start < end:
            arr[start], arr[end] = arr[end], arr[start]
            start += 1
            end -= 1
    
    # Example
    arr = [1, 2, 3, 4, 5]
    print(rotate_left(arr, 2))   # [3, 4, 5, 1, 2]
    print(rotate_right(arr, 2))  # [4, 5, 1, 2, 3]
    Python

    Time and Space Complexity

    List Operations Complexity

    OperationTime ComplexitySpace Complexity
    Access by indexO(1)O(1)
    SearchO(n)O(1)
    Insert at endO(1) amortizedO(1)
    Insert at beginningO(n)O(1)
    Insert at middleO(n)O(1)
    Delete at endO(1)O(1)
    Delete at beginningO(n)O(1)
    Delete at middleO(n)O(1)
    SlicingO(k) where k is slice sizeO(k)
    CopyO(n)O(n)
    ReverseO(n)O(1)
    SortO(n log n)O(n)

    Common Array Patterns

    1. Two Pointer Technique

    # Example: Check if array is palindrome
    def is_palindrome(arr):
        left, right = 0, len(arr) - 1
        while left < right:
            if arr[left] != arr[right]:
                return False
            left += 1
            right -= 1
        return True
    
    # Example: Two sum in sorted array
    def two_sum_sorted(arr, target):
        left, right = 0, len(arr) - 1
    
        while left < right:
            current_sum = arr[left] + arr[right]
            if current_sum == target:
                return [left, right]
            elif current_sum < target:
                left += 1
            else:
                right -= 1
        return []
    
    # Example: Remove duplicates from sorted array
    def remove_duplicates(arr):
        if not arr:
            return 0
    
        write_index = 1
        for i in range(1, len(arr)):
            if arr[i] != arr[i - 1]:
                arr[write_index] = arr[i]
                write_index += 1
        return write_index
    Python

    2. Sliding Window

    # Maximum sum subarray of size k
    def max_sum_subarray(arr, k):
        if len(arr) < k:
            return -1
    
        # Calculate sum of first window
        window_sum = sum(arr[:k])
        max_sum = window_sum
    
        # Slide the window
        for i in range(len(arr) - k):
            window_sum = window_sum - arr[i] + arr[i + k]
            max_sum = max(max_sum, window_sum)
    
        return max_sum
    
    # Longest subarray with sum <= k
    def longest_subarray_sum_k(arr, k):
        left = 0
        current_sum = 0
        max_length = 0
    
        for right in range(len(arr)):
            current_sum += arr[right]
    
            while current_sum > k and left <= right:
                current_sum -= arr[left]
                left += 1
    
            max_length = max(max_length, right - left + 1)
    
        return max_length
    Python

    3. Kadane’s Algorithm (Maximum Subarray Sum)

    def max_subarray_sum(arr):
        """
        Find maximum sum of contiguous subarray
        Time: O(n), Space: O(1)
        """
        max_sum = arr[0]
        current_sum = arr[0]
    
        for i in range(1, len(arr)):
            current_sum = max(arr[i], current_sum + arr[i])
            max_sum = max(max_sum, current_sum)
    
        return max_sum
    
    # With indices
    def max_subarray_with_indices(arr):
        max_sum = arr[0]
        current_sum = arr[0]
        start = end = temp_start = 0
    
        for i in range(1, len(arr)):
            if arr[i] > current_sum + arr[i]:
                current_sum = arr[i]
                temp_start = i
            else:
                current_sum += arr[i]
    
            if current_sum > max_sum:
                max_sum = current_sum
                start = temp_start
                end = i
    
        return max_sum, start, end
    Python

    4. Prefix Sum

    # Calculate prefix sum array
    def prefix_sum(arr):
        prefix = [0] * len(arr)
        prefix[0] = arr[0]
    
        for i in range(1, len(arr)):
            prefix[i] = prefix[i - 1] + arr[i]
    
        return prefix
    
    # Range sum query using prefix sum
    def range_sum(arr, left, right):
        prefix = prefix_sum(arr)
        if left == 0:
            return prefix[right]
        return prefix[right] - prefix[left - 1]
    
    # Subarray sum equals k
    def subarray_sum_k(arr, k):
        count = 0
        prefix_sum = 0
        sum_count = {0: 1}  # prefix_sum : frequency
    
        for num in arr:
            prefix_sum += num
    
            # Check if (prefix_sum - k) exists
            if (prefix_sum - k) in sum_count:
                count += sum_count[prefix_sum - k]
    
            # Add current prefix_sum to hash map
            sum_count[prefix_sum] = sum_count.get(prefix_sum, 0) + 1
    
        return count
    Python

    5. Dutch National Flag (3-way Partitioning)

    def sort_colors(arr):
        """
        Sort array with 0s, 1s, and 2s
        Time: O(n), Space: O(1)
        """
        low, mid, high = 0, 0, len(arr) - 1
    
        while mid <= high:
            if arr[mid] == 0:
                arr[low], arr[mid] = arr[mid], arr[low]
                low += 1
                mid += 1
            elif arr[mid] == 1:
                mid += 1
            else:  # arr[mid] == 2
                arr[mid], arr[high] = arr[high], arr[mid]
                high -= 1
    
        return arr
    Python

    6. Moore’s Voting Algorithm (Majority Element)

    def find_majority_element(arr):
        """
        Find element appearing more than n/2 times
        Time: O(n), Space: O(1)
        """
        candidate = None
        count = 0
    
        # Find candidate
        for num in arr:
            if count == 0:
                candidate = num
            count += (1 if num == candidate else -1)
    
        # Verify candidate (if majority might not exist)
        if arr.count(candidate) > len(arr) // 2:
            return candidate
        return None
    Python

    Important Array Algorithms

    1. Find Missing Number

    # Method 1: Using sum formula
    def find_missing_number(arr, n):
        """
        Array contains numbers 1 to n with one missing
        Time: O(n), Space: O(1)
        """
        expected_sum = n * (n + 1) // 2
        actual_sum = sum(arr)
        return expected_sum - actual_sum
    
    # Method 2: Using XOR
    def find_missing_xor(arr, n):
        xor_all = 0
        xor_arr = 0
    
        for i in range(1, n + 1):
            xor_all ^= i
    
        for num in arr:
            xor_arr ^= num
    
        return xor_all ^ xor_arr
    Python

    2. Find Duplicates

    # Find all duplicates in array containing numbers 1 to n
    def find_duplicates(arr):
        """
        Time: O(n), Space: O(1)
        Uses array indices as hash keys
        """
        result = []
    
        for num in arr:
            index = abs(num) - 1
            if arr[index] < 0:
                result.append(abs(num))
            else:
                arr[index] = -arr[index]
    
        return result
    
    # Find duplicate in array of n+1 elements containing 1 to n
    def find_duplicate(arr):
        """
        Floyd's Cycle Detection (Tortoise and Hare)
        Time: O(n), Space: O(1)
        """
        slow = fast = arr[0]
    
        # Find intersection point
        while True:
            slow = arr[slow]
            fast = arr[arr[fast]]
            if slow == fast:
                break
    
        # Find entrance to cycle
        slow = arr[0]
        while slow != fast:
            slow = arr[slow]
            fast = arr[fast]
    
        return slow
    Python

    3. Stock Buy and Sell

    # Single transaction
    def max_profit_single(prices):
        """
        Time: O(n), Space: O(1)
        """
        if not prices:
            return 0
    
        min_price = prices[0]
        max_profit = 0
    
        for price in prices:
            min_price = min(min_price, price)
            max_profit = max(max_profit, price - min_price)
    
        return max_profit
    
    # Multiple transactions
    def max_profit_multiple(prices):
        """
        Time: O(n), Space: O(1)
        """
        profit = 0
    
        for i in range(1, len(prices)):
            if prices[i] > prices[i - 1]:
                profit += prices[i] - prices[i - 1]
    
        return profit
    Python

    4. Product of Array Except Self

    def product_except_self(arr):
        """
        Calculate product of all elements except self
        Time: O(n), Space: O(1) excluding output array
        """
        n = len(arr)
        result = [1] * n
    
        # Calculate left products
        left_product = 1
        for i in range(n):
            result[i] = left_product
            left_product *= arr[i]
    
        # Calculate right products and combine
        right_product = 1
        for i in range(n - 1, -1, -1):
            result[i] *= right_product
            right_product *= arr[i]
    
        return result
    Python

    5. Trapping Rain Water

    def trap_rain_water(height):
        """
        Time: O(n), Space: O(1)
        """
        if not height:
            return 0
    
        left, right = 0, len(height) - 1
        left_max, right_max = 0, 0
        water = 0
    
        while left < right:
            if height[left] < height[right]:
                if height[left] >= left_max:
                    left_max = height[left]
                else:
                    water += left_max - height[left]
                left += 1
            else:
                if height[right] >= right_max:
                    right_max = height[right]
                else:
                    water += right_max - height[right]
                right -= 1
    
        return water
    Python

    6. Next Permutation

    def next_permutation(arr):
        """
        Find next lexicographically greater permutation
        Time: O(n), Space: O(1)
        """
        n = len(arr)
    
        # Find first decreasing element from right
        i = n - 2
        while i >= 0 and arr[i] >= arr[i + 1]:
            i -= 1
    
        if i >= 0:
            # Find element just larger than arr[i]
            j = n - 1
            while arr[j] <= arr[i]:
                j -= 1
            arr[i], arr[j] = arr[j], arr[i]
    
        # Reverse the suffix
        arr[i + 1:] = reversed(arr[i + 1:])
        return arr
    Python

    7. Longest Consecutive Sequence

    def longest_consecutive(arr):
        """
        Time: O(n), Space: O(n)
        """
        if not arr:
            return 0
    
        num_set = set(arr)
        longest = 0
    
        for num in num_set:
            # Only start counting from sequence start
            if num - 1 not in num_set:
                current_num = num
                current_length = 1
    
                while current_num + 1 in num_set:
                    current_num += 1
                    current_length += 1
    
                longest = max(longest, current_length)
    
        return longest
    Python

    8. Merge Intervals

    def merge_intervals(intervals):
        """
        Time: O(n log n), Space: O(n)
        """
        if not intervals:
            return []
    
        # Sort by start time
        intervals.sort(key=lambda x: x[0])
        merged = [intervals[0]]
    
        for current in intervals[1:]:
            last = merged[-1]
    
            if current[0] <= last[1]:
                # Overlapping intervals, merge
                last[1] = max(last[1], current[1])
            else:
                # Non-overlapping, add to result
                merged.append(current)
    
        return merged
    Python

    Practice Problems

    Easy Level

    1. Find Maximum and Minimum Element
    def find_min_max(arr):
    if not arr:
        return None, None
    return min(arr), max(arr)
    
    
    # Optimized: Compare in pairs
    
    def find_min_max_optimized(arr):
        if not arr:
            return None, None
    
        if len(arr) == 1:
            return arr[0], arr[0]
    
        if arr[0] < arr[1]:
            min_val, max_val = arr[0], arr[1]
        else:
            min_val, max_val = arr[1], arr[0]
    
        for i in range(2, len(arr) - 1, 2):
            if arr[i] < arr[i + 1]:
                min_val = min(min_val, arr[i])
                max_val = max(max_val, arr[i + 1])
            else:
                min_val = min(min_val, arr[i + 1])
                max_val = max(max_val, arr[i])
    
        if len(arr) % 2 == 1:
            min_val = min(min_val, arr[-1])
            max_val = max(max_val, arr[-1])
    
        return min_val, max_val
    Python
    1. Reverse Array
    def reverse_array(arr):
        return arr[::-1]
    
    
    def reverse_inplace(arr):
        left, right = 0, len(arr) - 1
        while left < right:
            arr[left], arr[right] = arr[right], arr[left]
            left += 1
            right -= 1
        return arr
    Python
    1. Move Zeros to End
    def move_zeros(arr):
    """
    Time: O(n), Space: O(1)
    """
    write_index = 0
    
    # Move all non-zero elements forward
    for i in range(len(arr)):
        if arr[i] != 0:
            arr[write_index] = arr[i]
            write_index += 1
    
    # Fill remaining with zeros
    while write_index < len(arr):
        arr[write_index] = 0
        write_index += 1
    
    return arr
    Python
    1. Find Second Largest Element
    def second_largest(arr):
    if len(arr) < 2:
        return None
    
    first = second = float('-inf')
    
    for num in arr:
        if num > first:
            second = first
            first = num
        elif num > second and num != first:
            second = num
    
    return second if second != float('-inf') else None
    Python
    1. Check if Array is Sorted
    def is_sorted(arr):
    for i in range(1, len(arr)):
        if arr[i] < arr[i - 1]:
            return False
    return True
    
    
    # Check both ascending and descending
    
    def is_sorted_any_order(arr):
        ascending = descending = True
    
        for i in range(1, len(arr)):
            if arr[i] < arr[i - 1]:
                ascending = False
            if arr[i] > arr[i - 1]:
                descending = False
    
        return ascending or descending
    Python

    Medium Level

    1. Find All Pairs with Given Sum
    def find_pairs(arr, target):
    seen = set()
    pairs = []
    
    for num in arr:
        complement = target - num
        if complement in seen:
            pairs.append((complement, num))
        seen.add(num)
    
    return pairs
    Python
    1. Subarray with Given Sum
    def subarray_with_sum(arr, target):
    """
    For non-negative numbers
    Time: O(n), Space: O(1)
    """
    current_sum = arr[0]
    start = 0
    
    for end in range(1, len(arr) + 1):
        while current_sum > target and start < end - 1:
            current_sum -= arr[start]
            start += 1
    
        if current_sum == target:
            return start, end - 1
    
        if end < len(arr):
            current_sum += arr[end]
    
    return -1, -1
    Python
    1. Rearrange Positive and Negative Numbers
    def rearrange_pos_neg(arr):
    """
    Maintain relative order
    Time: O(n), Space: O(n)
    """
    positive = [x for x in arr if x >= 0]
    negative = [x for x in arr if x < 0]
    
    result = []
    i = j = 0
    
    while i < len(positive) and j < len(negative):
        result.append(positive[i])
        result.append(negative[j])
        i += 1
        j += 1
    
    result.extend(positive[i:])
    result.extend(negative[j:])
    
    return result
    Python
    1. Find Peak Element
    def find_peak(arr):
    """
    Binary search approach
    Time: O(log n), Space: O(1)
    """
    left, right = 0, len(arr) - 1
    
    while left < right:
        mid = (left + right) // 2
    
        if arr[mid] > arr[mid + 1]:
            right = mid
        else:
            left = mid + 1
    
    return left
    Python
    1. Merge Two Sorted Arrays
    def merge_sorted(arr1, arr2):
    """
    Time: O(n + m), Space: O(n + m)
    """
    result = []
    i = j = 0
    
    while i < len(arr1) and j < len(arr2):
        if arr1[i] <= arr2[j]:
            result.append(arr1[i])
            i += 1
        else:
            result.append(arr2[j])
            j += 1
    
    result.extend(arr1[i:])
    result.extend(arr2[j:])
    
    return result
    Python

    Hard Level

    1. Median of Two Sorted Arrays
    def find_median_sorted_arrays(arr1, arr2):
    """
    Time: O(log(min(m, n))), Space: O(1)
    """
    if len(arr1) > len(arr2):
        arr1, arr2 = arr2, arr1
    
    m, n = len(arr1), len(arr2)
    left, right = 0, m
    
    while left <= right:
        partition1 = (left + right) // 2
        partition2 = (m + n + 1) // 2 - partition1
    
        max_left1 = float('-inf') if partition1 == 0 else arr1[partition1 - 1]
        min_right1 = float('inf') if partition1 == m else arr1[partition1]
    
        max_left2 = float('-inf') if partition2 == 0 else arr2[partition2 - 1]
        min_right2 = float('inf') if partition2 == n else arr2[partition2]
    
        if max_left1 <= min_right2 and max_left2 <= min_right1:
            if (m + n) % 2 == 0:
                return (max(max_left1, max_left2) + min(min_right1, min_right2)) / 2
            else:
                return max(max_left1, max_left2)
        elif max_left1 > min_right2:
            right = partition1 - 1
        else:
            left = partition1 + 1
    
    raise ValueError("Arrays are not sorted")
    Python
    1. Minimum Platforms Required (Train Scheduling)
    def min_platforms(arrivals, departures):
    """
    Time: O(n log n), Space: O(1)
    """
    arrivals.sort()
    departures.sort()
    
    platforms_needed = 1
    max_platforms = 1
    i = j = 1
    
    while i < len(arrivals) and j < len(departures):
        if arrivals[i] <= departures[j]:
            platforms_needed += 1
            i += 1
        else:
            platforms_needed -= 1
            j += 1
    
        max_platforms = max(max_platforms, platforms_needed)
    
    return max_platforms
    Python
    1. Smallest Subarray with Sum Greater than X
    def smallest_subarray_sum(arr, x):
    """
    Time: O(n), Space: O(1)
    """
    min_length = float('inf')
    current_sum = 0
    start = 0
    
    for end in range(len(arr)):
        current_sum += arr[end]
    
        while current_sum > x:
            min_length = min(min_length, end - start + 1)
            current_sum -= arr[start]
            start += 1
    
    return min_length if min_length != float('inf') else 0
    Python

    Tips and Best Practices

    1. Choosing the Right Data Structure

    • Use lists for general-purpose arrays with mixed types
    • Use array module for memory-efficient homogeneous data
    • Use NumPy for numerical computations and large datasets
    • Use collections.deque for frequent insertions/deletions at both ends

    2. Performance Optimization

    # Bad: Creating new array in loop
    result = []
    for i in range(1000000):
        result.append(i)
    
    # Good: List comprehension
    result = [i for i in range(1000000)]
    
    # Better: Use range object directly if just iterating
    for i in range(1000000):
        process(i)
    Python

    3. Memory Management

    # Bad: Creating unnecessary copies
    def process_array(arr):
        temp = arr[:]  # Unnecessary copy
        return temp
    
    # Good: Work in-place when possible
    def process_array(arr):
        # Modify arr directly
        return arr
    
    # When you need copy, be explicit
    import copy
    deep_copy = copy.deepcopy(nested_array)
    shallow_copy = arr[:]
    Python

    4. Common Pitfalls

    # Pitfall 1: Modifying array while iterating
    arr = [1, 2, 3, 4, 5]
    for i in range(len(arr)):
        if arr[i] % 2 == 0:
            arr.remove(arr[i])  # BAD: Can skip elements
    
    # Solution: Iterate backwards or create new array
    for i in range(len(arr) - 1, -1, -1):
        if arr[i] % 2 == 0:
            arr.pop(i)
    
    # Pitfall 2: List multiplication with nested lists
    matrix = [[0] * 3] * 3  # BAD: All rows are same object
    matrix[0][0] = 1  # Changes all rows!
    
    # Solution:
    matrix = [[0] * 3 for _ in range(3)]  # GOOD
    
    # Pitfall 3: Default mutable arguments
    def append_to(element, target=[]):  # BAD
        target.append(element)
        return target
    
    # Solution:
    def append_to(element, target=None):  # GOOD
        if target is None:
            target = []
        target.append(element)
        return target
    Python

    5. Testing Strategies

    def test_array_function():
        # Test empty array
        assert function([]) == expected_empty
    
        # Test single element
        assert function([1]) == expected_single
    
        # Test two elements
        assert function([1, 2]) == expected_two
    
        # Test normal case
        assert function([1, 2, 3, 4, 5]) == expected_normal
    
        # Test edge cases
        assert function([1, 1, 1, 1]) == expected_duplicates
        assert function([-5, -3, 0, 3, 5]) == expected_negative
    
        # Test large input (performance)
        large_input = list(range(1000000))
        function(large_input)  # Should complete quickly
    Python

    6. Code Style and Readability

    # Use descriptive variable names
    # Bad
    a = [1, 2, 3]
    for i in range(len(a)):
        print(a[i])
    
    # Good
    numbers = [1, 2, 3]
    for number in numbers:
        print(number)
    
    # Use enumerate when you need indices
    for index, value in enumerate(numbers):
        print(f"Index {index}: {value}")
    
    # Use zip for parallel iteration
    names = ['Alice', 'Bob', 'Charlie']
    ages = [25, 30, 35]
    for name, age in zip(names, ages):
        print(f"{name} is {age} years old")
    Python

    7. Interview Tips

    1. Always clarify requirements
      • Array size constraints
      • Value ranges (positive, negative, zero)
      • Duplicates allowed?
      • Sorted or unsorted?
    2. Start with brute force
      • Explain the O(n²) solution first
      • Then optimize to O(n log n) or O(n)
    3. Consider edge cases
      • Empty array
      • Single element
      • All same elements
      • Negative numbers
      • Very large/small values
    4. Communicate complexity
      • Always state time and space complexity
      • Explain trade-offs
    5. Write clean code
      • Use meaningful names
      • Add comments for complex logic
      • Handle edge cases explicitly

    Additional Resources

    Python Documentation

    Practice Platforms

    • LeetCode (Array tag)
    • HackerRank (Arrays section)
    • CodeForces
    • GeeksforGeeks
    • Easy: #1, #26, #27, #35, #53, #66, #88, #118, #121, #167
    • Medium: #15, #16, #18, #31, #33, #34, #48, #56, #75, #238
    • Hard: #4, #41, #42, #84, #128, #135, #239, #287

    Summary

    Arrays are fundamental data structures that every programmer must master. Key takeaways:

    1. Python lists are dynamic arrays – most versatile and commonly used
    2. Array module provides memory-efficient typed arrays
    3. NumPy is essential for numerical and scientific computing
    4. Master common patterns: two pointers, sliding window, prefix sum
    5. Understand time/space complexity trade-offs
    6. Practice, practice, practice!

    Happy coding! 🚀


    Discover more from Altgr Blog

    Subscribe to get the latest posts sent to your email.

    Leave a Reply

    Your email address will not be published. Required fields are marked *