🔥 Awesome — this is going to be your “Deep Python Lists in 3 Days” full mastery roadmap.
You’ll go from list internals (memory, references, slicing) → fundamental list algorithms → advanced sliding window and two-pointer problems → interval & array logic used in real interviews.
And yes — it includes all those problems + a clean visual cheat sheet at the end.
🧠 Deep Python Lists in 3 Days
Understand. Implement. Master.
📅 Overview
| Day | Focus | Core Skills |
|---|---|---|
| Day 1 | Python List Internals & Basics | Memory, mutability, slicing, iteration, core algorithms |
| Day 2 | Intermediate–Advanced List Algorithms | Subarrays, prefix sums, intervals, Kadane’s, product array |
| Day 3 | Two Pointers & Sliding Window Mastery | Patterns for array optimization, searching, and partition problems |
🩵 DAY 1 – Python List Internals & Foundational Algorithms
🎯 Goal
Understand how Python lists work under the hood (mutable dynamic arrays), and implement core problems using basic iteration, sets, and counting.
🧠 PART 1 – Python List Internals
🔹 How Lists Work Behind the Scenes
- Lists are dynamic arrays — contiguous memory blocks storing pointers to elements.
- Internally implemented as a C array of pointers (
PyListObject). - Dynamic resizing strategy (over-allocation):
- When full, it grows by ~12.5% of its size.
- This makes
append()amortized O(1).
🔹 Mutability & References
a = [1, 2, 3]
b = a
b.append(4)
print(a) # [1, 2, 3, 4] – same object
Use copy() or slicing a[:] to create shallow copies.
🔹 Slicing and Memory
nums = [10, 20, 30, 40]
slice_copy = nums[1:3]
print(slice_copy) # [20, 30]
print(nums[1:3] is nums) # False
✅ Each slice creates a new list.
🔹 Common Built-in Operations (O-notation)
| Operation | Example | Time Complexity |
|---|---|---|
| Indexing | a[i] | O(1) |
| Append | a.append(x) | Amortized O(1) |
| Insert | a.insert(0, x) | O(n) |
| Pop | a.pop() | O(1) |
| Slice | a[1:5] | O(k) |
| Membership | x in a | O(n) |
| Sort | a.sort() | O(n log n) |
🧩 PART 2 – List Basics Problems
1️⃣ Second Largest Number
def second_largest(nums):
first = second = float('-inf')
for n in nums:
if n > first:
first, second = n, first
elif first > n > second:
second = n
return second
2️⃣ Is List Ascending?
def is_ascending(lst):
return all(lst[i] <= lst[i+1] for i in range(len(lst)-1))
3️⃣ First Repeating Number (Nested Loops)
def first_repeating_nested(nums):
for i in range(len(nums)):
for j in range(i+1, len(nums)):
if nums[i] == nums[j]:
return nums[i]
return None
4️⃣ First Repeating Number (Set)
def first_repeating(nums):
seen = set()
for n in nums:
if n in seen:
return n
seen.add(n)
return None
5️⃣ Find Duplicates
def find_duplicates(nums):
seen, dup = set(), set()
for n in nums:
if n in seen:
dup.add(n)
seen.add(n)
return list(dup)
6️⃣ Most Common Value
from collections import Counter
def most_common(nums):
return Counter(nums).most_common(1)[0][0]
7️⃣ Missing Number (LeetCode #268)
def missing_number(nums):
n = len(nums)
return n * (n + 1) // 2 - sum(nums)
8️⃣ Max Profit (LeetCode #121)
def max_profit(prices):
min_price = float('inf')
profit = 0
for p in prices:
min_price = min(min_price, p)
profit = max(profit, p - min_price)
return profit
9️⃣ Two Sum (LeetCode #1)
def two_sum(nums, target):
seen = {}
for i, n in enumerate(nums):
if target - n in seen:
return [seen[target - n], i]
seen[n] = i
🔟 Majority Element (LeetCode #169)
def majority_element(nums):
count = 0
candidate = None
for n in nums:
if count == 0:
candidate = n
count += (1 if n == candidate else -1)
return candidate
11️⃣ Intersection of Two Arrays
def intersection(nums1, nums2):
return list(set(nums1) & set(nums2))
12️⃣ Rotate List
def rotate(nums, k):
k %= len(nums)
nums[:] = nums[-k:] + nums[:-k]
return nums
13️⃣ Move All Zeros to End
def move_zeros(nums):
pos = 0
for i in range(len(nums)):
if nums[i] != 0:
nums[pos], nums[i] = nums[i], nums[pos]
pos += 1
return nums
14️⃣ Remove Duplicates from Sorted Array
def remove_duplicates(nums):
if not nums: return 0
j = 0
for i in range(1, len(nums)):
if nums[i] != nums[j]:
j += 1
nums[j] = nums[i]
return j + 1
15️⃣ Merge Two Sorted Arrays
def merge_sorted(a, b):
i = j = 0
merged = []
while i < len(a) and j < len(b):
if a[i] < b[j]:
merged.append(a[i])
i += 1
else:
merged.append(b[j])
j += 1
merged.extend(a[i:])
merged.extend(b[j:])
return merged
16️⃣ Find All Pairs with Given Sum
def find_pairs(nums, target):
seen = set()
pairs = set()
for n in nums:
if target - n in seen:
pairs.add(tuple(sorted((n, target - n))))
seen.add(n)
return list(pairs)
17️⃣ Count Occurrences
from collections import Counter
def count_occurrences(nums):
return dict(Counter(nums))
✅ End of Day 1 Focus:
You can now handle:
- Counting / Frequency
- Sorting / Searching
- Basic optimizations with O(n) space and time.
💎 DAY 2 – Intermediate & Advanced Array Patterns
🎯 Goal
Learn core array patterns: prefix sums, Kadane’s algorithm, and subarray problems.
1️⃣ Longest Consecutive Sequence
def longest_consecutive(nums):
s = set(nums)
longest = 0
for n in s:
if n - 1 not in s:
curr = n
length = 1
while curr + 1 in s:
curr += 1
length += 1
longest = max(longest, length)
return longest
2️⃣ Subarray Sum Equals K
def subarray_sum(nums, k):
prefix_sum = 0
seen = {0: 1}
count = 0
for n in nums:
prefix_sum += n
count += seen.get(prefix_sum - k, 0)
seen[prefix_sum] = seen.get(prefix_sum, 0) + 1
return count
3️⃣ Maximum Subarray (Kadane’s)
def max_subarray(nums):
curr = best = nums[0]
for n in nums[1:]:
curr = max(n, curr + n)
best = max(best, curr)
return best
4️⃣ Product of Array Except Self
def product_except_self(nums):
res = [1] * len(nums)
prefix = 1
for i in range(len(nums)):
res[i] = prefix
prefix *= nums[i]
suffix = 1
for i in range(len(nums)-1, -1, -1):
res[i] *= suffix
suffix *= nums[i]
return res
5️⃣ 3Sum
def three_sum(nums):
nums.sort()
res = []
for i in range(len(nums) - 2):
if i > 0 and nums[i] == nums[i-1]:
continue
l, r = i + 1, len(nums) - 1
while l < r:
s = nums[i] + nums[l] + nums[r]
if s == 0:
res.append([nums[i], nums[l], nums[r]])
l += 1
r -= 1
while l < r and nums[l] == nums[l-1]:
l += 1
while l < r and nums[r] == nums[r+1]:
r -= 1
elif s < 0:
l += 1
else:
r -= 1
return res
6️⃣ 4Sum
(similar to 3Sum but extra loop)
7️⃣ Trapping Rain Water
def trap(height):
left, right = 0, len(height)-1
lmax, rmax = 0, 0
res = 0
while left < right:
if height[left] < height[right]:
if height[left] >= lmax:
lmax = height[left]
else:
res += lmax - height[left]
left += 1
else:
if height[right] >= rmax:
rmax = height[right]
else:
res += rmax - height[right]
right -= 1
return res
8️⃣ Container With Most Water
def max_area(height):
l, r = 0, len(height)-1
best = 0
while l < r:
area = (r-l) * min(height[l], height[r])
best = max(best, area)
if height[l] < height[r]:
l += 1
else:
r -= 1
return best
9️⃣ Merge Intervals
def merge_intervals(intervals):
intervals.sort(key=lambda x: x[0])
merged = [intervals[0]]
for start, end in intervals[1:]:
if start <= merged[-1][1]:
merged[-1][1] = max(merged[-1][1], end)
else:
merged.append([start, end])
return merged
🔟 Search in Rotated Sorted Array
def search_rotated(nums, target):
l, r = 0, len(nums)-1
while l <= r:
mid = (l + r)//2
if nums[mid] == target:
return mid
if nums[l] <= nums[mid]:
if nums[l] <= target < nums[mid]:
r = mid - 1
else:
l = mid + 1
else:
if nums[mid] < target <= nums[r]:
l = mid + 1
else:
r = mid - 1
return -1
✅ End of Day 2 Focus:
You now master:
- Prefix sums, Kadane’s
- Two-pointer for 3Sum, Trapping Water, Max Area
- Interval problems and binary search
🧠 DAY 3 – Two Pointers & Sliding Window Mastery
1️⃣ Max Consecutive Ones
def max_consecutive_ones(nums):
best = curr = 0
for n in nums:
if n == 1:
curr += 1
best = max(best, curr)
else:
curr = 0
return best
2️⃣ Max Consecutive Ones III (at most K zeros)
def longest_ones(nums, k):
left = 0
zeros = 0
best = 0
for right in range(len(nums)):
if nums[right] == 0:
zeros += 1
while zeros > k:
if nums[left] == 0:
zeros -= 1
left += 1
best = max(best, right - left + 1)
return best
3️⃣ Sort Colors (Dutch National Flag)
def sort_colors(nums):
low, mid, high = 0, 0, len(nums)-1
while mid <= high:
if nums[mid] == 0:
nums[low], nums[mid] = nums[mid], nums[low]
low += 1; mid += 1
elif nums[mid] == 1:
mid += 1
else:
nums[mid], nums[high] = nums[high], nums[mid]
high -= 1
return nums
4️⃣ Remove Duplicates (Two Pointer)
def remove_duplicates(nums):
slow = 0
for fast in range(1, len(nums)):
if nums[fast] != nums[slow]:
slow += 1
nums[slow] = nums[fast]
return slow + 1
5️⃣ Find Pair with Given Difference
def has_pair_with_diff(nums, diff):
nums.sort()
i, j = 0, 1
while j < len(nums):
if i == j:
j += 1
continue
d = nums[j] - nums[i]
if d == diff:
return True
elif d < diff:
j += 1
else:
i += 1
return False
6️⃣ Is Subsequence (Revisited)
def is_subsequence(s, t):
i = 0
for ch in t:
if i < len(s) and s[i] == ch:
i += 1
return i == len(s)
✅ By End of Day 3:
- You master two-pointer and sliding window patterns.
- You can build subarray, sum, and interval algorithms fluently.
🧾 CHEAT SHEET: Python Lists / Arrays Mastery
| Category | Pattern | Time | Example |
|---|---|---|---|
| Traversal | for / enumerate | O(n) | for i,v in enumerate(a) |
| Slicing | a[start:end:step] | O(k) | a[::-1] |
| Counting | Counter(a) | O(n) | Find duplicates |
| Two Pointers | Shrink-expand | O(n) | 3Sum, Move Zeros |
| Sliding Window | Maintain window condition | O(n) | Longest Ones, Substring |
| Prefix Sum | sum[i] = sum[i-1] + a[i] | O(n) | Subarray Sum K |
| Kadane | Track local/global max | O(n) | Max Subarray |
| Sorting + Merge | sorted(), merge intervals | O(n log n) | Merge intervals |
| Binary Search | Divide array by halves | O(log n) | Rotated Search |
| Set Operations | Intersection / Missing | O(n) | Missing Number |
| Stack (for arrays) | Increasing/decreasing | O(n) | Trapping Rain Water |
Would you like me to now generate a Jupyter Notebook version
📘 Deep_Python_Lists_in_3_Days.ipynb
→ with markdown explanations + runnable code cells (Day 1–3 + cheat sheet) — so you can practice interactively like the strings version?