Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

Readme.md

Certainly! Here’s a quick list of patterns and tips for each of these algorithms. Working with these patterns should help you recognize how to approach problems using each of these techniques.


1. Binary Search

  • Basic Pattern: Divide the search range in half and decide which half to keep based on a condition.
  • Common Use Cases:
    • Searching in sorted arrays or lists.
    • Finding the position of an element or determining if an element exists.
  • Variants:
    • Binary Search on a Range: Problems that require searching in a continuous range, like finding the minimum in a rotated sorted array.
    • Binary Search for the First/Last Occurrence: Use lower/upper bounds for problems requiring the first or last occurrence of a target.
    • Binary Search on Answer: When the answer lies within a range of values, e.g., minimizing/maximizing a value.
  • Practice Tips: Try problems where the array might be rotated, or where constraints are provided for the maximum/minimum.

2. Breadth-First Search (BFS)

  • Basic Pattern: Explore neighbors level by level (use a queue to keep track of nodes).
  • Common Use Cases:
    • Finding the shortest path in unweighted graphs or grids.
    • Working with grid-based problems (e.g., shortest distance in a maze).
  • Variants:
    • Multi-Source BFS: Initialize BFS from multiple starting points (often useful in grid problems).
    • 2D Grid BFS: For grid-based pathfinding where you check neighbors up, down, left, and right.
    • Bidirectional BFS: Used when searching from both start and target nodes, helpful for optimizing search time.
  • Practice Tips: Practice on graph and grid-based problems, especially shortest path problems.

3. Depth-First Search (DFS)

  • Basic Pattern: Recursively (or iteratively with a stack) explore nodes as deep as possible before backtracking.
  • Common Use Cases:
    • Pathfinding and exploring all paths in a graph.
    • Problems involving connectivity (e.g., counting connected components).
    • Tree-based problems (e.g., finding depths, paths).
  • Variants:
    • Recursive DFS: Use function calls for recursive traversal.
    • Iterative DFS: Implement DFS using an explicit stack.
    • Backtracking DFS: Often used when exploring multiple paths or combinations (useful in problems like permutations, combinations).
  • Practice Tips: Focus on recursive problems in trees and graphs, as well as backtracking problems.

4. Two Pointers

  • Basic Pattern: Use two pointers to reduce time complexity by processing elements in pairs.
  • Common Use Cases:
    • Finding pairs that satisfy a condition (e.g., sums to a target).
    • Problems involving contiguous subarrays or subsets.
  • Variants:
    • Opposite Ends: Pointers start from opposite ends of an array and move toward each other (useful for palindromic checks, pair sums).
    • Sliding Window with Two Pointers: Used in problems where you need to track subarrays or subsequences.
    • Same Direction: Two pointers moving in the same direction for a more nuanced traversal, often for variable-length subarrays.
  • Practice Tips: Focus on problems with arrays and subarrays, especially involving sums, differences, or constraints.

5. Priority Queue (Heap)

  • Basic Pattern: Use a priority queue (min-heap or max-heap) to manage elements by priority.
  • Common Use Cases:
    • Kth largest/smallest element problems.
    • Scheduling tasks based on priorities.
    • Dijkstra’s algorithm for shortest path.
  • Variants:
    • Min-Heap: Most common for finding smallest elements in a collection.
    • Max-Heap: Useful for problems needing the largest elements.
    • Double-ended Priority Queue: Use two heaps to manage both the smallest and largest elements dynamically.
  • Practice Tips: Focus on problems that require finding kth smallest/largest elements and scheduling-type tasks.