惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
爱范儿
爱范儿
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 叶小钗
Last Week in AI
Last Week in AI
博客园 - 三生石上(FineUI控件)
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
月光博客
月光博客
大猫的无限游戏
大猫的无限游戏
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - Franky
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 司徒正美
罗磊的独立博客
博客园 - 聂微东
T
Troy Hunt's Blog
美团技术团队
IT之家
IT之家
A
Arctic Wolf
腾讯CDC
雷峰网
雷峰网
SecWiki News
SecWiki News
博客园_首页
L
LINUX DO - 最新话题
Cloudbric
Cloudbric
量子位
N
News and Events Feed by Topic
小众软件
小众软件
C
CXSECURITY Database RSS Feed - CXSecurity.com
Cyberwarzone
Cyberwarzone
J
Java Code Geeks
V
V2EX
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Latest news
Latest news
Webroot Blog
Webroot Blog
F
Fortinet All Blogs
P
Privacy International News Feed
NISL@THU
NISL@THU
Google Online Security Blog
Google Online Security Blog
WordPress大学
WordPress大学
PCI Perspectives
PCI Perspectives
GbyAI
GbyAI
宝玉的分享
宝玉的分享
阮一峰的网络日志
阮一峰的网络日志
S
Secure Thoughts
Simon Willison's Weblog
Simon Willison's Weblog
P
Palo Alto Networks Blog
V
Visual Studio Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Time and Space Complexity Fundamentals
Subrata Kuma · 2026-05-08 · via DEV Community

"It's not enough to write code that works. Great engineers write code that works **well."


Why Does This Even Matter?

Imagine you're building a contact search feature for a messaging app. You write the code, it works perfectly — on your laptop with 50 test contacts.

Then the app launches. Users have 10,000 contacts. Search slows down. You get 50,000 users. The app crashes under load. The CEO is furious.

The code was correct, but it wasn't efficient.

This is exactly the problem that Time and Space Complexity helps us reason about — before we ship to a million users.

Think of it like planning a road trip:

  • Time Complexity = How long will the journey take?
  • Space Complexity = How much luggage space do I need?

Both matter. A trip that takes 2 hours is great. But if your car is so packed you can't breathe, that's a different problem.

[Image: A humorous split-panel — left: happy driver with small suitcase, 2-hour clock; right: same car, same clock, comically overloaded with luggage]

💡 Key Insight: Complexity analysis lets you predict how your code will behave as the input grows — without having to test it at every possible scale.


What is Time Complexity?

Time complexity is a measure of how the number of operations your algorithm performs grows as the input size grows.

Notice: we said operations, not seconds. That's intentional.

Why not seconds? Because:

  • A slow computer might take 5 seconds; a fast computer might take 0.1 seconds — for the same algorithm
  • We want to describe the algorithm itself, independent of hardware

So instead of measuring time directly, we count how many steps the algorithm takes relative to the size of the input.

[Image: Three panels — old slow computer (5s), modern laptop (0.1s), same algorithm badge between them; third panel shows step counter growing with input]

Real World Example: Finding a Product in a Store

Imagine a grocery store.

