Popcorn Hack 1, constant time
arr = [1, 2, 3, 4, 5]
print(arr[2]) # Indexing is O(1), and lists are 0-indexed, so index 2 is the third item
3
Popcorn Hack 1, linear time
for item in arr:
print(item) # Loops over each item once — linear time
1
2
3
4
5
Popcorn Hack 2
def print_unique_pairs(arr):
for i in range(len(arr)):
for j in range(i + 1, len(arr)):
print(f"({arr[i]}, {arr[j]})")
# Example usage
arr = [1, 2, 3]
print_unique_pairs(arr)
(1, 2)
(1, 3)
(2, 3)
Popcorn Hack 2 continued-complexity explained
The time complexity of this code is O(log n).
Explanation: Binary search works by repeatedly dividing the search space in half. With each comparison, it eliminates half of the remaining elements. Because of this divide-and-conquer approach, the number of operations grows logarithmically relative to the size of the input — not linearly or quadratically. This makes binary search highly efficient for large sorted arrays.
Popcorn hack 3
1) b, factorial time explanation: Factorial time — O(n!) — grows extremely fast. It becomes impractical even for relatively small inputs (like n = 20). It’s often seen in brute-force algorithms for problems like the traveling salesman. 2) c, quadratic time explanation: Nested loops where each loop runs up to n usually result in O(n²), which is quadratic time. For example:
Homework Hack
def homework_hack(arr, complexity):
if complexity == "constant":
# Return the first item of the array (O(1) operation)
return arr[0] if arr else None
elif complexity == "linear":
# Print all the items in the array (O(n) operation)
for item in arr:
print(item)
elif complexity == "quadratic":
# Print all pairs of items in the array (O(n^2) operation)
for i in range(len(arr)):
for j in range(len(arr)):
print(arr[i], arr[j])
else:
print("Invalid complexity type. Use 'constant', 'linear', or 'quadratic'.")