Complete TLE Guide — From Zero to Optimized

Stop Getting
Time Limit Exceeded

A complete beginner-friendly guide: understand why TLE happens, how to count instructions, and exactly how to optimize your code step by step.

🖥️ The Machine
🔢 Count Instructions
⚡ Calculator
🔧 How to Optimize
📋 The Process
📊 Complexity Chart
📋 Cheat Sheet
🧠 Quiz
01 — The Judge Machine
What is TLE, really?

Before you can fix TLE, you need to understand what happens when you hit "Submit."

🖥️ The online judge runs on a ~1 GHz server

Every submission runs on a real server. That server executes roughly 1,000,000,000 (10⁹) simple instructions per second. If your code needs more instructions than that within the time limit (usually 1–2 seconds), the judge kills your process and says: Time Limit Exceeded.

10⁹
Instructions / second
1–2 s
Typical time limit
~10⁸
Safe operations target
💡
Why 10⁸ as the safe target if the machine does 10⁹? Because not all instructions are equal — memory access, branching, and function calls are slower than simple additions. A safe rule: keep total operations under 10⁸ and you'll almost never TLE.
02 — Counting Instructions
Every line of code has a cost

An "instruction" is any single action your CPU performs. Let's break down a real loop.

A simple loop — count the instructionsJavaScript
1for(let i = 0; i <= n; i++) { // ← 3 instructions per iteration 2 sum += arr[i]; // ← 2 instructions: read + add 3}
🔢 Init i=0 ×1 (once only)
🔍 Check i <= n ×n times
➕ Increment i++ ×n times
📖 Read arr[i] ×n times
⚙️ Add to sum ×n times
🧮
Total ≈ 5 × n instructions. If N = 10⁶, that's 5 million ops — perfectly fine. But if you add a nested loop inside, it becomes 5 × N × N = 5 × 10¹² — instant TLE!
📐 The Golden Formula
If your code has K instructions per element and input size is N:
Total Ops = N × K
Max safe N = 10⁸ ÷ K
K=1 → max N = 10⁸
K=10 → max N = 10⁷
K=100 → max N = 10⁶
K=1000 → max N = 10⁵
03 — Try It Yourself
⚡ TLE Calculator

Drag the sliders to instantly see if your code passes or TLEs — and get a tip.

Input size (N) 10⁶
Instructions / element (K) 100
Total Operations
—
Approx Time
—
Judge Limit
~10⁸–10⁹
—
04 — How to Optimize
Too many instructions? Here's how to cut them

If you have 100 instructions per element and N=10⁶, that's 10⁸ — borderline. Here are the exact techniques to reduce that count. Click each tab.

⚠️
The #1 cause of TLE: A loop inside a loop. For N=10⁶, that's 10¹² operations. Always ask yourself: "Can I remove the inner loop?"
Problem: Find if any two numbers sum to a target
❌ BEFORE — O(n²) — TLE for N > 10⁴
Brute force: check every pairJS
1for(let i=0; i<n; i++) { // outer loop 2 for(let j=i+1; j<n; j++) { // inner loop 3 if(arr[i]+arr[j]===target) 4 return true; 5 } 6}
💀 N=10⁶: 10¹² ops → takes hours
✅ AFTER — O(n) — Using a Set
Smart: store & check in 1 passJS
1const seen = new Set(); 2for(let x of arr) { 3 // O(1) lookup — not O(n)! 4 if(seen.has(target-x)) return true; 5 seen.add(x); 6}
✅ N=10⁶: ~3×10⁶ ops → instant
🔑
Key idea: Instead of checking every pair (2 loops), store what you've seen in a Set. A Set lookup is O(1) — one step, not n steps. This turns n² into n.
🗂️
HashMaps save you when you're doing repeated lookups. Array search = O(n) every time. HashMap search = O(1) every time. That single change can convert O(n²) → O(n).
Problem: Count frequency of each element
❌ BEFORE — Hidden O(n²)
find() inside a loop = disasterJS
const result = []; 2for(let x of arr) { 3 let f = result.find(r=>r.v===x); 4 // find() scans whole array each time! 5 if(f) f.c++; 6 else result.push({v:x,c:1}); 7}
💀O(n²) — TLE for large N
✅ AFTER — O(n) with Map
map.get() is always O(1)JS
1const map = new Map(); 2for(let x of arr) { 3 // O(1) — no scanning! 4 map.set(x,(map.get(x)||0)+1); 5} 6return map;
✅O(n) — 2 ops per element
🔑
Rule of thumb: Whenever you write arr.find(), arr.includes(), or arr.indexOf() inside a loop — that's secretly O(n²). Replace with a Map or Set.
➕
Prefix Sum is a preprocessing trick. Spend O(n) once building it, then answer any "sum of a range" query in O(1) instead of O(n) each time. If you have many queries, this is a game-changer.
Problem: Answer Q queries — "what is the sum of arr[l..r]?"
❌ BEFORE — O(n) per query
Re-sum every time a query comesJS
function rangeSum(arr,l,r) { let sum=0; for(let i=l; i<=r; i++) sum+=arr[i]; 4 return sum; 5} // Q queries × n = n×Q total ops
💀 N=Q=10⁶:10¹² ops
✅ AFTER — O(n) build + O(1)/query
Build once, answer instantlyJS
const pre=[0]; for(let x of arr) pre.push(pre.at(-1)+x); // Any range sum now O(1)! function rangeSum(l,r) { return pre[r+1]-pre[l]; 5}
✅ N=Q=10⁶:2×10⁶ ops total
🔍 Visual: how it works
arr  = [3, 1, 4, 1, 5, 9]
pre  = [0, 3, 4, 8, 9, 14, 23]
sum(l=1,r=4) = pre[5]-pre[1] = 14-3 = 11 ✅ — 1 subtraction!
🔎
Binary Search cuts your search space in half every step. Linear search on 10⁶ elements = 10⁶ checks. Binary search = just ~20 checks. That's the power of logarithm.
Problem: Find a target value in a sorted array
❌ BEFORE — O(n)
Scan every elementJS
for(let i=0; i<arr.length; i++) { if(arr[i]===target) return i; 3} 4return -1;
💀 N=10⁶:up to 10⁶ checks
✅ AFTER — O(log n)
Halve the search space each stepJS
let [lo,hi]=[0,arr.length-1]; while(lo<=hi) { let mid=(lo+hi)>>1; // ÷2 if(arr[mid]===target) return mid; arr[mid]<target?lo=mid+1:hi=mid-1; 6}
✅ N=10⁶:only ~20 checks!
1,000,000 → 500,000 → 250,000 → 125,000 → ... → 1 (log₂(10⁶) ≈ 20 steps)
💾
Memoization = Don't compute the same thing twice. If a function is called with the same input, return the cached answer. This turns exponential recursion into linear time.
Problem: Compute Fibonacci(n)
❌ BEFORE — O(2ⁿ)
Plain recursion — recomputes everythingJS
function fib(n) { if(n<=1) return n; return fib(n-1)+fib(n-2); 4} // fib(50) calls itself ~2⁵⁰ times!
💀 fib(50):~10¹⁵ calls!
✅ AFTER — O(n) with cache
Store results, never repeat workJS
const cache={}; function fib(n) { if(n in cache) return cache[n]; if(n<=1) return n; return cache[n]=fib(n-1)+fib(n-2); 6}
✅ fib(50):just 50 calls!
🔑
Spot it: If your recursive function is ever called with the same arguments more than once, add a cache object. This is the foundation of Dynamic Programming.
👈👉
Two Pointers replaces a nested loop by keeping two indices that move intelligently. Both pointers together travel at most N steps total — giving O(n) instead of O(n²).
Problem: Find a pair in a sorted array that sums to target
❌ BEFORE — O(n²)
Try every pairJS
for(let i=0; i<n; i++) { for(let j=i+1; j<n; j++) { if(arr[i]+arr[j]===t) 4 return [i,j]; 5 } 6}
💀n²/2 comparisons
✅ AFTER — O(n) Two Pointers
Move pointers smartly inwardJS
let l=0, r=arr.length-1; while(l<r) { const s=arr[l]+arr[r]; if(s===target) return [l,r]; s<target?l++:r--; 6}
✅at most n total steps
🔑
When to use: Sorted array + looking for a pair or subarray. The left pointer only moves right, the right only moves left — together they can never take more than N steps.
05 — The Process
Step-by-step: constraint → algorithm → code

Follow these steps on every problem — before writing a single line of code.

1
📖 Read the constraint — find N
Look for 1 ≤ N ≤ ???. That number is your guide. Don't skip it!
// Example constraint:
"1 ≤ N ≤ 10⁶, 1 ≤ arr[i] ≤ 10⁹"
// → N is at most 1 million. This tells you everything.
2
🧮 Calculate the max allowed complexity
Divide 10⁸ by N to find max K (instructions per element), then map that to a Big-O complexity.
N=10⁸ → K=1  → O(n) only
N=10⁷ → K=10  → O(n) or tight O(n log n)
N=10⁶ → K=100 → O(n log n)
N=10⁴ → K=10⁴ → O(n²)
N=10³ → K=10⁵ → O(n³)
3
🧠 Pick the right algorithm / data structure
Need O(1) lookup?
→ HashMap / Set
Need O(log n) search?
→ Binary search / Heap
Range queries in O(1)?
→ Prefix Sum
Avoid recomputation?
→ Memoization / DP
4
✏️ Write & count your loop ops before submitting
Mentally count the instructions inside each loop. If you have a loop inside a loop, verify that n² × K fits within 10⁸.
⚠️
Hidden O(n) traps inside loops: str += char (use array.join), arr.splice(), arr.unshift(), arr.includes(), JSON.stringify() — all secretly O(n)!
5
🚀 Submit with confidence
If your math says it'll pass, it almost certainly will. If it still TLEs, check for hidden O(n) operations inside your loop, or unnecessary repeated work in your algorithm.
06 — Visual Complexity
N = 10⁶: which complexities survive?

Each bar shows total operations. Anything beyond the 10⁹ limit = TLE.

🟢 Green = safe  |  🟡 Yellow = borderline  |  🔴 Red = TLE

07 — Constraint Cheat Sheet
See constraint → pick algorithm instantly

👆 Click any row to see the math, a real example, and why it works.

Input NUse This ✅Avoid ❌Quick Tip
08 — Test Yourself
🧠 Quick Quiz

Can you pick the right approach just from the constraint?