Publié · en amélioration
Guide Stratégie pour les entretiens de codage · 2/6
Ce chapitre n'est disponible qu'en anglais pour le moment.
If you start typing as soon as you hear the problem, you tend to discover too late that you misread a requirement or missed a better approach. This chapter applies a six-step procedure to a single example: clarify, work through examples, brute force, optimize, code, test.
The example problem: "Given an array nums of positive integers and a value target, return the length of the shortest contiguous subarray whose sum is at least target. If there is no such subarray, return 0."
Restate the problem in your own words and ask about anything ambiguous. The answers often decide which algorithm you can use.
O(n²) is risky.Assume the answers are: all positive, n up to 100,000, length only.
Do not rely only on the examples you are given. Build a few small ones yourself and compute the expected results by hand: one typical case plus two or three edge cases is plenty.
| nums | target | expected | why |
|---|---|---|---|
[3, 1, 2, 4, 1] | 6 | 2 | [2, 4] sums to 6 |
[1, 1, 1] | 5 | 0 | even the whole array sums to 3 |
[7] | 7 | 1 | a single element is enough |
[] | 1 | 0 | empty array |
Describe the simplest solution first. For each start index, extend to the right and record the length as soon as the sum reaches the target. That is O(n²) time. Even if you do not write it out, stating it along with its complexity gives you a baseline to improve on, and the function doubles as a reference answer for testing later.
def shortest_at_least_brute(nums: list[int], target: int) -> int:
best = 0
for start in range(len(nums)):
total = 0
for end in range(start, len(nums)):
total += nums[end]
if total >= target:
length = end - start + 1
if best == 0 or length < best:
best = length
break # extending further only makes it longer
return bestLook for repeated work in the brute force. Every time the start index moves, the sum is rebuilt from scratch. Because all values are positive, two facts hold:
So you can grow the right end one step at a time, and once the sum reaches the target, pull the left end in for as long as the condition still holds, updating the shortest length as you go. This is a variable-size sliding window. Each pointer moves at most n times, so the total is O(n). Say this out loud and get the interviewer's agreement before you start coding.
Tracing nums = [3, 1, 2, 4, 1] with target = 6:
| right | added | window (after adding) | sum | shrinking step | best |
|---|---|---|---|---|---|
| 0 | 3 | [3] | 3 | none | none |
| 1 | 1 | [3, 1] | 4 | none | none |
| 2 | 2 | [3, 1, 2] | 6 | record 3, drop 3, sum 3 | 3 |
| 3 | 4 | [1, 2, 4] | 7 | record 3, drop 1, sum 6, record 2, drop 2, sum 4 | 2 |
| 4 | 1 | [4, 1] | 5 | none | 2 |
Write the code you just described and briefly narrate why each line is there. Name variables after their roles: left, right, total.
def shortest_at_least(nums: list[int], target: int) -> int:
left = 0
total = 0
best = float("inf")
for right, value in enumerate(nums):
total += value
while total >= target: # shrink while the condition holds
best = min(best, right - left + 1)
total -= nums[left]
left += 1
return 0 if best == float("inf") else int(best)Finishing the code is not the end. Trace the examples from step 2 line by line and check the edge cases. If time allows, mention that you would compare against the brute force on random inputs; interviewers notice that.
cases = [
([3, 1, 2, 4, 1], 6, 2),
([1, 1, 1], 5, 0),
([7], 7, 1),
([], 1, 0),
]
for nums, target, expected in cases:
assert shortest_at_least(nums, target) == expected
assert shortest_at_least_brute(nums, target) == expected
print("all tests passed")| Phase | Suggested time | Common slip |
|---|---|---|
| Clarify and examples | 5 min | Moving on without asking about edge cases |
| Brute force and optimization | 10 min | Jumping into code without stating the idea |
| Coding | 15 to 20 min | Typing in silence |
| Testing and polish | 5 to 10 min | Ending with "I think it works" instead of tracing |
The six steps are less a ritual than a set of guard rails. Clarifying fixes the constraints and therefore the algorithm, the brute force becomes both a baseline and a testing tool, and agreeing on the optimization before coding saves rewrites. The next chapter implements the most common patterns in real code.
0 commentaire
Se connecter · Connectez-vous pour laisser un commentaire.
Soyez le premier à commenter.