Lessons
1 · Reality Check and Your Search Plan
2 · Building Credibility From Zero
- 06What Credibility Means for a Fresher: Proof of Work
- 07Choose and Build a Project That Mirrors Your Target Companies
- 08Ship It: Deploy, Document and Make Your GitHub Easy to Read
- 09External Proof: Open Source, Hackathons and Writing About Your Work
- 10Honest Numbers: Measuring and Quantifying Student Projects
3 · Resume and LinkedIn
4 · Finding Jobs Before the Crowd
5 · Applications and Referrals
6 · Online Assessments and DSA
7 · Company Research for Interviews
8 · Technical Interview Rounds
9 · Behavioral and HR Rounds
10 · Offers, Negotiation and Joining
Lesson 24 · Online Assessments and DSA
OA Strategy: Constraints, Time, Brute Force and Partial Scoring
Knowing algorithms is half of an online assessment. The other half is strategy: reading all problems first, using the constraints to tell you the complexity you need, capping time per problem, submitting a working brute force before optimising, collecting partial marks, and testing edge cases before the hidden tests do. Includes a stress-testing technique for practice, with a short program.
For
Freshers taking timed coding assessments who want to turn what they know into more marks.
Level
Before you start
Read The OA Landscape: Platforms, Formats, Proctoring and Rules (article 23). You should be able to write simple programs and know what time complexity means.
On this page
Key takeaways
- Read every problem before writing code. Start with the one you are most sure of, not necessarily the first.
- Constraints tell you the complexity you need: roughly, n up to 10^5 needs about O(n log n), n up to 10^6 about O(n), n up to 20 allows exponential search.
- Cap your time per problem, and always submit a working simpler solution before chasing the optimal one. Many platforms give marks per test case.
- Test the edge cases hidden tests love: smallest input, largest input, all equal, sorted, negative numbers, zero and no answer.
- In practice, check fast solutions against a slow, trusted one on random small inputs. It finds bugs that sample tests miss.
Two students with the same knowledge take the same 90-minute assessment with two problems. The first opens problem one, spends 70 minutes trying to find the optimal solution, gets close, and submits nothing that compiles. Problem two goes unread. Score: zero.
The second reads both problems, starts with the one she recognises, submits a working solution in 25 minutes, then writes a slow but correct solution to the harder one, which passes 6 of 10 test cases, and spends the last 15 minutes on edge cases. Score: well over half. Same knowledge, very different results. The difference is strategy, and strategy can be learned in a week.
What you will learn
#- A time plan for a multi-problem assessment.
- How to read a problem so you understand it before coding.
- How constraints tell you the complexity, and so the approach, you need.
- Why brute force first, and how partial scoring rewards it.
- An edge-case checklist, and stress testing for practice.
The time plan
#For a typical assessment with two or three problems in 60 to 120 minutes:
- Read everything first (about 5 minutes). Skim every problem: what it asks and its constraints. Problems are not always in order of difficulty.
- Start with your most confident problem. A quick, complete solution early lowers pressure for the rest.
- Set a time cap per problem. For two problems in 90 minutes, about 35 to 40 minutes each. When the cap arrives, submit your best working version and move on. You can return.
- Keep the last 10 minutes for testing edge cases and re-submitting, not for starting new code.
- Multiple-choice sections have their own timers on some platforms. Do not leave easy marks unanswered: if there is no negative marking, answer everything; if there is, skip only what you cannot narrow down.
Reading a problem properly
#Most wrong answers start with misreading. A three-step read:
- Read the examples first, then the statement. Work out by hand how each example input becomes its output. It often makes the statement clear.
- Name the output type. A count, a maximum or minimum, yes or no, an arrangement, a path? The type narrows the approach.
- Read the constraints last, carefully. They decide the complexity you need (next section), and they reveal edge cases: can numbers be negative? can the array be empty? can the answer exceed the range of a 32-bit integer?
Constraints tell you the complexity
#A rough rule of thumb: a typical judge can do somewhere around 10^7 to 10^8 simple operations per second in a fast language such as C++ or Java, and fewer in Python. So the size limit on the input tells you how fast your algorithm must be.
Largest n | Complexity that usually fits | Typical approaches |
|---|---|---|
up to about 10 | O(n!) | Try all permutations, backtracking |
up to about 20 | O(2^n) | Try all subsets, bitmask DP |
up to about 500 | O(n^3) | Triple loops, some DP |
up to about 5,000 | O(n^2) | Double loops, 2D DP |
up to about 10^5 to 2 × 10^5 | O(n log n) | Sorting, binary search, heaps, segment trees |
up to about 10^6 | O(n) | One pass: hashing, two pointers, sliding window, prefix sums |
up to 10^9 or more | O(log n) or O(1) | Binary search on the answer, maths |
These boundaries are approximate; the time limit, the language and the constant factor matter. But the habit is powerful: read the constraints before choosing an approach. If n is up to 2 × 10^5, an O(n^2) solution will time out on the large tests, so do not spend 30 minutes perfecting it unless you mean it as your brute force.
Brute force first
#Before trying the optimal solution, write the simplest correct one, even if it is slow. Three reasons:
- Partial marks. Many platforms score each test case separately. A slow but correct solution often passes the small tests: perhaps 30 to 60 per cent of the marks, depending on how the tests are designed.
- Understanding. Writing the brute force forces you to handle the input, output and edge cases correctly, which the optimal solution needs too.
- Checking. You can compare your optimal solution with it on small inputs.
Then, if time allows and you know the better approach, optimise. If you do not know it, use the remaining time on edge cases and on other problems.
Partial scoring
#When a platform awards marks per passed test case, think in tiers:
Tier | What you submit | When |
|---|---|---|
1 | A correct brute force | As soon as you have it |
2 | The brute force plus correct handling of edge cases (empty or single-element input, all equal, already sorted) | Next, it is quick |
3 | The optimised solution | Only if you know the approach and have the time |
Handling special cases explicitly, such as "if the array has one element, the answer is 0", is legitimate edge-case handling. It is different from printing memorised answers to particular test inputs, which is pointless and may be flagged.
Some platforms instead require all tests to pass, or weight hidden performance tests heavily (Codility, for example, separates correctness from performance in its scoring). Read the instructions; the brute-force-first habit still helps, because it gives you something correct to build on.
Edge cases hidden tests love
#Before submitting, test with the platform's custom input:
- The examples from the problem.
- The smallest valid input (n = 0 or 1, an empty string, a single character).
- The largest input you can construct, to check time.
- All elements equal.
- Already sorted, and reverse sorted.
- Negative numbers and zero, if allowed.
- A case where the answer is "none" or 0.
- Values near the limit, to check overflow.
This takes a few minutes and catches a large share of hidden-test failures.
Stress testing, for practice
#When you practise (not during a proctored test unless it is fully yours to use), there is a powerful habit: write a slow, obviously correct solution and a fast one, generate many small random inputs, and compare. The first mismatch shows you a failing input. Here is the technique for a simple problem: the largest sum of any k consecutive numbers.
# File: stress_test.py# Practice technique: check a fast solution against a slow, obviously correct one# on many small random inputs. Problem: the largest sum of any k consecutive numbers.import randomdef brute(nums, k): """O(n*k): try every window. Slow but easy to trust.""" return max(sum(nums[i:i + k]) for i in range(len(nums) - k + 1))def fast_buggy(nums, k): """O(n) sliding window with a bug: best starts at 0.""" window = sum(nums[:k]) best = 0 for i in range(k, len(nums)): window += nums[i] - nums[i - k] best = max(best, window) return bestdef fast(nums, k): """O(n) sliding window, fixed: best starts at the first window.""" window = sum(nums[:k]) best = window for i in range(k, len(nums)): window += nums[i] - nums[i - k] best = max(best, window) return bestdef stress(candidate, trials=500): random.seed(7) for _ in range(trials): n = random.randint(1, 8) k = random.randint(1, n) nums = [random.randint(-10, 10) for _ in range(n)] expected, got = brute(nums, k), candidate(nums, k) if expected != got: return f"mismatch for nums={nums}, k={k}: expected {expected}, got {got}" return f"all {trials} random tests passed"print("buggy:", stress(fast_buggy))print("fixed:", stress(fast))buggy: mismatch for nums=[2, 10, -9, -8, 7, -7], k=2: expected 12, got 1fixed: all 500 random tests passedThe buggy version passes many simple tests, but the stress test finds an input where it fails: the best window is the very first one (2 + 10 = 12), and best started at 0, so the first window was never counted. (Starting at 0 would also be wrong whenever every window sum is negative.) Small random inputs are used on purpose: when a mismatch appears, it is small enough to trace by hand.
The fixed seed makes the run repeatable, so the output above is the same every time.
Using AI after the test, not during it
#After an assessment, write down the problems from memory as well as you can (many candidates do this to learn; do not share them where the employer's terms forbid it). Then, in practice:
I took a coding assessment. Here is a problem as I remember it, my approach,and how far I got. Do not give me the full solution.1. Was my approach correct? If not, which pattern fits, and why do the constraints point to it?2. Which edge cases probably failed in the hidden tests?3. Give me one hint toward the optimal approach, then stop.[problem as you remember it, constraints, your code]Then solve it yourself. Article 25 builds this into a full practice system.
Common mistakes
#- Opening problem one and never reading problem two.
- Choosing an approach before reading the constraints.
- Chasing the optimal solution with nothing submitted.
- Forgetting overflow with large values.
- Submitting without testing edge cases.
- Spending the last minutes starting a new approach instead of testing.
Exercises
#Exercise 1
Constraints to complexity
#What complexity, and what kind of approach, do these constraints suggest? (a) n ≤ 2 × 10^5, find the number of pairs with a given sum; (b) n ≤ 18, choose a subset with the best score; (c) n ≤ 10^6, length of the longest substring with at most k distinct characters; (d) answer ≤ 10^18, find the smallest x such that a monotonic condition holds.
Exercise 2: Plan the time
#A 120-minute assessment has three problems: P1 is a familiar hashing problem, P2 is an unfamiliar graph problem with n ≤ 10^5, P3 is a string problem you half recognise. Write your time plan.
Exercise 3: Find the edge cases
#A function returns the length of the longest strictly increasing contiguous run in an array. List at least five edge-case inputs you would test, and the expected output for each.
Exercise 4: Stress test your own code
#Choose a problem you solved recently with an optimised approach. Write a brute force, a small random input generator and a comparison loop (in any language), and run at least 500 trials. Record whether it found a bug.
Show solutionHide solution
(a) About O(n log n) or O(n). O(n^2) pair checking is about 4 × 10^10 operations, far too many. Use a hash map of counts in one pass (O(n)), or sort and use two pointers (O(n log n)). Watch out: the number of pairs can exceed 32-bit range, so use a 64-bit counter.
(b) O(2^n) is fine: 2^18 is about 262,000 subsets. Try all subsets, or use bitmask DP if subsets interact.
(c) O(n): a sliding window with a hash map of character counts, expanding the right end and shrinking the left when the distinct count exceeds k.
(d) O(log(answer)) checks: binary search on the answer over the range up to 10^18, about 60 iterations, each checking the condition. Use 64-bit arithmetic and be careful with overflow in the check.
Exercise 2
Show solutionHide solution
- 0 to 5 minutes: read all three problems and their constraints.
- 5 to 30: P1 (familiar). Code, test edge cases, submit.
- 30 to 70: P3 (half recognised). Brute force first and submit, then try the pattern you half recognise.
- 70 to 105: P2 (unfamiliar graph). Model it as a graph, consider BFS or DFS (both fit 10^5 nodes in O(n + m)), and submit whatever correct version you can, even if it handles only small cases.
- 105 to 120: edge cases and re-submissions on all three; no new approaches.
Adjust once you start: if P1 takes 10 minutes, the extra time goes to P3 and P2.
Exercise 3
Show solutionHide solution
Input | Expected | Why |
|---|---|---|
| 0 | Empty input (if allowed by constraints) |
| 1 | Single element |
| 1 | All equal: strictly increasing runs have length 1 |
| 4 | Already sorted: the whole array |
| 1 | Reverse sorted |
| 3 | The longest run is at the end; a common bug is not updating the best after the loop |
| 4 | Negative numbers and zero |
The sixth case catches the most common bug in this problem: updating the best length only when a run breaks, so a run that reaches the end of the array is never counted.
Exercise 4
Show solutionHide solution
A good stress test:
- uses a brute force so simple you trust it (often nested loops);
- generates small inputs (sizes 0 to 8, values in a small range including negatives if allowed) so failures are easy to trace;
- uses a fixed seed so a failure can be reproduced;
- prints the first failing input with both outputs.
If it found a bug, write down which edge case it was and add that case to your personal checklist. If it found none after 500 trials, try a wider value range or larger sizes once.
Where to go next
#- Next: Pattern-First DSA Practice With AI as a Coach, Not a Crutch builds the problem-solving behind the strategy.
- For a step-by-step problem-solving method, see Problem Solving Fundamentals: From a Question to an Algorithm.
- For complexity in depth, see Time and Space Complexity Without the Confusion.
- Career
- Software Engineering
- #AI
- #coding interviews
- #DSA
- #freshers
- #interview preparation
- #job search
- #off-campus placement
- #online assessment
- #problem solving
Connected lessons
Linked from 2 guides
Other pages in the library that point here.
Keep reading
More in Career →Guide · Technology
The Interview Problem-Solving Workflow
Guide · Technology
Heaps and Priority Queues
Course · Technology
DSA From Zero to Job-Ready: A Practical Guide with Java

