A data structure is a way of organizing and storing data so that it can be accessed and modified efficiently.
Why Use Data Structures? Because they help in:
Real-life Example: Think of a data structure like a bookshelf. You can organize books (data) in rows, by category (array, stack, etc.), so it’s easier to find and use them quickly.
An algorithm is a step-by-step procedure to solve a problem or perform a computation.
Why Use Algorithms?
Real-life Example: Making tea. Your algorithm could be:
1. Boil water
2. Add tea leaves
3. Pour into a cup
4. Add sugar/milk
When to Use: When you need fast access using index and a fixed-size collection.
Why: Simple structure with O(1) access time.
Real-life Example: Seats in a theater — fixed position, numbered.
When to Use: When frequent insertion/deletion is required.
Why: No need to shift elements; dynamic size.
Real-life Example: Train compartments linked together.
When to Use: When you need Last-In-First-Out (LIFO) behavior.
Why: Ideal for undo operations, expression parsing, etc.
Real-life Example: Stack of plates.
When to Use: First-In-First-Out (FIFO) scenarios like print queues.
Why: Useful in scheduling and buffering.
Real-life Example: People standing in line.
When to Use: When you need fast lookup using keys.
Why: Offers O(1) average time for get/put.
Real-life Example: Dictionary (word → meaning).
When to Use: To maintain hierarchical data (e.g., file system, DOM).
Why: Efficient searching, insertion, traversal.
Real-life Example: Organization chart or folder structure.
When to Use: When dealing with networks, routes, social connections.
Why: Models complex relationships effectively.
Real-life Example: Google Maps, Facebook friends.
Definition: Time complexity is a measure of the time an algorithm takes to run as a function of the input size.
Why It Matters: Helps estimate performance and scalability of algorithms.
Common Time Complexities:
Real-Life Examples:
Definition: Space complexity is a measure of the total memory used by an algorithm relative to input size.
Why It Matters: Crucial in memory-limited environments and large-scale systems.
Components:
Examples:
Tip: In-place algorithms (like Quick Sort) are memory efficient.
Sometimes improving time complexity increases space usage and vice versa.
Idea: Repeatedly swap adjacent elements if they are in the wrong order.
Time Complexity: O(n²)
Idea: Find the smallest element and place it at the beginning.
Time Complexity: O(n²)
Idea: Divide the array into halves, sort and merge them recursively.
Time Complexity: O(n log n)
Idea: Traverse the array and compare each element to the target.
Time Complexity: O(n)
Use Case: Unsorted arrays, small datasets
Idea: Divide the sorted array in half and compare mid with the key.
Time Complexity: O(log n)
Use Case: Sorted arrays
Problem: Given an array of integers nums
and an integer target
, return indices of the two numbers such that they add up to target
.
Example:
Input: nums = [2, 7, 11, 15], target = 9 Output: [0, 1]
Problem: Given a sorted array nums
, remove the duplicates in-place such that each element appears only once and return the new length.
Example:
Input: nums = [1,1,2] Output: 2, nums = [1,2,_]
Problem: Given an integer array nums
, find the contiguous subarray with the largest sum and return its sum.
Example:
Input: nums = [-2,1,-3,4,-1,2,1,-5,4] Output: 6 (subarray: [4,-1,2,1])
Problem: Given an array arr
, check if there exists two indices i
and j
such that i != j
and arr[i] == 2 * arr[j]
.
Example:
Input: arr = [10,2,5,3] Output: true
Problem: Given the array nums
consisting of 2n
elements in the form [x1,x2,...,xn,y1,y2,...,yn]
, return the array in the form [x1,y1,x2,y2,...,xn,yn]
.
Example:
Input: nums = [2,5,1,3,4,7], n = 3 Output: [2,3,5,4,1,7]
Problem: For each number in the array nums
, count how many numbers are smaller than it and return the result as an array.
Example:
Input: nums = [8,1,2,2,3] Output: [4,0,1,1,3]
Problem: Return the running sum of the given array. The running sum is defined as: runningSum[i] = sum(nums[0]...nums[i])
.
Example:
Input: nums = [1,2,3,4] Output: [1,3,6,10]
Problem: Given a 2D array accounts
where accounts[i][j]
is the amount of money the i-th customer has in the j-th bank, return the wealth that the richest customer has.
Example:
Input: accounts = [[1,2,3],[3,2,1]] Output: 6