Table of Contents
- Introduction
- Arrays vs Lists in Python
- Python Array Module
- NumPy Arrays
- Common Array Operations
- Time and Space Complexity
- Common Array Patterns
- Important Array Algorithms
- Practice Problems
- 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]PythonAdvantages:
- 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])PythonAdvantages:
- More memory-efficient
- Faster for basic operations
- Type safety
Disadvantages:
- Limited to single data type
- Fewer built-in methods
- Less flexible
Comparison Table
| Feature | List | Array Module | NumPy Array |
|---|---|---|---|
| Type Safety | No | Yes | Yes |
| Memory | Higher | Lower | Lowest |
| Performance | Good | Better | Best (for numerical) |
| Flexibility | High | Medium | High |
| Use Case | General purpose | Basic arrays | Scientific 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)PythonBasic 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()PythonNumPy 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))PythonCommon 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])Python2. 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])Python3. 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()Python4. 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}")Python5. 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 resultPython6. 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 arrPython7. 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]PythonTime and Space Complexity
List Operations Complexity
| Operation | Time Complexity | Space Complexity |
|---|---|---|
| Access by index | O(1) | O(1) |
| Search | O(n) | O(1) |
| Insert at end | O(1) amortized | O(1) |
| Insert at beginning | O(n) | O(1) |
| Insert at middle | O(n) | O(1) |
| Delete at end | O(1) | O(1) |
| Delete at beginning | O(n) | O(1) |
| Delete at middle | O(n) | O(1) |
| Slicing | O(k) where k is slice size | O(k) |
| Copy | O(n) | O(n) |
| Reverse | O(n) | O(1) |
| Sort | O(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_indexPython2. 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_lengthPython3. 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, endPython4. 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 countPython5. 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 arrPython6. 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 NonePythonImportant 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_arrPython2. 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 slowPython3. 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 profitPython4. 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 resultPython5. 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 waterPython6. 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 arrPython7. 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 longestPython8. 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 mergedPythonPractice Problems
Easy Level
- 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_valPython- 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 arrPython- 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 arrPython- 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 NonePython- 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 descendingPythonMedium Level
- 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 pairsPython- 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, -1Python- 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 resultPython- 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 leftPython- 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 resultPythonHard Level
- 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- 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_platformsPython- 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 0PythonTips 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)Python3. 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[:]Python4. 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 targetPython5. 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 quicklyPython6. 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")Python7. Interview Tips
- Always clarify requirements
- Array size constraints
- Value ranges (positive, negative, zero)
- Duplicates allowed?
- Sorted or unsorted?
- Start with brute force
- Explain the O(n²) solution first
- Then optimize to O(n log n) or O(n)
- Consider edge cases
- Empty array
- Single element
- All same elements
- Negative numbers
- Very large/small values
- Communicate complexity
- Always state time and space complexity
- Explain trade-offs
- 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
Recommended Problems (LeetCode)
- 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:
- Python lists are dynamic arrays – most versatile and commonly used
- Array module provides memory-efficient typed arrays
- NumPy is essential for numerical and scientific computing
- Master common patterns: two pointers, sliding window, prefix sum
- Understand time/space complexity trade-offs
- Practice, practice, practice!
Happy coding! 🚀
Discover more from Altgr Blog
Subscribe to get the latest posts sent to your email.
