Jump into concepts and practice - no test required
or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
▶
Steps
setup
Calculate net gas at each station
Compute net gas array where each element is gas[i] - cost[i]. This shows how much gas is gained or lost at each station.
💡 Net gas array simplifies the problem by focusing on surplus or deficit at each station.
Line:net = [gas[i] - cost[i] for i in range(n)]
💡 Net gas array reveals which stations add or consume gas, critical for checking circuit feasibility.
setup
Check total net gas sum
Sum all net gas values to verify if completing the circuit is possible at all.
💡 If total net gas is negative, no start station can complete the circuit.
Line:if sum(net) < 0:
return -1
💡 Total net gas sum >= 0 means a solution may exist.
setup
Initialize prefix sums array
Create prefix sums array of length 2*n+1 initialized with zeros to simulate circular traversal.
💡 Prefix sums allow quick calculation of net gas over any window.
Line:prefix = [0] * (2 * n + 1)
💡 Prefix sums prepare for efficient window sum queries.
fill_cells
Build prefix sums for circular net array (i=0)
Calculate prefix[1] = prefix[0] + net[0 % n], adding net at station 0.
💡 Each prefix sum accumulates net gas to enable quick window sum checks.
Line:prefix[i+1] = prefix[i] + net[i % n]
💡 Prefix sums grow by adding net gas values in circular order.
fill_cells
Build prefix sums for circular net array (i=1)
Calculate prefix[2] = prefix[1] + net[1 % n], adding net at station 1.
💡 Continuing prefix sums to cover twice the array length for circular wrap.
Line:prefix[i+1] = prefix[i] + net[i % n]
💡 Prefix sums reflect cumulative net gas over extended circular route.
fill_cells
Build prefix sums for circular net array (i=2)
Calculate prefix[3] = prefix[2] + net[2 % n], adding net at station 2.
💡 Prefix sums continue to accumulate net gas values circularly.
Line:prefix[i+1] = prefix[i] + net[i % n]
💡 Prefix sums enable O(1) window sum queries for any segment.
fill_cells
Build prefix sums for circular net array (i=3)
Calculate prefix[4] = prefix[3] + net[3 % n], adding net at station 3.
💡 Adding positive net gas at station 3 increases prefix sums.
Line:prefix[i+1] = prefix[i] + net[i % n]
💡 Positive net gas stations increase cumulative sums, critical for feasibility.
fill_cells
Build prefix sums for circular net array (i=4)
Calculate prefix[5] = prefix[4] + net[4 % n], adding net at station 4.
💡 Completing one full cycle of prefix sums for circular array.
Line:prefix[i+1] = prefix[i] + net[i % n]
💡 Prefix sums now cover one full cycle of net gas values.
fill_cells
Build prefix sums for circular net array (i=5)
Calculate prefix[6] = prefix[5] + net[5 % n], adding net at station 0 again for circular wrap.
💡 Extending prefix sums to twice the array length to simulate circularity.
Line:prefix[i+1] = prefix[i] + net[i % n]
💡 Prefix sums allow checking any window of length n in O(1).
fill_cells
Build prefix sums for circular net array (i=6)
Calculate prefix[7] = prefix[6] + net[6 % n], adding net at station 1 again.
💡 Continuing to fill prefix sums for full circular coverage.
Line:prefix[i+1] = prefix[i] + net[i % n]
💡 Prefix sums now fully represent two cycles of net gas.
fill_cells
Build prefix sums for circular net array (i=7)
Calculate prefix[8] = prefix[7] + net[7 % n], adding net at station 2 again.
💡 Filling prefix sums to cover all 2*n elements.
Line:prefix[i+1] = prefix[i] + net[i % n]
💡 Prefix sums allow quick sum checks for any window of length n.
fill_cells
Build prefix sums for circular net array (i=8)
Calculate prefix[9] = prefix[8] + net[8 % n], adding net at station 3 again.
💡 Completing prefix sums for the circular array twice over.
Line:prefix[i+1] = prefix[i] + net[i % n]
💡 Prefix sums now fully represent two cycles of net gas values.
fill_cells
Build prefix sums for circular net array (i=9)
Calculate prefix[10] = prefix[9] + net[9 % n], adding net at station 4 again.
💡 Final prefix sum completes the double-length prefix sums array.
Line:prefix[i+1] = prefix[i] + net[i % n]
💡 Prefix sums array is ready for sliding window sum queries.
compare
Check window sum for start index 0
Calculate prefix[0+n] - prefix[0] = prefix[5] - prefix[0] to check if sum of net gas over stations 0 to 4 is non-negative.
💡 Checking if starting at station 0 allows completing the circuit.
Line:if prefix[i+n] - prefix[i] >= 0:
return i
💡 Window sum check shows if the circuit can be completed starting at i.
compare
Check window sum for start index 1
Calculate prefix[1+n] - prefix[1] = prefix[6] - prefix[1] to check net gas sum for stations 1 to 0 (circular).
💡 Checking if starting at station 1 allows completing the circuit.
Line:if prefix[i+n] - prefix[i] >= 0:
return i
💡 Negative window sum means starting at 1 is not feasible.
compare
Check window sum for start index 2
Calculate prefix[2+n] - prefix[2] = prefix[7] - prefix[2] to check net gas sum for stations 2 to 1 (circular).
💡 Checking if starting at station 2 allows completing the circuit.
Line:if prefix[i+n] - prefix[i] >= 0:
return i
💡 Negative window sum means starting at 2 is not feasible.
compare
Check window sum for start index 3
Calculate prefix[3+n] - prefix[3] = prefix[8] - prefix[3] to check net gas sum for stations 3 to 2 (circular).
💡 Checking if starting at station 3 allows completing the circuit.
Line:if prefix[i+n] - prefix[i] >= 0:
return i
💡 Non-negative window sum means starting at 3 completes the circuit.
reconstruct
Return the valid start index
Return the start index 3 where the circuit can be completed successfully.
💡 Returning the answer completes the algorithm.
Line:return i
💡 The algorithm finds the minimal start index with non-negative net gas window.
def canCompleteCircuit(gas, cost):
n = len(gas) # STEP 1
net = [gas[i] - cost[i] for i in range(n)] # STEP 1
if sum(net) < 0: # STEP 2
return -1
prefix = [0] * (2 * n + 1) # STEP 3
for i in range(2 * n): # STEP 4-13
prefix[i+1] = prefix[i] + net[i % n]
for i in range(n): # STEP 14-17
if prefix[i+n] - prefix[i] >= 0:
return i # STEP 18
return -1
📊
Gas Station (Circular) - Watch the Algorithm Execute, Step by Step
Watching each step reveals how the greedy approach efficiently checks feasibility without simulating the entire trip repeatedly.
Step 1/18
·Active fill★Answer cell
record
-2
0
-2
1
-2
2
3
3
3
4
compare
-2
0
-2
1
-2
2
3
3
3
4
Result: 0
record
0
0
0
1
0
2
0
3
0
4
0
5
0
6
0
7
0
8
0
9
0
10
record
i
0
0
-2
1
0
2
0
3
0
4
0
5
0
6
0
7
0
8
0
9
0
10
record
0
0
i
-2
1
-4
2
0
3
0
4
0
5
0
6
0
7
0
8
0
9
0
10
record
0
0
-2
1
i
-4
2
-6
3
0
4
0
5
0
6
0
7
0
8
0
9
0
10
record
0
0
-2
1
-4
2
i
-6
3
-3
4
0
5
0
6
0
7
0
8
0
9
0
10
record
0
0
-2
1
-4
2
-6
3
i
-3
4
0
5
0
6
0
7
0
8
0
9
0
10
record
0
0
-2
1
-4
2
-6
3
-3
4
i
0
5
-2
6
0
7
0
8
0
9
0
10
record
0
0
-2
1
-4
2
-6
3
-3
4
0
5
i
-2
6
-4
7
0
8
0
9
0
10
record
0
0
-2
1
-4
2
-6
3
-3
4
0
5
-2
6
i
-4
7
-6
8
0
9
0
10
record
0
0
-2
1
-4
2
-6
3
-3
4
0
5
-2
6
-4
7
i
-6
8
-3
9
0
10
record
0
0
-2
1
-4
2
-6
3
-3
4
0
5
-2
6
-4
7
-6
8
i
-3
9
0
10
compare
i
0
0
-2
1
-4
2
-6
3
-3
4
0
5
-2
6
-4
7
-6
8
-3
9
0
10
compare
0
0
i
-2
1
-4
2
-6
3
-3
4
0
5
-2
6
-4
7
-6
8
-3
9
0
10
compare
0
0
-2
1
i
-4
2
-6
3
-3
4
0
5
-2
6
-4
7
-6
8
-3
9
0
10
compare
0
0
-2
1
-4
2
i
-6
3
-3
4
0
5
-2
6
-4
7
-6
8
-3
9
0
10
Result: 3
record
0
0
-2
1
-4
2
start
-6
3
-3
4
0
5
-2
6
-4
7
-6
8
-3
9
0
10
Result: 3
Key Takeaways
✓ The net gas array transforms the problem into finding a non-negative sum subarray in a circular array.
This insight is hard to see from code alone because it abstracts the problem into a simpler numeric form.
✓ Prefix sums allow O(1) queries for sums over any window, enabling efficient feasibility checks.
Visualizing prefix sums clarifies why the algorithm avoids repeated summations.
✓ Checking each start index with prefix sums reveals exactly where the circuit can be completed.
Seeing each comparison step shows why some start points fail and one succeeds.
Practice
(1/5)
1. You have a list of children each with a greed factor and a list of cookies each with a size. You want to assign cookies to children so that each child gets at most one cookie and the cookie size is at least the child's greed factor. Which algorithmic approach guarantees the maximum number of content children?
easy
A. Greedy algorithm by sorting greed factors and cookie sizes, then assigning smallest sufficient cookie to each child
B. Dynamic Programming to try all possible assignments and pick the best
C. Brute force nested loops checking every cookie for every child without sorting
D. Divide and Conquer by splitting children and cookies and merging results
Solution
Step 1: Understand problem constraints
Each child can get at most one cookie, and the cookie must satisfy the child's greed factor.
Step 2: Identify optimal approach
Sorting both greed and cookie arrays allows a greedy assignment from smallest greed to smallest sufficient cookie, ensuring maximum matches.
Final Answer:
Option A -> Option A
Quick Check:
Greedy sorting approach is classic for assignment problems [OK]
Hint: Sort both arrays and assign greedily [OK]
Common Mistakes:
Thinking brute force is needed for optimality
Assuming DP is required
Ignoring sorting leads to suboptimal matches
2. Consider the following Python code for forming the largest number from the list [3, 30, 34, 5]. What is the final returned string?
easy
A. 534330
B. 53430
C. 534303
D. 534330
Solution
Step 1: Convert numbers to strings: ['3', '30', '34', '5']
We compare pairs by concatenation: '5'+'34' vs '34'+'5' -> '534' > '345', so '5' before '34'. Similarly for others.
Step 2: Sort using custom comparator to get order: ['5', '34', '3', '30']
Concatenate to get '534330'. The check for leading zero is false since first is '5'.
Final Answer:
Option A -> Option A
Quick Check:
Concatenation order matches expected largest number [OK]
Hint: Compare concatenations 'a+b' and 'b+a' to order strings [OK]
Common Mistakes:
Off-by-one in sorting
Ignoring leading zero case
Misordering '30' and '3'
3. Consider the following Python function that calculates the minimum number of platforms needed. Given the input arrivals = [900, 940, 950] and departures = [910, 1200, 1120], what is the value of max_platforms after processing the second train (index 1)?
After first train: heap=[910], max_platforms=1
Second train arrival=940, heap top=910 ≤ 940, pop 910
Push 1200, heap=[1200], max_platforms=max(1,1)=1
Since question asks after second train, max_platforms=1
Final Answer:
Option B -> Option B
Quick Check:
Heap size after second train is 1, max_platforms updated to 1 [OK]
Hint: Heap pops departures ≤ arrival before push [OK]
Common Mistakes:
Not popping from heap before push
Confusing max_platforms update timing
Off-by-one in iteration
4. What is the time complexity of the optimal max heap approach to reorganize a string of length n with k unique characters?
medium
A. O(n²) because each character insertion may require scanning the entire string
B. O(n log k) because each of the n characters is pushed and popped from a heap of size k
C. O(k log n) because the heap operations depend on the string length
D. O(n) because each character is processed once without extra overhead
Solution
Step 1: Identify heap operations per character
Each character is pushed and popped at most once per occurrence, total n operations.
Step 2: Analyze heap size and operation cost
Heap size is at most k (unique chars), each push/pop is O(log k), so total O(n log k).
Final Answer:
Option B -> Option B
Quick Check:
Heap operations dominate, not scanning entire string [OK]
Hint: Heap ops cost O(log k) per character [OK]
Common Mistakes:
Confusing n and k in complexity
Assuming linear time without heap cost
Mistaking quadratic due to nested loops
5. Suppose the problem is modified: instead of finding the largest monotone increasing digits number ≤ n, you want the largest monotone increasing digits number ≤ n that can reuse digits any number of times (digits can be repeated arbitrarily). Which approach correctly adapts the algorithm?
hard
A. Use the original greedy algorithm but allow digits after marker to be any digit less than or equal to the digit at marker-1
B. Sort the digits of n and build the largest monotone number by repeating the smallest digit as many times as needed
C. Use a backtracking approach to generate all monotone numbers with digits ≤ those in n, allowing reuse, and pick the largest ≤ n
D. Modify the greedy algorithm to decrement digits and set trailing digits to the digit at marker-1 instead of 9
Solution
Step 1: Understand digit reuse changes problem nature
Allowing reuse means digits can be repeated arbitrarily, so greedy digit decrement and trailing 9 assignment no longer guarantee largest monotone number ≤ n.
Step 2: Backtracking enumerates all monotone numbers with digit reuse
Backtracking can generate all monotone numbers with digits ≤ those in n, allowing reuse, then pick the largest ≤ n.
Step 3: Other options fail to handle reuse or produce incorrect numbers
Sorting digits or modifying trailing digits to marker-1 digit does not guarantee largest monotone number with reuse.
Final Answer:
Option C -> Option C
Quick Check:
Backtracking correctly handles reuse and monotonicity constraints [OK]
Hint: Digit reuse breaks greedy; backtracking needed for correctness [OK]
Common Mistakes:
Trying to adapt greedy without full enumeration
Assuming trailing digits can be set to 9 or marker digit