This repository tracks my daily LeetCode problem-solving streak. Every day I solve at least one problem, understand it deeply, and commit both the solution and a full breakdown README.
Each day's folder contains:
solution.py— clean, commented Python 3 solutionREADME.md— problem statement, intuition, dry run, and complexity analysis
| Metric | Count |
|---|---|
| Total Problems Solved | 47 |
| Easy | 11 |
| Medium | 25 |
| Hard | 11 |
| Current Streak | 47 days 🔥 |
| Language | Python 3 |
Linked List · Two Pointers · Fast & Slow Pointers · In-Place Reversal · Matrix · Union-Find · Monotonic Stack · BFS · DFS · Number Theory · SPF Sieve · Graph Components · Graph Reachability · Tree · LCA · Binary Lifting · Binary Tree · Tree Construction · Dynamic Programming · DP on DAG · Digit DP · Memoized DFS · Simulation · Greedy · Exchange Argument · Decoupling · Hash Table · Hash Set · Hash Map · Math · Geometry · Modular Arithmetic · Parity Counting · Binary Search · Rotated Sorted Array · Heap · Sparse Table · K-Largest from Sorted Lists · Difference Array · Prefix Sum · Prefix Difference · Range Updates · Bit Manipulation · Bitmask as Set · Trie · Suffix Trie · Bucket Clearing · Sliding Window · Segment Tree · Sorted Set · Digit Sum · Stable Partition · Three-Way Partition · Constraint Propagation · Reverse Index Mapping · Circular Scan · Sorted Arrays
Leetcode---Problem/
│
├── Day - 1/ # 61. Rotate List — circular link & break, O(n)/O(1)
├── Day - 2/ # 1861. Rotating the Box — gravity + 90° rotation, O(m×n)
├── Day - 3/ # 3660. Jump Game IX — component-max stack + Union-Find
├── Day - 4/ # 3629. Min Jumps via Prime Teleportation — BFS + SPF sieve + bucket clearing
├── Day - 5/ # 13. Roman to Integer — right-to-left compare, O(n)
├── Day - 6/ # 1914. Cyclically Rotating a Grid — layer → 1D rotation, O(m×n)
├── Day - 7/ # 2770. Max Number of Jumps to Reach Last Index — bottom-up DP, O(n²)
├── Day - 8/ # 1665. Min Initial Energy to Finish Tasks — greedy sort by surplus
├── Day - 9/ # 1674. Min Moves to Make Array Complementary — difference array, O(n+limit)
├── Day - 10/ # 2784. Check if Array is Good — max-pinned n + sorted compare
├── Day - 11/ # 153. Find Min in Rotated Sorted Array — binary search vs nums[right]
├── Day - 12/ # 154. Find Min in Rotated Sorted Array II — tie-shrink for duplicates
├── Day - 13/ # 1306. Jump Game III — BFS over ±arr[i], O(n)
├── Day - 14/ # 1345. Jump Game IV — BFS + value-bucket clearing, O(n)
├── Day - 15/ # 2540. Minimum Common Value — merge-style two-pointer, O(n+m)
├── Day - 16/ # 2657. Prefix Common Array — bitmask seen-sets + popcount, O(n)
├── Day - 17/ # 3043. Longest Common Prefix length — hash set of int prefixes via //10
├── Day - 18/ # 33. Search in Rotated Sorted Array — sorted-half detection, O(log n)
├── Day - 19/ # 1752. Check if Sorted and Rotated — circular drop counter, O(n)/O(1)
├── Day - 20/ # 1340. Jump Game V — memoized DFS on DAG, break-on-block, O(n·d)
├── Day - 21/ # 1871. Jump Game VII — BFS + sliding frontier pointer, O(n)
├── Day - 22/ # 3120. Count Special Characters I — two presence sets, O(n)
├── Day - 23/ # 3121. Count Special Characters II — last-lower vs first-upper maps, O(n)
├── Day - 24/ # 3093. Longest Common Suffix Queries — reverse-trie w/ per-node best, O(C+Q)
├── Day - 25/ # 3300. Min Element After Digit-Sum Replacement — streaming min, O(n)
├── Day - 26/ # 3161. Block Placement Queries — max segment tree + sorted set, O(n log M)
├── Day - 27/ # 2126. Destroying Asteroids — greedy sort ascending + sweep
├── Day - 28/ # 2144. Min Cost of Buying Candies — sort desc, skip every 3rd
├── Day - 29/ # 3633. Earliest Finish Time I — brute force pairs × both orders, O(n·m)
├── Day - 30/ # 3635. Earliest Finish Time II — decoupled best-completion + sweep, O(n+m)
├── Day - 31/ # 3751. Total Waviness I — brute-force digit peak/valley scan, O(R·D)
├── Day - 32/ # 3753. Total Waviness II — digit DP + f(num2)−f(num1−1), O(D)
├── Day - 33/ # 2574. Left and Right Sum Differences — total-minus-prefix, O(n)/O(1)
├── Day - 34/ # 2196. Create Binary Tree From Descriptions — value→node map, root = non-child
├── Day - 35/ # 2161. Partition Array by Pivot — stable 3-way bucket partition, O(n)
├── Day - 36/ # 3689. Max Total Subarray Value I — k × (globalMax − globalMin), O(n)
├── Day - 37/ # 3691. Max Total Subarray Value II — heap over sorted chains + sparse table
├── Day - 38/ # 3558. Assign Edge Weights I — BFS depth + 2^(d−1), O(n)
├── Day - 39/ # 3559. Assign Edge Weights II — binary-lifting LCA + 2^(d−1), O((n+q) log n)
├── Day - 40/ # 2130. Maximum Twin Sum — fast/slow + in-place reversal, O(n)/O(1)
├── Day - 41/ # 3838. Weighted Word Mapping — weight-sum → mod 26 → reverse map, O(n)
├── Day - 42/ # 2095. Delete the Middle Node — fast/slow + prev splice, O(n)/O(1)
├── Day - 43/ # 3612. Process String I — list-buffer simulation
├── Day - 44/ # 3614. Process String II — length tracking + reverse index mapping, O(n)
├── Day - 45/ # 1344. Angle Between Clock Hands — 0.5°/min hour creep, O(1)
├── Day - 46/ # 1732. Find the Highest Altitude — running prefix-sum max, O(n)/O(1)
├── Day - 47/ # 1840. Maximum Building Height — anchor compression + tent-peak, O(m log m)
│
│ (each folder contains solution.py + README.md)
│
└── README.md ← you are here
The trick: Connect the tail to the head to form a circle, walk to the new tail at index length − k − 1, then break the circle. Two passes, no extra memory.
The trick: The 90° clockwise rotation maps "rightward" to "downward". Apply gravity first (stones slide right per row via two-pointer), then result[j][m-1-i] = box[i][j]. Each obstacle resets the gravity pointer.
The bug fix: When components merge, a future small element must compare against the component's max, not the individual value. Maintain a stack of (root, component_max) — pop and union whenever component_max > nums[i].
The trick: Group indices by prime factors into buckets upfront; on first activation of value p, drain and clear its bucket so future activations do zero re-work. SPF sieve for O(log V) factorization.
The trick: Iterate right-to-left; if the current numeral is smaller than the one to its right, subtract it, else add. Single pass, O(1) space.
The trick: A 2D ring rotation is a 1D list rotation in disguise. Flatten each layer clockwise, shift by k % layer_size, write back. Layers are independent.
The trick: Asks for the max hops, so greedy fails. Bottom-up DP dp[j] = max(dp[i] + 1) over valid predecessors (|nums[j] − nums[i]| ≤ target); mark unreachable as −1.
The trick: Sort by minimum − actual descending (the surplus). High-surplus tasks have the highest entry cost, so do them first. Sum of forced top-ups = answer; provable by exchange argument.
The trick: Iterate over target sum T ∈ [2, 2·limit]. Each pair has 3 cost zones (0/1/2 moves) — apply as difference-array range updates, prefix-sum, take the min. Beats O(n·limit) by a factor of n.
The trick: n is forced to max(nums). Then two checks: len(nums) == n + 1, and sorted nums == [1,2,…,n−1,n,n].
The trick: Compare nums[mid] to nums[right] (not nums[left]). > → pivot right (left = mid+1); else right half sorted (right = mid, keeping mid). One rule, no no-rotation special case.
The trick: Duplicates add nums[mid] == nums[right] ambiguity. Fallback safely with right -= 1 (mid still holds an equivalent copy). Worst case O(n) on [3,3,3,3,1,3,3].
The trick: Graph reachability — each index has edges i ± arr[i]. BFS with visited, O(n); check arr[i] == 0 on dequeue.
The O(n²) trap: Same-value teleports fan out to n−1 neighbours. Fix: after the first dequeue of value v, clear buckets[v] — every same-value index is already enqueued. Each bucket iterated once → O(n).
The trick: Both arrays sorted → merge-style two-pointer. First match is the minimum; advance the smaller pointer otherwise. O(n+m), O(1).
The trick: A bitmask is a set in one integer. popcount(seen_A & seen_B) gives C[i] directly.
The trick: Decouple via a hash set of integer prefixes built with repeated // 10 (strips the last digit). Query each arr2 number longest-first, break on first hit. O((n+m)·D), D ≤ 9.
The trick: Exactly one break point → at any mid, one half is fully sorted. nums[left] <= nums[mid] identifies it; an O(1) range check on the sorted half picks the direction. One-pass O(log n).
The trick: At most one "drop" in a circular scan via (i+1) % n, which unifies the rotated and unrotated cases. Allow ≤ 1 drop.
The trick: Strictly-decreasing jumps ⇒ DAG ⇒ memoized DFS is safe. break on arr[k] >= arr[i] — a blocking index halts that whole direction, cutting per-state work O(d²) → O(d).
The trick: Reachability with windows [i+minJump, i+maxJump]. Naive BFS rescans overlaps → TLE. A sliding frontier pointer (BFS dequeues in non-decreasing order) keeps every index scanned at most once → O(n).
The trick: Only presence matters — two sets (lower_seen, upper_seen), count c where c ∈ lower and c.upper() ∈ upper. O(n), O(1).
The trick: The "all lowercase before first uppercase" rule collapses to last_lower[c] < first_upper[c.upper()] — the worst-case lowercase vs the lowest-bar uppercase.
The trick: Longest common suffix = longest common prefix of reverses. Build a reverse-trie; pre-store at every node the best container index (shortest, then earliest). Query walks reversed(query) and reads the deepest node's best. O(C+Q).
The trick: Stream each digit sum (% 10 / // 10) straight into min() — no array. O(n), O(1).
The trick: Obstacles carve gaps; store each gap at its right endpoint in a max segment tree (prefix-max auto-excludes gaps past x) plus a trailing partial x − last. Insertion splits a gap — one update decreases, so a Fenwick max won't do; a segment tree is required.
The trick: Mass only grows, so destroy the smallest reachable asteroid first — sort ascending and sweep. All orders absorb the same total, so the first unbeatable asteroid is a genuine fail. (Use 64-bit outside Python.)
The trick: The free candy is the cheapest of its triple. Maximize freebie value: sort descending and skip every index ≡ 2 (mod 3). Ascending would be both costlier and illegal.
The trick: Per pair, each order's finish is max(firstFinish, secondOpen) + secondDur (the max models waiting). With n,m ≤ 100, brute-force all pairs × both orders.
The trick: Larger input kills O(n·m). The two orders decouple: max(landFinish, waterOpen) + waterDur is monotone in landFinish, so the earliest-finishing land ride is best against every water ride. Precompute each category's best, sweep once → O(n+m).
The trick: num2 ≤ 10⁵ → brute-force every number, count strict interior peaks/valleys. Strictness drops 122, 100. O(R·D).
The trick: num2 ≤ 10¹⁵ → digit DP with f(num2) − f(num1 − 1). Carry the previous two digits; the distribution line wav += w + add * c spreads a peak's +1 across every number in the branch.
The trick: right = total − left − nums[i] falls out of the partition left + nums[i] + right = total. Carry a running left. O(n), O(1).
The trick: Index nodes by value, create lazily via get(); the root is the value never seen as a child. TreeNode — it shadows the judge's class.
The trick: A stable 3-way partition — swap-based Dutch National Flag breaks order. Bucket less/greater in scan order, count pivots, stitch less + [pivot]*c + greater. O(n).
The trick: Any subarray's value ≤ globalMax − globalMin, attained by the whole array. Repeats allowed → answer is k × (globalMax − globalMin).
The trick: "Distinct" forbids repeats → need the k largest values among ~10⁹ subarrays. For fixed l, value(l, r) is monotone in r, giving n sorted chains. K-largest-from-sorted-lists heap + sparse tables for O(1) range max/min → O((n+k) log n).
The trick: Only the path length d matters. Weight 1 flips parity, weight 2 doesn't, so odd cost ⇔ odd count of 1s = 2^(d−1) (first-edge flip bijection). BFS for d.
The trick: Same 2^(d−1) count, but per-query path lengths via d = depth[u] + depth[v] − 2·depth[LCA]. Binary-lifting LCA → O(log n) per query.
The trick: Twins mirror across the middle. Find the middle (fast/slow), reverse the second half, then sum the two halves in lockstep. O(n)/O(1).
The trick: Sum letter weights → % 26 → reverse-alphabet map via chr(122 − r) ('z' − r), no lookup table. O(Σ lengths).
The trick: Fast/slow finds the ⌊n/2⌋ node in one pass; a trailing prev splices it out. Guard the single-node case. O(n)/O(1).
The trick: Pure simulation on a list buffer — append / pop (guarded) / result += result / reverse(). |s| ≤ 20 keeps doublings tiny.
The trick: # doubling blows the length to 10¹⁵ — unbuildable. Track lengths forward, then walk the queried index k backward through each op (letter / * / #: k −= L / %: k = L−1−k) until it hits the source letter. O(n).
The trick: Minute hand 6°/min; hour hand 30°/hr + 0.5°/min (the minute creep is the whole catch — 3:30 → 105°, not 90°). hour % 12, then min(diff, 360 − diff).
The trick: Altitudes are a prefix sum of gain; the answer is the max prefix sum with 0 (the start) seeded as a candidate. O(n)/O(1).
The trick: n ≤ 10⁹ → work with O(m) anchors (restrictions + [1,0] + [n,n−1]). Propagate the ±1 rule forward and backward to get each anchor's true max, then the tent peak between adjacent anchors is ⌊(lh + rh + dist) / 2⌋. Complexity is n-independent.
- LeetCode: user9694nN
Building consistency, one problem at a time.