[Image: Bird's-eye grocery store — three color-coded shopper paths showing O(1), O(n), O(log n)]

Scenario A — Constant Time: You want to grab milk. You know it's always in Aisle 3, second shelf. No matter how big the store gets — 10 aisles or 100 aisles — you walk straight to it.

Scenario B — Linear Time: You're looking for a discontinued item. You have to walk down every single aisle, checking every shelf, until you find it. The bigger the store, the longer it takes.

Scenario C — Logarithmic Time: The store manager arranges items alphabetically. You start in the middle, check if your item comes before or after, eliminate half the store, repeat. Much faster!

Same goal (find the product). Very different strategies. Very different performance as the store scales.


What is Space Complexity?

Space complexity is a measure of how much extra memory your algorithm needs as the input size grows.

"Extra memory" means memory in addition to the input itself — things like variables you declare, new arrays you create, or the call stack when you use recursion.

Real World Example: Packing for a Trip

[Image: Two columns — O(1): same small suitcase regardless of 1-day or 30-day trip; O(n): suitcase grows comically large for 30 days]

Scenario A — Constant Space: No matter how many days you're going (1 day or 30 days), you only bring one universal outfit. The number of days doesn't change how much you pack.

Scenario B — Linear Space: For every day of the trip, you pack a fresh outfit. 7 days = 7 outfits. 30 days = 30 outfits. The luggage grows proportionally.

The goal is the same (be prepared for the trip), but the approach determines how much space you need.


Big O Notation — The Universal Language

Programmers across the world use Big O Notation to communicate complexity. It's a standardized, mathematical way to describe the worst-case growth rate of an algorithm.

How to Read It

[Image: Visual reference card — 6 Big O notations, color-coded green to red, with pronunciation, meaning, and mini growth curve per row]

Notation Pronunciation Meaning
O(1) "O of 1" Constant — always the same number of steps
O(log n) "O of log n" Grows very slowly as input grows
O(n) "O of n" Grows linearly with input
O(n log n) "O of n log n" Slightly worse than linear
O(n²) "O of n squared" Grows quadratically — gets bad fast
O(2ⁿ) "O of 2 to the n" Grows exponentially — dangerous

The n represents the size of your input. It could be the number of items in a list, characters in a string, or rows in a database table.

The "Drop the Constants" Rule

When writing Big O, we always simplify:

  • O(2n)O(n) (we drop the constant 2)
  • O(n + 100)O(n) (we drop the +100)
  • O(n² + n)O(n²) (we keep only the dominant term)

Why? Because Big O describes behavior at massive scale. When n = 1,000,000, the difference between n and 2n is irrelevant compared to the difference between n and .

💡 If your commute is 2 hours vs. 4 hours, that's meaningful. But if someone's commute is 2 hours vs. someone else's 200 hours — the constant factor becomes insignificant in comparison.


Common Complexities, Explained Simply

O(1) — Constant Time

No matter how big the input is, it always takes the same number of steps.

Real World: ATM PIN Check

[Image: ATM with golden direct-line to one highlighted account, large database crossed out on the side, two counters showing "100 customers → Instant" and "100M customers → Still Instant"]

When you enter your PIN at an ATM, it checks your account's PIN directly. It doesn't loop through every customer's PIN in the bank's database. The check is instant regardless of whether the bank has 100 customers or 100 million.

// Get the first item from an array
function getFirstItem(arr) {
  return arr[0]; // Always exactly 1 operation
}

// Check if a number is even
function isEven(num) {
  return num % 2 === 0; // Always exactly 1 operation
}

Enter fullscreen mode Exit fullscreen mode

No loops. No conditions that grow with input. Same work every time.

When you see it: Direct array access by index, hash map lookups, simple math operations.


O(log n) — Logarithmic Time

Each step cuts the problem in half. The input can grow enormously, but the steps barely increase.

Real World: Dictionary Lookup

[Image: Three-step left-to-right story — dictionary opened at middle ("landed on G"), right half eliminated, opened again ("landed on R"), left eliminated, finally "MANGO ✅" found; dictionaries visually shrink across steps]

When you look up "Mango" in a physical dictionary, you don't start from page 1. You open roughly the middle, check if "M" comes before or after, flip to the appropriate half, repeat. A 500-page dictionary and a 5000-page dictionary don't take 10x longer — the number of flips barely changes.

This is called Binary Search, and it's the classic example of O(log n).

function binarySearch(sortedArr, target) {
  let left = 0;
  let right = sortedArr.length - 1;

  while (left <= right) {
    let mid = Math.floor((left + right) / 2);

    if (sortedArr[mid] === target) return mid;        // Found it!
    else if (sortedArr[mid] < target) left = mid + 1; // Go right
    else right = mid - 1;                              // Go left
  }

  return -1; // Not found
}

Enter fullscreen mode Exit fullscreen mode

How Slow Does It Grow?

Input Size (n) Steps (log₂ n)
8 3
1,024 10
1,000,000 ~20
1,000,000,000 ~30

One billion items — only 30 steps. That's the power of O(log n).

When you see it: Binary search, tree traversals, database indexes.


O(n) — Linear Time

The number of steps grows directly in proportion to the input size.

Real World: Finding a Name in an Unsorted List

[Image: Party guest list scroll — finger scanning name by name with ✗ marks, "Priya" highlighted but not yet reached; side panels show short scroll (100 guests) vs comically long scroll (1000 guests)]

Imagine you have a printed guest list for a party, but it's not sorted. You're looking for "Priya". You have to check each name, one by one, from top to bottom — until you find it or reach the end. 100 guests = up to 100 checks. 1000 guests = up to 1000 checks.

// Find an item in an unsorted array
function findItem(arr, target) {
  for (let i = 0; i < arr.length; i++) { // Loop runs n times
    if (arr[i] === target) return i;
  }
  return -1;
}

// Calculate the sum of all numbers
function sumAll(arr) {
  let total = 0;
  for (let num of arr) { // Visits every element once
    total += num;
  }
  return total;
}

Enter fullscreen mode Exit fullscreen mode

One loop that touches each element once = O(n).

When you see it: Simple loops over arrays, searching unsorted data, reading a file line by line.


O(n log n) — Linearithmic Time

Slightly worse than linear, but much better than quadratic. This is the complexity of most efficient sorting algorithms.

Real World: Sorting a Deck of Cards (Merge Sort Style)

[Image: Top-to-bottom flowchart — deck splits into halves (blue phase, "log n"), keeps splitting until tiny sorted piles, then merges back up (orange phase, "n"), final sorted deck at bottom glowing green]

Imagine sorting a deck of 52 cards using an efficient strategy:

  1. Split the deck into two halves
  2. Sort each half (recursively split again and again)
  3. Merge the sorted halves back together

The splitting is the log n part. Doing it across all n elements is the n part. Together: O(n log n).

function mergeSort(arr) {
  if (arr.length <= 1) return arr;

  const mid = Math.floor(arr.length / 2);
  const left = mergeSort(arr.slice(0, mid));  // log n levels of splitting
  const right = mergeSort(arr.slice(mid));

  return merge(left, right); // n work at each level
}

function merge(left, right) {
  const result = [];
  let i = 0, j = 0;

  while (i < left.length && j < right.length) {
    if (left[i] <= right[j]) result.push(left[i++]);
    else result.push(right[j++]);
  }

  return [...result, ...left.slice(i), ...right.slice(j)];
}

Enter fullscreen mode Exit fullscreen mode

When you see it: Merge sort, heap sort, most built-in Array.sort() implementations.


O(n²) — Quadratic Time

For every element, you do work for every other element. Performance degrades rapidly.

Real World: Introducing Everyone at a Party

[Image: Four panels left to right — 5 people (clean lines, calm), 10 people (busier), 100 people (dense web), 1000 people (solid dark mass ⚠️); color shifts green → red across panels]

At a party, if every person must shake hands with every other person:

  • 5 people = 10 handshakes
  • 10 people = 45 handshakes
  • 100 people = 4,950 handshakes
  • 1,000 people = 499,500 handshakes

Double the people, quadruple the work (roughly).

// Bubble Sort — the classic O(n²) algorithm
function bubbleSort(arr) {
  for (let i = 0; i < arr.length; i++) {        // Outer loop: n times
    for (let j = 0; j < arr.length - i; j++) {  // Inner loop: n times
      if (arr[j] > arr[j + 1]) {
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
      }
    }
  }
  return arr;
}

Enter fullscreen mode Exit fullscreen mode

⚠️ Warning Sign: A nested loop where both levels iterate over the input is almost always O(n²). Fine for small inputs — dangerous at scale.

When you see it: Bubble sort, selection sort, naive duplicate-finding, comparing every pair.


O(2ⁿ) — Exponential Time

Every new element doubles the work. This grows so fast it becomes unusable for even moderate inputs.

Real World: Brute-Force Password Cracking

[Image: Three stacked panels — Panel 1: confident robot, 10-char lock, "1,024 tries, cracked in seconds"; Panel 2: sweating robot, 30-char lock, "1 billion tries, 2% done"; Panel 3: smoking broken robot, 50-char lock, "1 quadrillion+, 0.000001% done ⚠️"; exponential curve annotated on the right]

A password with n characters, each being 0 or 1 (binary), has 2ⁿ possible combinations:

  • 10 characters = 1,024 tries
  • 30 characters = 1,073,741,824 tries
  • 50 characters = over 1 quadrillion tries

This is why longer passwords are exponentially safer.

// Naive recursive Fibonacci (the classic bad example)
function fibonacci(n) {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2); // Two recursive calls each time
}

