diff --git a/README.md b/README.md index 7fa66ef98..ba621d51a 100644 --- a/README.md +++ b/README.md @@ -97,17 +97,17 @@ We are grateful to all the contributors who have helped improve this project. Yo - - yashksaini-coder + + T-Rahul-prabhu-38
- Yash Kumar Saini + t rahul prabhu
- - IRFANSARI + + ananyag309
- Irfan Ansari + Ananya Gupta
@@ -120,10 +120,17 @@ We are grateful to all the contributors who have helped improve this project. Yo - - ananyag309 + + IRFANSARI
- Ananya Gupta + Irfan Ansari +
+ + + + yashksaini-coder +
+ Yash Kumar Saini
@@ -148,12 +155,14 @@ We are grateful to all the contributors who have helped improve this project. Yo - - Bhum-ika + + vedhcet-07
- Bhumika Sharma + Vishwas M D
+ + nishakp3005 @@ -161,27 +170,25 @@ We are grateful to all the contributors who have helped improve this project. Yo Nishita Panchal - - - - vedhcet-07 + + J-B-Mugundh
- Vishwas M D + Mugundh J B
- - shalini-bhandari + + Bhum-ika
- Shalini Bhandari + Bhumika Sharma
- - Mohith1490 + + Akki-58
- Mohith Singh + AJ
@@ -192,10 +199,19 @@ We are grateful to all the contributors who have helped improve this project. Yo - - Akki-58 + + Mohith1490
- AJ + Mohith Singh +
+ + + + + + shalini-bhandari +
+ Shalini Bhandari
@@ -205,8 +221,6 @@ We are grateful to all the contributors who have helped improve this project. Yo Harsh - - IRFANSARI2 @@ -228,13 +242,6 @@ We are grateful to all the contributors who have helped improve this project. Yo Shubh Agarwal - - - J-B-Mugundh -
- Mugundh J B -
- oebelus @@ -242,6 +249,8 @@ We are grateful to all the contributors who have helped improve this project. Yo Oebelus + + rajatsinghal02 diff --git a/docs/algorithms/Recursive Algorithms/DirectRecursion.md b/docs/algorithms/recursive-algorithms/DirectRecursion.md similarity index 100% rename from docs/algorithms/Recursive Algorithms/DirectRecursion.md rename to docs/algorithms/recursive-algorithms/DirectRecursion.md diff --git a/docs/algorithms/Recursive Algorithms/IndirectRecursion.md b/docs/algorithms/recursive-algorithms/IndirectRecursion.md similarity index 100% rename from docs/algorithms/Recursive Algorithms/IndirectRecursion.md rename to docs/algorithms/recursive-algorithms/IndirectRecursion.md diff --git a/docs/algorithms/Recursive Algorithms/_category_.json b/docs/algorithms/recursive-algorithms/_category_.json similarity index 100% rename from docs/algorithms/Recursive Algorithms/_category_.json rename to docs/algorithms/recursive-algorithms/_category_.json diff --git a/docs/algorithms/Sorting Algorithms/BubbleSort.md b/docs/algorithms/sorting-algorithms/BubbleSort.md similarity index 100% rename from docs/algorithms/Sorting Algorithms/BubbleSort.md rename to docs/algorithms/sorting-algorithms/BubbleSort.md diff --git a/docs/algorithms/Sorting Algorithms/BucketSort.md b/docs/algorithms/sorting-algorithms/BucketSort.md similarity index 100% rename from docs/algorithms/Sorting Algorithms/BucketSort.md rename to docs/algorithms/sorting-algorithms/BucketSort.md diff --git a/docs/algorithms/Sorting Algorithms/CombSort.md b/docs/algorithms/sorting-algorithms/CombSort.md similarity index 100% rename from docs/algorithms/Sorting Algorithms/CombSort.md rename to docs/algorithms/sorting-algorithms/CombSort.md diff --git a/docs/algorithms/Sorting Algorithms/CountingSort.md b/docs/algorithms/sorting-algorithms/CountingSort.md similarity index 100% rename from docs/algorithms/Sorting Algorithms/CountingSort.md rename to docs/algorithms/sorting-algorithms/CountingSort.md diff --git a/docs/algorithms/Sorting Algorithms/CycleSort.md b/docs/algorithms/sorting-algorithms/CycleSort.md similarity index 100% rename from docs/algorithms/Sorting Algorithms/CycleSort.md rename to docs/algorithms/sorting-algorithms/CycleSort.md diff --git a/docs/algorithms/Sorting Algorithms/HeapSort.md b/docs/algorithms/sorting-algorithms/HeapSort.md similarity index 99% rename from docs/algorithms/Sorting Algorithms/HeapSort.md rename to docs/algorithms/sorting-algorithms/HeapSort.md index 479a402b8..3bd56e555 100644 --- a/docs/algorithms/Sorting Algorithms/HeapSort.md +++ b/docs/algorithms/sorting-algorithms/HeapSort.md @@ -1,6 +1,5 @@ --- - -id: selection-sort-algo +id: heap-sort-algo sidebar_position: 6 title: Heap Sort sidebar_label: Heap Sort diff --git a/docs/algorithms/Sorting Algorithms/InsertionSort.md b/docs/algorithms/sorting-algorithms/InsertionSort.md similarity index 100% rename from docs/algorithms/Sorting Algorithms/InsertionSort.md rename to docs/algorithms/sorting-algorithms/InsertionSort.md diff --git a/docs/algorithms/Sorting Algorithms/MergeSort.md b/docs/algorithms/sorting-algorithms/MergeSort.md similarity index 100% rename from docs/algorithms/Sorting Algorithms/MergeSort.md rename to docs/algorithms/sorting-algorithms/MergeSort.md diff --git a/docs/algorithms/Sorting Algorithms/QuickSort.md b/docs/algorithms/sorting-algorithms/QuickSort.md similarity index 100% rename from docs/algorithms/Sorting Algorithms/QuickSort.md rename to docs/algorithms/sorting-algorithms/QuickSort.md diff --git a/docs/algorithms/Sorting Algorithms/RadixSort.md b/docs/algorithms/sorting-algorithms/RadixSort.md similarity index 100% rename from docs/algorithms/Sorting Algorithms/RadixSort.md rename to docs/algorithms/sorting-algorithms/RadixSort.md diff --git a/docs/algorithms/Sorting Algorithms/SelectionSort.md b/docs/algorithms/sorting-algorithms/SelectionSort.md similarity index 90% rename from docs/algorithms/Sorting Algorithms/SelectionSort.md rename to docs/algorithms/sorting-algorithms/SelectionSort.md index bc09c5228..51879adaa 100644 --- a/docs/algorithms/Sorting Algorithms/SelectionSort.md +++ b/docs/algorithms/sorting-algorithms/SelectionSort.md @@ -1,10 +1,10 @@ --- - id: selection-sort-algo sidebar_position: 2 -title: Selection Sort -sidebar_label: Selection Sort - +title: Selection Sort +sidebar_label: Selection Sort +description: Selection sort is a simple comparison-based sorting algorithm that repeatedly selects the smallest (or largest) element from the unsorted portion of the array and swaps it with the first unsorted element. It works by dividing the array into a sorted and an unsorted region and systematically reducing the size of the unsorted region. +tags: [Sorting Algorithms, Selection Sort] --- ### Definition: diff --git a/docs/algorithms/Sorting Algorithms/ShellSort.md b/docs/algorithms/sorting-algorithms/ShellSort.md similarity index 100% rename from docs/algorithms/Sorting Algorithms/ShellSort.md rename to docs/algorithms/sorting-algorithms/ShellSort.md diff --git a/docs/algorithms/Sorting Algorithms/TimSort.md b/docs/algorithms/sorting-algorithms/TimSort.md similarity index 100% rename from docs/algorithms/Sorting Algorithms/TimSort.md rename to docs/algorithms/sorting-algorithms/TimSort.md diff --git a/docs/algorithms/Sorting Algorithms/_category_.json b/docs/algorithms/sorting-algorithms/_category_.json similarity index 100% rename from docs/algorithms/Sorting Algorithms/_category_.json rename to docs/algorithms/sorting-algorithms/_category_.json diff --git a/docs/dynamic-programming/Two-City-Scheduling-3D-DP.md b/docs/dynamic-programming/Two-City-Scheduling-3D-DP.md new file mode 100644 index 000000000..d6253cdfa --- /dev/null +++ b/docs/dynamic-programming/Two-City-Scheduling-3D-DP.md @@ -0,0 +1,313 @@ +--- +id: two-city-scheduling-dp +title: Two City Scheduling Problem - 3D Dynamic Programming +sidebar_label: Two City Scheduling +sidebar_position: 2 +description: "In this post, we'll explore the Two City Scheduling problem, a classic algorithmic challenge that can be solved efficiently using 3D Dynamic Programming. We'll delve into the problem's constraints, discuss the dynamic programming approach, and provide solutions in multiple languages such as C++, Java, Python, JavaScript, and Go. By the end, you'll understand how to use DP to minimize the total travel costs for sending an equal number of people to two different cities." +tags: [dsa, dynamic programming, scheduling] +--- + +## Problem Statement +You are given two cities, `A` and `B`, and a list of people, where each person has a cost associated with flying to either city. Your goal is to find the optimal way to send `N` people to city `A` and `N` people to city `B` such that the total cost is minimized. + +The input consists of an array `costs` where `costs[i] = [aCost, bCost]`, which represents the cost of flying the `i-th` person to city `A` and city `B`. + +### Objective +- Return the minimum total cost to send `N` people to each city. + +### Example +```plaintext +Input: costs = [[10,20],[30,200],[50,30],[200,500]] +Output: 370 +``` + + +### Constraints +- `2 * n == costs.length` +- `2 <= costs.length <= 100` +- `costs.length` is even. +- `1 <= aCosti, bCosti <= 1000` + +## Solution +This solution employs a dynamic programming approach to solve the Two City Scheduling problem. + +### Dynamic Programming Approach + +**DP Array Initialization:** + +We initialize a 3D DP array `dp[i][wA][wB]`, where: +- `i` represents the first `i` people considered. +- `wA` represents the number of people sent to city `A`. +- `wB` represents the number of people sent to city `B`. + +**Base Case:** + +For `0` people, the total cost is `0` (no one is sent). + +**Transition:** + +For each person, we can choose to send them to either city `A` or city `B`, updating our DP table accordingly: +- If a person is sent to city `A`, we reduce the count of people going to city `A` and add the cost of sending them there. +- Similarly, if sent to city `B`, we reduce the count of people going to city `B` and add the respective cost. + +**Final Calculation:** + +The minimum total cost will be found in `dp[2 * N][N][N]`. + +### Time and Space Complexity +- **Time Complexity:** O(N³), where N is half the size of the costs array. +- **Space Complexity:** O(N³) due to the 3D DP array. + +### Code Implementation + +C++: +```cpp +class Solution { +public: + int twoCitySchedCost(vector>& costs) { + int N = costs.size() / 2; + int dp[2 * N + 1][N + 1][N + 1]; + for (int i = 0; i <= N; ++i) { + for (int j = 0; j <= N; ++j) { + dp[0][i][j] = 0; + } + } + for (int i = 1; i <= 2 * N; ++i) { + for (int wA = 1; wA <= N; ++wA) { + if (dp[i - 1][wA - 1][0] == INT_MAX) { + dp[i][wA][0] = INT_MAX; + } else { + dp[i][wA][0] = costs[i - 1][0] + dp[i - 1][wA - 1][0]; + } + } + for (int wB = 1; wB <= N; ++wB) { + if (dp[i - 1][0][wB - 1] == INT_MAX) { + dp[i][0][wB] = INT_MAX; + } else { + dp[i][0][wB] = costs[i - 1][1] + dp[i - 1][0][wB - 1]; + } + } + dp[i][0][0] = INT_MAX; + } + + for (int i = 1; i <= 2 * N; ++i) { + for (int wA = 1; wA <= N; ++wA) { + for (int wB = 1; wB <= N; ++wB) { + if (dp[i - 1][wA - 1][wB] == INT_MAX) { + dp[i][wA][wB] = costs[i - 1][1]; + } else if (dp[i - 1][wA][wB - 1] == INT_MAX) { + dp[i][wA][wB] = costs[i - 1][0]; + } else { + dp[i][wA][wB] = min(costs[i - 1][0] + dp[i - 1][wA - 1][wB], + costs[i - 1][1] + dp[i - 1][wA][wB - 1]); + } + } + } + } + return dp[2 * N][N][N]; + } +}; +``` + +Java: +```java +class Solution { + public int twoCitySchedCost(int[][] costs) { + int N = costs.length / 2; + int[][][] dp = new int[2 * N + 1][N + 1][N + 1]; + + for (int i = 0; i <= N; i++) { + for (int j = 0; j <= N; j++) { + dp[0][i][j] = 0; + } + } + + for (int i = 1; i <= 2 * N; i++) { + for (int wA = 1; wA <= N; wA++) { + if (dp[i - 1][wA - 1][0] == Integer.MAX_VALUE) { + dp[i][wA][0] = Integer.MAX_VALUE; + } else { + dp[i][wA][0] = costs[i - 1][0] + dp[i - 1][wA - 1][0]; + } + } + for (int wB = 1; wB <= N; wB++) { + if (dp[i - 1][0][wB - 1] == Integer.MAX_VALUE) { + dp[i][0][wB] = Integer.MAX_VALUE; + } else { + dp[i][0][wB] = costs[i - 1][1] + dp[i - 1][0][wB - 1]; + } + } + dp[i][0][0] = Integer.MAX_VALUE; + } + + for (int i = 1; i <= 2 * N; i++) { + for (int wA = 1; wA <= N; wA++) { + for (int wB = 1; wB <= N; wB++) { + if (dp[i - 1][wA - 1][wB] == Integer.MAX_VALUE) { + dp[i][wA][wB] = costs[i - 1][1]; + } else if (dp[i - 1][wA][wB - 1] == Integer.MAX_VALUE) { + dp[i][wA][wB] = costs[i - 1][0]; + } else { + dp[i][wA][wB] = Math.min(costs[i - 1][0] + dp[i - 1][wA - 1][wB], + costs[i - 1][1] + dp[i - 1][wA][wB - 1]); + } + } + } + } + + return dp[2 * N][N][N]; + } +} +``` + +Python: +```python +class Solution: + def twoCitySchedCost(self, costs: List[List[int]]) -> int: + N = len(costs) // 2 + dp = [[[0] * (N + 1) for _ in range(N + 1)] for _ in range(2 * N + 1)] + + for i in range(1, 2 * N + 1): + for wA in range(1, N + 1): + if dp[i - 1][wA - 1][0] == float('inf'): + dp[i][wA][0] = float('inf') + else: + dp[i][wA][0] = costs[i - 1][0] + dp[i - 1][wA - 1][0] + + for wB in range(1, N + 1): + if dp[i - 1][0][wB - 1] == float('inf'): + dp[i][0][wB] = float('inf') + else: + dp[i][0][wB] = costs[i - 1][1] + dp[i - 1][0][wB - 1] + + dp[i][0][0] = float('inf') + + for i in range(1, 2 * N + 1): + for wA in range(1, N + 1): + for wB in range(1, N + 1): + if dp[i - 1][wA - 1][wB] == float('inf'): + dp[i][wA][wB] = costs[i - 1][1] + elif dp[i - 1][wA][wB - 1] == float('inf'): + dp[i][wA][wB] = costs[i - 1][0] + else: + dp[i][wA][wB] = min(costs[i - 1][0] + dp[i - 1][wA - 1][wB], + costs[i - 1][1] + dp[i - 1][wA][wB - 1]) + + return dp[2 * N][N][N] +``` + +Javascript: +```javascript +class Solution { + twoCitySchedCost(costs) { + const N = costs.length / 2; + const dp = Array.from({ length: 2 * N + 1 }, () => + Array.from({ length: N + 1 }, () => Array(N + 1).fill(0)) + ); + + for (let i = 0; i <= N; i++) { + for (let j = 0; j <= N; j++) { + dp[0][i][j] = 0; + } + } + + for (let i = 1; i <= 2 * N; i++) { + for (let wA = 1; wA <= N; wA++) { + dp[i][wA][0] = dp[i - 1][wA - 1][0] === Infinity ? Infinity : costs[i - 1][0] + dp[i - 1][wA - 1][0]; + } + for (let wB = 1; wB <= N; wB++) { + dp[i][0][wB] = dp[i - 1][0][wB - 1] === Infinity ? Infinity : costs[i - 1][1] + dp[i - 1][0][wB - 1]; + } + dp[i][0][0] = Infinity; + } + + for (let i = 1; i <= 2 * N; i++) { + for (let wA = 1; wA <= N; wA++) { + for (let wB = 1; wB <= N; wB++) { + if (dp[i - 1][wA - 1][wB] === Infinity) { + dp[i][wA][wB] = costs[i - 1][1]; + } else if (dp[i - 1][wA][wB - 1] === Infinity) { + dp[i][wA][wB] = costs[i - 1][0]; + } else { + dp[i][wA][wB] = Math.min(costs[i - 1][0] + dp[i - 1][wA - 1][wB], + costs[i - 1][1] + dp[i - 1][wA][wB - 1]); + } + } + } + } + + return dp[2 * N][N][N]; + } +} +``` + +Go: +```go +package main + +import ( + "math" +) + +func twoCitySchedCost(costs [][]int) int { + N := len(costs) / 2 + dp := make([][][]int, 2*N+1) + for i := range dp { + dp[i] = make([][]int, N+1) + for j := range dp[i] { + dp[i][j] = make([]int, N+1) + } + } + + for i := 0; i <= N; i++ { + for j := 0; j <= N; j++ { + dp[0][i][j] = 0 + } + } + + for i := 1; i <= 2*N; i++ { + for wA := 1; wA <= N; wA++ { + if dp[i-1][wA-1][0] == math.MaxInt { + dp[i][wA][0] = math.MaxInt + } else { + dp[i][wA][0] = costs[i-1][0] + dp[i-1][wA-1][0] + } + } + for wB := 1; wB <= N; wB++ { + if dp[i-1][0][wB-1] == math.MaxInt { + dp[i][0][wB] = math.MaxInt + } else { + dp[i][0][wB] = costs[i-1][1] + dp[i-1][0][wB-1] + } + } + dp[i][0][0] = math.MaxInt + } + + for i := 1; i <= 2*N; i++ { + for wA := 1; wA <= N; wA++ { + for wB := 1; wB <= N; wB++ { + if dp[i-1][wA-1][wB] == math.MaxInt { + dp[i][wA][wB] = costs[i-1][1] + } else if dp[i-1][wA][wB-1] == math.MaxInt { + dp[i][wA][wB] = costs[i-1][0] + } else { + dp[i][wA][wB] = min(costs[i-1][0]+dp[i-1][wA-1][wB], + costs[i-1][1]+dp[i-1][wA][wB-1]) + } + } + } + } + + return dp[2*N][N][N] +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} +``` + +### Conclusion +This solution effectively utilizes dynamic programming to optimize the process of scheduling flights to two cities, significantly reducing the computational complexity compared to a brute-force approach. By leveraging a 3D DP array, we ensure that we only compute each state once, leading to an efficient solution. \ No newline at end of file diff --git a/docs/greedy-algorithms/greedy-example.md b/docs/greedy-algorithms/greedy-example.md new file mode 100644 index 000000000..42310d84c --- /dev/null +++ b/docs/greedy-algorithms/greedy-example.md @@ -0,0 +1,60 @@ +--- +id: greedy Algorithms +title: greedy Algorithms +sidebar_label: greedy Algorithms +sidebar_position: 4 +description: Greedy algorithms are a class of algorithms that make the optimal choice at each step with the hope of finding the global optimum +tags: [Competitive Programming,greedy approach,optimization] +--- + +# Greedy Algorithms - Examples + +Here are a few examples of greedy algorithms in C++, demonstrating how the approach works in different problem scenarios. + +## 1. Activity Selection Problem + +The activity selection problem involves selecting the maximum number of activities that don't overlap. Given start and finish times, we need to choose activities that don't overlap. + +### C++ Code + +```cpp +#include +#include +#include + +struct Activity { + int start; + int finish; +}; + +// Comparator to sort activities by their finish times +bool compare(Activity a1, Activity a2) { + return a1.finish < a2.finish; +} + +void activitySelection(Activity activities[], int n) { + std::sort(activities, activities + n, compare); + + // The first activity always gets selected + int lastSelectedActivity = 0; + std::cout << "Selected activities: " << lastSelectedActivity << " "; + + // Consider the rest of the activities + for (int i = 1; i < n; i++) { + if (activities[i].start >= activities[lastSelectedActivity].finish) { + std::cout << i << " "; + lastSelectedActivity = i; + } + } + std::cout << std::endl; +} + +int main() { + Activity activities[] = {{0, 6}, {1, 4}, {3, 5}, {5, 7}, {5, 9}, {8, 9}}; + int n = sizeof(activities) / sizeof(activities[0]); + + activitySelection(activities, n); + + return 0; +} +``` \ No newline at end of file diff --git a/docs/greedy-algorithms/greedy-theory.md b/docs/greedy-algorithms/greedy-theory.md new file mode 100644 index 000000000..f72a9c884 --- /dev/null +++ b/docs/greedy-algorithms/greedy-theory.md @@ -0,0 +1,62 @@ +--- +id: greedy Algorithms +title: greedy Algorithms +sidebar_label: greedy Algorithms +sidebar_position: 4 +description: Greedy algorithms are a class of algorithms that make the optimal choice at each step with the hope of finding the global optimum +tags: [Competitive Programming,greedy approach,optimization] +--- +# Greedy Algorithms - Theory + +## Introduction + +Greedy algorithms are a paradigm for solving optimization problems. The main idea behind a greedy algorithm is to make a sequence of choices, each of which looks the best at the moment. It chooses the optimal solution at every step with the hope that these local optimal choices will lead to a global optimal solution. + +Unlike dynamic programming, where you solve every subproblem and then combine the solutions to form the optimal solution for the entire problem, greedy algorithms directly pick what seems to be the best option at each decision point. + +### Characteristics of Greedy Algorithms + +1. **Greedy Choice Property**: A globally optimal solution can be arrived at by making locally optimal choices. The algorithm assumes that by choosing the optimal solution at each step, the overall solution will be optimal. + +2. **Optimal Substructure**: A problem has an optimal substructure if an optimal solution to the problem can be constructed efficiently from optimal solutions of its subproblems. This is necessary for a greedy algorithm to be valid. + +3. **Non-Overlapping Subproblems**: Greedy algorithms generally work well when subproblems don’t overlap (like in dynamic programming), which allows making decisions based only on local information. + +### How Greedy Algorithms Work + +- **Step 1: Greedy Choice**: At each step, choose the best possible option available. This is a local optimization. +- **Step 2: Reduce Problem Size**: After making the choice, reduce the problem size. The remaining subproblem must also satisfy the properties of the greedy approach. +- **Step 3: Repeat**: Repeat the greedy choice step until the problem is reduced to a simple base case. + +### Applications of Greedy Algorithms + +Greedy algorithms are applied to a variety of problems, especially in optimization scenarios: + +1. **Activity Selection Problem**: Selecting the maximum number of activities that don't overlap. +2. **Huffman Coding**: A compression algorithm used for lossless data compression. +3. **Kruskal's and Prim's Algorithm**: Used to find the Minimum Spanning Tree (MST) in a graph. +4. **Dijkstra's Algorithm**: Used to find the shortest path from one source to all other vertices in a graph. + +### Advantages of Greedy Algorithms + +1. **Simple to Implement**: Greedy algorithms are generally easier to code and understand because they follow a straightforward approach. +2. **Efficient**: They tend to run faster compared to other algorithms like dynamic programming due to their simple structure. +3. **Optimal Solutions (if applicable)**: For certain problems, greedy algorithms do give an optimal solution. + +### Limitations + +- **Not Always Optimal**: Greedy algorithms do not guarantee an optimal solution for all problems. In some cases, they might only provide a suboptimal solution. +- **Problem-Specific**: Greedy algorithms work well for problems with specific properties, like the greedy choice property and optimal substructure. Without these properties, greedy algorithms may fail to find the best solution. + +### Greedy vs. Dynamic Programming + +| **Feature** | **Greedy Algorithm** | **Dynamic Programming** | +|--------------------------|------------------------------------------------|---------------------------------------------------| +| **Choice** | Greedy algorithms make a local optimal choice | DP solves all subproblems and combines solutions. | +| **Structure** | No overlapping subproblems | Overlapping subproblems are recomputed. | +| **Use** | Simple and efficient for specific problems | Used for complex problems where greedy fails. | +| **Examples** | Kruskal's MST, Huffman Coding, Dijkstra's | Longest Common Subsequence, Matrix Chain Multiplication | + +### Conclusion + +Greedy algorithms are an efficient approach to solving many problems. However, their applicability is limited to problems that satisfy specific properties like the greedy choice property and optimal substructure. If these properties are absent, dynamic programming or other algorithms should be considered. diff --git a/docs/heap/heap-operations.md b/docs/heap/heap-operations.md new file mode 100644 index 000000000..49cb1620d --- /dev/null +++ b/docs/heap/heap-operations.md @@ -0,0 +1,185 @@ +--- +id: Heap-data-Structure +title: heap data structure +sidebar_label: Heap Data Structure +sidebar_position: 10 +description: Heaps are commonly used to implement priority queues and ensure efficient retrieval of the minimum or maximum element. +tags: [Competitive Programming,top-K,priority queue] +--- +# Heap Data Structure Operations Examples + +## Example 1: Insert and Peek Operations + +- Inserting 40, 60, 20, 10, 50: The heap is reorganized after every insertion to maintain the max heap property. +- Peeking: After the insertions, the maximum element (root) is displayed, which is 60. + +```cpp +#include +#include + +using namespace std; + +class MaxHeap { + vector heap; + + // Heapify up to restore the heap property after insertion + void heapifyUp(int index) { + if (index == 0) return; + int parentIndex = (index - 1) / 2; + if (heap[parentIndex] < heap[index]) { + swap(heap[parentIndex], heap[index]); + heapifyUp(parentIndex); + } + } + +public: + // Insert a new element into the heap + void insert(int value) { + heap.push_back(value); + heapifyUp(heap.size() - 1); + } + + // Peek the maximum element (root) + int getMax() { + if (heap.size() == 0) throw runtime_error("Heap is empty"); + return heap[0]; + } + + // Print heap elements + void printHeap() { + for (int val : heap) { + cout << val << " "; + } + cout << endl; + } +}; + +int main() { + MaxHeap maxHeap; + + // Inserting elements into the heap + maxHeap.insert(40); + maxHeap.insert(60); + maxHeap.insert(20); + maxHeap.insert(10); + maxHeap.insert(50); + + // Printing the heap after insertions + cout << "Heap after insertions: "; + maxHeap.printHeap(); + + // Peeking the maximum element + cout << "Max element: " << maxHeap.getMax() << endl; + + return 0; +} +``` +``` +Heap after insertions: 60 50 20 10 40 +Max element: 60 +``` + + + + +## Example 2: Insert, Delete, and Peek Operations + +```cpp +#include +#include + +using namespace std; + +class MaxHeap { + vector heap; + + // Heapify up to restore the heap property after insertion + void heapifyUp(int index) { + if (index == 0) return; + int parentIndex = (index - 1) / 2; + if (heap[parentIndex] < heap[index]) { + swap(heap[parentIndex], heap[index]); + heapifyUp(parentIndex); + } + } + + // Heapify down to restore the heap property after deletion + void heapifyDown(int index) { + int leftChild = 2 * index + 1; + int rightChild = 2 * index + 2; + int largest = index; + + if (leftChild < heap.size() && heap[leftChild] > heap[largest]) { + largest = leftChild; + } + + if (rightChild < heap.size() && heap[rightChild] > heap[largest]) { + largest = rightChild; + } + + if (largest != index) { + swap(heap[index], heap[largest]); + heapifyDown(largest); + } + } + +public: + // Insert a new element into the heap + void insert(int value) { + heap.push_back(value); + heapifyUp(heap.size() - 1); + } + + // Remove the maximum element from the heap + void removeMax() { + if (heap.size() == 0) throw runtime_error("Heap is empty"); + heap[0] = heap.back(); + heap.pop_back(); + heapifyDown(0); + } + + // Peek the maximum element (root) + int getMax() { + if (heap.size() == 0) throw runtime_error("Heap is empty"); + return heap[0]; + } + + // Print heap elements + void printHeap() { + for (int val : heap) { + cout << val << " "; + } + cout << endl; + } +}; + +int main() { + MaxHeap maxHeap; + + // Inserting elements into the heap + maxHeap.insert(90); + maxHeap.insert(30); + maxHeap.insert(70); + maxHeap.insert(50); + maxHeap.insert(20); + + cout << "Heap after insertions: "; + maxHeap.printHeap(); + + // Removing the max element + maxHeap.removeMax(); + cout << "Heap after removing max: "; + maxHeap.printHeap(); + + // Peeking the new max element + cout << "Max element after removal: " << maxHeap.getMax() << endl; + + return 0; +} +``` + +``` +Heap after insertions: 90 50 70 30 20 +Heap after removing max: 70 50 20 30 +Max element after removal: 70 +``` diff --git a/docs/heap/heapBasics.md b/docs/heap/heapBasics.md new file mode 100644 index 000000000..a2d8f6518 --- /dev/null +++ b/docs/heap/heapBasics.md @@ -0,0 +1,184 @@ +--- +id: Heap-data-Structure +title: heap data structure +sidebar_label: Heap Data Structure +sidebar_position: 10 +description: Heaps are commonly used to implement priority queues and ensure efficient retrieval of the minimum or maximum element. +tags: [Competitive Programming,top-K,priority queue] +--- +# Heap Data Structure + +A **Heap** is a specialized tree-based data structure that satisfies the **Heap Property**. Heaps are commonly used to implement priority queues and ensure efficient retrieval of the minimum or maximum element. + + +## Introduction + +A **Heap** is a complete binary tree, which means every level is fully filled except possibly the last level, which is filled from left to right. The heap is used to efficiently manage a priority queue, allowing us to retrieve the highest or lowest priority element in constant time. + +Heaps can be represented as arrays, which helps in reducing the space complexity by avoiding pointers. + +## Types of Heaps + +### Max Heap + +In a **Max Heap**, for every node `i`, the value of `i` is greater than or equal to the values of its children. Therefore, the root of the tree contains the maximum element. +``` + + 50 + / \ + 30 20 + / \ / + 15 10 8 +``` + + +### Min Heap + +In a **Min Heap**, for every node `i`, the value of `i` is less than or equal to the values of its children. The root contains the minimum element. +``` + 10 + / \ + 15 30 + / \ / + 50 20 40 +``` + +## Heap Operations + +### Insert + +Inserting an element in a heap involves adding the new element at the end of the tree (or array representation) and then "bubbling up" to restore the heap property. + +1. Insert the element at the next available position. +2. Compare the element with its parent and swap if necessary (heapify up). + +### Delete + +The element to be deleted is usually the root (for priority queues). The last element of the heap replaces the root, and the heap property is restored by "bubbling down" (heapify down). + +1. Replace the root with the last element. +2. Restore the heap property by moving the element down (heapify down). + +### Peek + +The **peek** operation returns the root element of the heap without removing it: +- For a **Max Heap**, this returns the maximum element. +- For a **Min Heap**, this returns the minimum element. + +### Heapify + +Heapifying ensures that a subtree satisfies the heap property. Two types of heapify operations are: +- **Heapify Up**: Used in insertion. +- **Heapify Down**: Used in deletion. + +## Applications + +- **Priority Queue**: Used in scheduling processes, graph algorithms (like Dijkstra's shortest path). +- **Heap Sort**: Sorting algorithm using heaps. +- **Graph Algorithms**: Like Prim's and Dijkstra's shortest path algorithms. +- **Median Maintenance**: Heaps can be used to keep track of the median in a dynamic dataset. + +## Time Complexity + +- **Insertion**: $O(log n)$ +- **Deletion**: $O(log n)$ +- **Peek**: $O(1)$ +- **Heapify**: $O(log n)$ + +## Implementation + +### C++ Code Example + +Here’s a C++ implementation of a Max Heap: + +```cpp +#include +#include + +using namespace std; + +class MaxHeap { + vector heap; + + // Heapify up to restore the heap property after insertion + void heapifyUp(int index) { + if (index == 0) return; + int parentIndex = (index - 1) / 2; + if (heap[parentIndex] < heap[index]) { + swap(heap[parentIndex], heap[index]); + heapifyUp(parentIndex); + } + } + + // Heapify down to restore the heap property after deletion + void heapifyDown(int index) { + int leftChild = 2 * index + 1; + int rightChild = 2 * index + 2; + int largest = index; + + if (leftChild < heap.size() && heap[leftChild] > heap[largest]) { + largest = leftChild; + } + + if (rightChild < heap.size() && heap[rightChild] > heap[largest]) { + largest = rightChild; + } + + if (largest != index) { + swap(heap[index], heap[largest]); + heapifyDown(largest); + } + } + +public: + // Insert a new element into the heap + void insert(int value) { + heap.push_back(value); + heapifyUp(heap.size() - 1); + } + + // Remove the maximum element from the heap + void removeMax() { + if (heap.size() == 0) return; + heap[0] = heap.back(); + heap.pop_back(); + heapifyDown(0); + } + + // Peek the maximum element (root) + int getMax() { + if (heap.size() == 0) throw runtime_error("Heap is empty"); + return heap[0]; + } + + // Print heap elements + void printHeap() { + for (int val : heap) { + cout << val << " "; + } + cout << endl; + } +}; + +int main() { + MaxHeap maxHeap; + + maxHeap.insert(50); + maxHeap.insert(30); + maxHeap.insert(20); + maxHeap.insert(15); + maxHeap.insert(10); + maxHeap.insert(8); + + cout << "Heap after insertions: "; + maxHeap.printHeap(); + + cout << "Max element: " << maxHeap.getMax() << endl; + + maxHeap.removeMax(); + cout << "Heap after removing max: "; + maxHeap.printHeap(); + + return 0; +} +``` diff --git a/docusaurus.config.js b/docusaurus.config.js index 31468fe37..88bb7228a 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -1,7 +1,7 @@ import { themes as prismThemes } from "prism-react-renderer"; // import remarkPlugin from 'remark-plugin'; -import remarkMath from 'remark-math'; -import rehypeKatex from 'rehype-katex'; +import remarkMath from "remark-math"; +import rehypeKatex from "rehype-katex"; const path = require("path"); /** @type {import('@docusaurus/types').Config} */ @@ -23,8 +23,9 @@ const config = { "classic", /** @type {import('@docusaurus/preset-classic').Options} */ ({ + debug: true, docs: { - sidebarPath: "./sidebars.js", + sidebarPath: "./sidebars.js", editUrl: "https://github.com/Ajay-Dhangar/algo/tree/main/", remarkPlugins: [remarkMath], rehypePlugins: [rehypeKatex], @@ -44,11 +45,11 @@ const config = { stylesheets: [ { - href: 'https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css', - type: 'text/css', + href: "https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css", + type: "text/css", integrity: - 'sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM', - crossorigin: 'anonymous', + "sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM", + crossorigin: "anonymous", }, ], @@ -69,7 +70,54 @@ const config = { position: "left", label: "Tutorial", }, - { to: "/blog", label: "Blog", position: "left" }, + { + to: "https://ajay-dhangar.github.io/algo/roadmap", + label: "Roadmap", + position: "left", + target: "_self", + }, + { + to: "https://ajay-dhangar.github.io/algo/challenges", + label: "Challenges", + position: "left", + target: "_self", + }, + { + to: "https://ajay-dhangar.github.io/algo/practice", + label: "Practice", + position: "left", + target: "_self", + }, + { + to: "https://ajay-dhangar.github.io/algo/leaderboard", + label: "Leaderboard", + position: "left", + target: "_self", + }, + { + to: "https://ajay-dhangar.github.io/algo/community", + label: "Community", + position: "left", + target: "_self", + }, + { + to: "https://ajay-dhangar.github.io/algo/resources", + label: "Resources", + position: "left", + target: "_self", + }, + { + to: "https://ajay-dhangar.github.io/algo/faq", + label: "FAQ", + position: "left", + target: "_self", + }, + { + to: "https://ajay-dhangar.github.io/algo/blogs", + label: "Blogs", + position: "left", + target: "_self", + }, { href: "https://github.com/ajay-dhangar/algo", label: "GitHub", diff --git a/package-lock.json b/package-lock.json index 35acc2ae2..dbb821710 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@docusaurus/core": "^3.5.2", "@docusaurus/plugin-content-blog": "^3.5.2", "@docusaurus/plugin-content-docs": "^3.5.2", + "@docusaurus/plugin-debug": "^3.5.2", "@docusaurus/preset-classic": "^3.5.2", "@docusaurus/theme-mermaid": "^3.5.2", "@giscus/react": "^3.0.0", diff --git a/package.json b/package.json index 2de38dae8..8829cabbd 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@docusaurus/core": "^3.5.2", "@docusaurus/plugin-content-blog": "^3.5.2", "@docusaurus/plugin-content-docs": "^3.5.2", + "@docusaurus/plugin-debug": "^3.5.2", "@docusaurus/preset-classic": "^3.5.2", "@docusaurus/theme-mermaid": "^3.5.2", "@giscus/react": "^3.0.0", diff --git a/src/pages/Blogs/index.tsx b/src/pages/Blogs/index.tsx new file mode 100644 index 000000000..8ebfefbef --- /dev/null +++ b/src/pages/Blogs/index.tsx @@ -0,0 +1,100 @@ +import Layout from "@theme/Layout"; +import React, { useState } from "react"; +import { motion } from "framer-motion"; +import { FaSearch, FaTag } from "react-icons/fa"; + +const Blogs: React.FC = () => { + const [searchTerm, setSearchTerm] = useState(""); + const [selectedTag, setSelectedTag] = useState("All"); + + const blogPosts = [ + { id: 1, title: "Understanding Time Complexity", tag: "Theory", summary: "Learn the basics of time complexity analysis." }, + { id: 2, title: "Top 5 Sorting Algorithms", tag: "Sorting", summary: "Explore the most common sorting algorithms and their use cases." }, + { id: 3, title: "Graph Theory Basics", tag: "Graphs", summary: "Introduction to graph theory and essential algorithms." }, + // Add more blog posts here + ]; + + const filteredPosts = blogPosts.filter((post) => { + const matchesTag = selectedTag === "All" || post.tag === selectedTag; + const matchesSearch = post.title.toLowerCase().includes(searchTerm.toLowerCase()); + return matchesTag && matchesSearch; + }); + + const tags = ["All", "Theory", "Sorting", "Graphs"]; + + return ( + +
+
+ + Blogs + + + +
+ + setSearchTerm(e.target.value)} + className="pl-10 p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400" + /> +
+
+ + +
+
+ + {/* Blog Posts List */} + + {filteredPosts.map((post) => ( + +

+ {post.title} +

+

{post.summary}

+ +
+ ))} +
+
+
+
+ ); +}; + +export default Blogs; \ No newline at end of file diff --git a/src/pages/Challenges/index.tsx b/src/pages/Challenges/index.tsx new file mode 100644 index 000000000..5cd66367f --- /dev/null +++ b/src/pages/Challenges/index.tsx @@ -0,0 +1,59 @@ +import React from "react"; +import { motion } from "framer-motion"; +import { FaClock, FaTrophy } from "react-icons/fa"; +import Layout from "@theme/Layout"; + +const Challenges: React.FC = () => { + return ( + +
+
+ + Coding Challenges + + + + Push your coding limits by participating in timed coding challenges. + + +
+ {/* Example Challenge */} + +

+ Challenge 1: 30-Minute Problem +

+

+ Solve the problem within 30 minutes to earn points and rank up. +

+
+ + Time Limit: 30 min +
+ +
+ + {/* More Challenges */} +
+
+
+
+ ); +}; + +export default Challenges; \ No newline at end of file diff --git a/src/pages/Community/index.tsx b/src/pages/Community/index.tsx new file mode 100644 index 000000000..c574296dc --- /dev/null +++ b/src/pages/Community/index.tsx @@ -0,0 +1,55 @@ +import Layout from "@theme/Layout"; +import React from "react"; +import { motion } from "framer-motion"; +import { FaComment, FaUsers } from "react-icons/fa"; + +const Community: React.FC = () => { + return ( + +
+
+ + Join the Community + + + + Engage with fellow learners, share ideas, and help each other + improve. + + + + +

+ Become a part of our growing community! +

+

+ Start discussions, ask questions, and collaborate with others. +

+ +
+
+
+
+ ); +}; + +export default Community; diff --git a/src/pages/Leaderboard/index.tsx b/src/pages/Leaderboard/index.tsx new file mode 100644 index 000000000..28c7e19a3 --- /dev/null +++ b/src/pages/Leaderboard/index.tsx @@ -0,0 +1,68 @@ +import Layout from "@theme/Layout"; +import React from "react"; +import { motion } from "framer-motion"; +import { FaCrown } from "react-icons/fa"; + +const Leaderboard: React.FC = () => { + const leaders = [ + { name: "Ajay Dhangar", points: 1500, rank: 1 }, + { name: "Jane Doe", points: 1450, rank: 2 }, + { name: "John Smith", points: 1420, rank: 3 }, + // Add more users + ]; + + return ( + +
+
+ + Leaderboard + + + + See where you rank against other coders! + + +
+ + + + + + + + + + {leaders.map((leader) => ( + + + + + + ))} + +
RankNamePoints
+ {leader.rank === 1 ? ( + + ) : ( + leader.rank + )} + {leader.name}{leader.points}
+
+
+
+
+ ); +}; + +export default Leaderboard; \ No newline at end of file diff --git a/src/pages/License.md b/src/pages/License.md new file mode 100644 index 000000000..bbc520825 --- /dev/null +++ b/src/pages/License.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Ajay Dhangar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/src/pages/Practice/index.tsx b/src/pages/Practice/index.tsx new file mode 100644 index 000000000..20f6f8101 --- /dev/null +++ b/src/pages/Practice/index.tsx @@ -0,0 +1,74 @@ +import React from "react"; +import { LayoutGroup, motion } from "framer-motion"; +import { FaPlayCircle } from "react-icons/fa"; +import Layout from "@theme/Layout"; + +const Practice: React.FC = () => { + return ( + +
+
+ + Practice Your Skills + + + + Sharpen your coding skills with hundreds of algorithm problems to practice. + + +
+ {/* Example Practice Problem */} + +

+ Problem 1: Two Sum +

+

+ Given an array of integers, return indices of the two numbers such that they add up to a specific target. +

+ +
+ + {/* Example Problem 2 */} + +

+ Problem 2: Longest Substring Without Repeating Characters +

+

+ Find the length of the longest substring without repeating characters. +

+ +
+ + {/* Add more problems as needed */} +
+
+
+
+ ); +}; + +export default Practice; \ No newline at end of file diff --git a/src/pages/Resources/index.tsx b/src/pages/Resources/index.tsx new file mode 100644 index 000000000..d540e141f --- /dev/null +++ b/src/pages/Resources/index.tsx @@ -0,0 +1,58 @@ +import React from "react"; +import Layout from "@theme/Layout"; +import { motion } from "framer-motion"; + +const resources = [ + { id: 1, title: "Introduction to Algorithms by CLRS", type: "Book", description: "One of the most comprehensive algorithm books.", link: "#" }, + { id: 2, title: "LeetCode", type: "Website", description: "A platform for practicing algorithms with real problems.", link: "#" }, + { id: 3, title: "Coursera: Algorithmic Toolbox", type: "Course", description: "An introductory course for algorithms.", link: "#" }, + // Add more resources +]; + +const Resources: React.FC = () => { + return ( + +
+
+ + Resources + + + + {resources.map((resource) => ( + +

+ {resource.title} +

+

{resource.description}

+
+ Access + + + ))} + +
+
+ + ); +}; + +export default Resources; \ No newline at end of file diff --git a/src/pages/Roadmap/index.tsx b/src/pages/Roadmap/index.tsx new file mode 100644 index 000000000..def41a551 --- /dev/null +++ b/src/pages/Roadmap/index.tsx @@ -0,0 +1,121 @@ +import React from "react"; +import { motion } from "framer-motion"; +import Layout from "@theme/Layout"; + +interface Milestone { + title: string; + description: string; + status: "planned" | "in-progress" | "completed"; +} + +const milestones: Milestone[] = [ + { + title: "AI and Machine Learning Algorithms", + description: + "Integrate AI and machine learning algorithms to enhance the learning experience and provide advanced problem-solving tools.", + status: "planned", + }, + { + title: "Performance Benchmarking", + description: + "Implement performance benchmarking tools to compare different algorithm implementations across various metrics.", + status: "in-progress", + }, + { + title: "Support for Additional Languages", + description: + "Expand support for more programming languages such as Go, Rust, and Kotlin to cater to a broader developer audience.", + status: "planned", + }, + { + title: "Interactive Visualizations", + description: + "Develop interactive visualizations for algorithm performance and execution flow to aid in deeper understanding.", + status: "planned", + }, + { + title: "Mobile Application", + description: + "Launch a mobile application version of Algo to provide on-the-go access to tutorials, algorithms, and contributions.", + status: "completed", + }, +]; + +const Roadmap: React.FC = () => { + const getStatusColor = (status: string) => { + switch (status) { + case "completed": + return "text-green-500"; + case "in-progress": + return "text-yellow-500"; + case "planned": + return "text-blue-500"; + default: + return "text-gray-500"; + } + }; + + return ( + +
+ {/* Header Section */} +
+ + Our Roadmap + + + Discover the future plans and upcoming features for Algo. + +
+ + {/* Roadmap Items */} +
+ + {milestones.map((milestone, index) => ( + +
+ + • + +
+
+

{milestone.title}

+

{milestone.description}

+ + {milestone.status.replace("-", " ")} + +
+
+ ))} +
+
+
+
+ ); +}; + +export default Roadmap; \ No newline at end of file diff --git a/src/pages/faq/index.tsx b/src/pages/faq/index.tsx index 64b7f9b63..06c8e19b3 100644 --- a/src/pages/faq/index.tsx +++ b/src/pages/faq/index.tsx @@ -1,33 +1,94 @@ import React from "react"; -import GiscusComponent from "../../components/GiscusComponent"; +import { motion } from "framer-motion"; +import Layout from "@theme/Layout"; -/** - * FAQ Page - * - * This component renders the Q&A section of the website where users can ask and answer questions - * using the Giscus GitHub Discussions widget. - * - * @returns {JSX.Element} The rendered Q&A page component - */ -const FAQ: React.FC = () => { +interface FAQItem { + question: string; + answer: string; +} + +const faqs: FAQItem[] = [ + { + question: "What is Algo?", + answer: + "Algo is an open-source platform designed to help developers learn, implement, and contribute to algorithmic solutions across various programming languages.", + }, + { + question: "How can I contribute to Algo?", + answer: + "You can contribute by submitting pull requests to our GitHub repository, adding new algorithms, improving existing ones, or enhancing the documentation.", + }, + { + question: "Do I need prior experience to contribute?", + answer: + "No prior experience is required! We welcome contributors of all skill levels. Whether you're a beginner or an experienced developer, your contributions are valuable.", + }, + { + question: "How can I get support?", + answer: + "You can reach out to us via our Discord community, submit issues on GitHub, or contact us directly through the Contact page.", + }, + { + question: "Where can I practice algorithms?", + answer: + "You can practice algorithms on websites like LeetCode, Codeforces, and CodeHarborHub.", + }, + // Add more FAQs +]; + +const FAQ: React.FC = () => { return ( -
-
-
-

+ +
+ {/* Header Section */} +
+ Frequently Asked Questions -

-

- Have any questions about Algo? Feel free to ask, and our community will help! -

-
+ + + Find answers to the most common questions about Algo. + + -
- {/* */} -
+ {/* FAQ Items */} +
+ + {faqs.map((faq, index) => ( + +

+ {faq.question} +

+

{faq.answer}

+
+ ))} +
+
-
+ ); }; -export default FAQ; \ No newline at end of file +export default FAQ;