Enter fullscreen mode Exit fullscreen mode

For fibonacci(50), this makes over 2 trillion function calls. Your computer will appear to freeze.

💡 Fix: Use memoization or dynamic programming to bring this down to O(n).

When you see it: Naive recursion without memoization, generating all subsets/combinations.


The Complexity Ladder — Visual Summary

From best to worst:

O(1) < O(log n) < O(n) < O(n log n) < O(n²) < O(2ⁿ)
FAST ◄─────────────────────────────────────────► SLOW

Enter fullscreen mode Exit fullscreen mode

A quick gut-check reference:

Complexity Name Feeling at Scale
O(1) Constant ✅ Always instant
O(log n) Logarithmic ✅ Barely grows
O(n) Linear 🟡 Manageable
O(n log n) Linearithmic 🟡 Acceptable
O(n²) Quadratic 🔴 Gets bad fast
O(2ⁿ) Exponential 🔴 Avoid at all costs

Best, Worst, and Average Case

Big O usually describes the worst case, but algorithms can behave differently depending on the input.

Real World: Security Check at an Airport

[Image: Three conveyor belts stacked vertically — suspicious red bag moves from position 1 (best), position 5 (average), position 10 (worst); scanned bags marked ✓, unscanned grayed out; mini bar chart on right showing 1 vs 5 vs 10 scans]

  • Best Case: The first bag scanned is the suspicious one → done immediately → O(1)
  • Average Case: The suspicious bag is somewhere in the middle → about half scanned
  • Worst Case: The suspicious bag is the very last one → every bag is scanned → O(n)
function findTarget(arr, target) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === target) return i; // Found it — stop early!
  }
  return -1;
}

Enter fullscreen mode Exit fullscreen mode

Case Scenario Complexity
Best Target is the first element O(1)
Average Target is somewhere in the middle O(n/2) → O(n)
Worst Target is the last element or missing O(n)

💡 When people say an algorithm is "O(n)", they typically mean the worst case. That's the safe, conservative estimate you plan around.


Space Complexity Deep Dive

Space complexity counts the extra memory allocated by your algorithm, not the input itself.

O(1) Space — Constant

function sumArray(arr) {
  let total = 0; // Only 1 extra variable, regardless of arr's size
  for (let num of arr) {
    total += num;
  }
  return total;
}

Enter fullscreen mode Exit fullscreen mode

No matter if arr has 10 or 10 million elements — we only ever create one extra variable (total).

O(n) Space — Linear

function doubleAll(arr) {
  const result = []; // New array grows with input
  for (let num of arr) {
    result.push(num * 2);
  }
  return result;
}

Enter fullscreen mode Exit fullscreen mode

If arr has 1000 elements, result also has 1000 elements. Space grows linearly.

O(n) Space — Recursion Stack

function countdown(n) {
  if (n <= 0) return;
  console.log(n);
  countdown(n - 1); // Each call sits on the call stack
}

Enter fullscreen mode Exit fullscreen mode

Calling countdown(1000) creates 1000 stack frames. The call stack is memory too!


Time vs Space — The Trade-off

Often, you can make code faster by using more memory, or use less memory but run slower. This is one of the most classic trade-offs in computer science.

Real World: Memorizing vs. Recalculating

Without memorization: Every time someone asks "What's the capital of France?", you think deeply for 5 seconds.

With memorization: You memorized the answer once, and recall it instantly — but it occupies a slot in your brain.

In code, this is called memoization or caching:

// WITHOUT memoization — O(2ⁿ) time, O(n) space
function fib(n) {
  if (n <= 1) return n;
  return fib(n - 1) + fib(n - 2);
}

// WITH memoization — O(n) time, O(n) space
function fibMemo(n, memo = {}) {
  if (n in memo) return memo[n]; // Use cached result
  if (n <= 1) return n;
  memo[n] = fibMemo(n - 1, memo) + fibMemo(n - 2, memo);
  return memo[n];
}

Enter fullscreen mode Exit fullscreen mode

We used more space (memo object) to dramatically reduce time. That's the trade-off in action.

💡 There's no universal right answer. Sometimes you need speed (real-time systems). Sometimes you need memory efficiency (mobile apps, embedded devices). Context decides.


Common Mistakes Beginners Make

❌ Mistake 1: Assuming "It Works" Means "It's Good"

// Works perfectly for 100 users. Collapses for 100,000.
function findDuplicates(users) {
  for (let i = 0; i < users.length; i++)
    for (let j = 0; j < users.length; j++)
      if (i !== j && users[i].email === users[j].email) // O(n²)
        console.log("Duplicate:", users[i].email);
}

Enter fullscreen mode Exit fullscreen mode

Fix: Use a Set or Map for O(n) duplicate detection.


❌ Mistake 2: Calling Expensive Operations Inside Loops

// O(n²) disguised as O(n)
for (let i = 0; i < arr.length; i++) {
  if (arr.includes(arr[i] * 2)) { // .includes() is O(n)!
    console.log("Found double!");
  }
}

Enter fullscreen mode Exit fullscreen mode

Fix: Convert arr to a Set before the loop. Set.has() is O(1).


❌ Mistake 3: Forgetting the Call Stack in Recursion

// Space complexity is O(n) due to recursion depth — not O(1)!
function factorial(n) {
  if (n === 1) return 1;
  return n * factorial(n - 1); // n stack frames in memory
}

Enter fullscreen mode Exit fullscreen mode


❌ Mistake 4: Over-Optimizing Too Early

Writing complex O(log n) code for a dataset that will never exceed 100 items is wasted effort. As Donald Knuth famously said:

"Premature optimization is the root of all evil."

Write clean, correct code first. Profile it. Then optimize if needed.


Chapter Summary

Concept What It Measures Analogy
Time Complexity How steps grow with input How long a road trip takes
Space Complexity How memory grows with input How much luggage you pack
Big O Notation Worst-case growth rate Speed limit of the algorithm
O(1) Constant — doesn't grow ATM PIN check
O(log n) Halves problem each step Dictionary lookup
O(n) Grows linearly Unsorted list search
O(n log n) Slightly worse than linear Merge sort
O(n²) Grows quadratically Handshakes at a party
O(2ⁿ) Doubles each step Password brute force

The Golden Rules

  1. Drop constants — O(3n) is just O(n)
  2. Keep the dominant term — O(n² + n) is just O(n²)
  3. Nested loops multiply — O(n) inside O(n) = O(n²)
  4. Sequential blocks add — O(n) + O(n) = O(n), not O(n²)
  5. Always think about scale — What happens when n = 1,000,000?

Practice Problems

Try to figure out the time and space complexity of each function before revealing the answer.

Problem 1:

function mystery1(n) {
  let result = 0;
  for (let i = 1; i <= n; i++) {
    result += i;
  }
  return result;
}
// Time: ? | Space: ?

Enter fullscreen mode Exit fullscreen mode

Answer: Time: O(n) — the loop runs n times. Space: O(1) — only one extra variable.


Problem 2:

function mystery2(arr) {
  const seen = new Set();
  for (let item of arr) {
    if (seen.has(item)) return true;
    seen.add(item);
  }
  return false;
}
// Time: ? | Space: ?

Enter fullscreen mode Exit fullscreen mode

Answer: Time: O(n) — single loop, Set operations are O(1). Space: O(n) — the Set can grow up to input size.


Problem 3:

function mystery3(matrix) {
  let sum = 0;
  for (let row of matrix) {
    for (let cell of row) {
      sum += cell;
    }
  }
  return sum;
}
// Assume matrix is n × n. Time: ? | Space: ?

Enter fullscreen mode Exit fullscreen mode

Answer: Time: O(n²) — every cell of an n × n matrix is visited. Space: O(1) — only one extra variable.


Want to Go Deeper?

Now that you understand what each complexity means, the natural next step is learning how to look at any piece of code and figure out its complexity yourself — step by step.

I've written a detailed guide covering:

  • ✅ A 5-step process to analyze any function
  • ✅ How to spot hidden complexity in built-in methods
  • ✅ How sequential blocks and nested blocks combine
  • ✅ The most common traps and how to avoid them

👉 Read: How to Analyze Your Own Code → rnm.subraatakumar.com


This article is part of the **Data Structures & Algorithms for Beginners* series on RN Mastery.*
Written by Subrata Kumar with ❤️ for developers who want to write code that scales.