diff --git a/dsa-solutions/gfg-solutions/0023-Find-triplet-with-zero-sum.md b/dsa-solutions/gfg-solutions/0023-Find-triplet-with-zero-sum.md
index c233a16b8..6f4d0d97e 100644
--- a/dsa-solutions/gfg-solutions/0023-Find-triplet-with-zero-sum.md
+++ b/dsa-solutions/gfg-solutions/0023-Find-triplet-with-zero-sum.md
@@ -56,6 +56,7 @@ You don't need to read input or print anything. Your task is to complete the fun
### Constraints
+
- $1 ≤ N ≤ 10^5$
- $-10^3 ≤ arr[i] ≤ 10^3$
diff --git a/dsa-solutions/gfg-solutions/0024-minimum-indexed-character.md b/dsa-solutions/gfg-solutions/0024-minimum-indexed-character.md
index f15b7dc58..2d1b5ac8d 100644
--- a/dsa-solutions/gfg-solutions/0024-minimum-indexed-character.md
+++ b/dsa-solutions/gfg-solutions/0024-minimum-indexed-character.md
@@ -50,12 +50,13 @@ There are no characters that are common in "patt" and "str".
### Your Task
You only need to complete the function `minIndexChar()` that returns the index of the answer in `str` or returns `-1` if no character of `patt` is present in `str`.
-**Expected Time Complexity:** O(N)
-**Expected Auxiliary Space:** O(Number of distinct characters)
+**Expected Time Complexity:** $O(N)$
+**Expected Auxiliary Space:** $O(Number of distinct characters)$
### Constraints
-- 1 ≤ |str|,|patt| ≤ 10^5
-- 'a' ≤ str[i], patt[i] ≤ 'z'
+
+- $1 ≤ |str|,|patt| ≤ 10^5$
+- $'a' ≤ str[i], patt[i] ≤ 'z'$
## Solution
@@ -169,8 +170,8 @@ class Solution {
### Complexity Analysis
-- **Time Complexity:** O(N), where N is the length of the string `str`. We iterate through each character in `patt` and use the `find` or `indexOf` method, which runs in O(N) time.
-- **Space Complexity:** O(1), as we only use a constant amount of extra space for variables.
+- **Time Complexity:** $O(N)$, where N is the length of the string `str`. We iterate through each character in `patt` and use the `find` or `indexOf` method, which runs in $O(N)$ time.
+- **Space Complexity:** $O(1)$, as we only use a constant amount of extra space for variables.
---
diff --git a/dsa-solutions/gfg-solutions/Easy problems/bfs-of-graph.md b/dsa-solutions/gfg-solutions/Easy problems/bfs-of-graph.md
new file mode 100644
index 000000000..1acd8e44e
--- /dev/null
+++ b/dsa-solutions/gfg-solutions/Easy problems/bfs-of-graph.md
@@ -0,0 +1,222 @@
+---
+id: bfs-of-graph
+title: BFS of Graph
+sidebar_label: 8 BFS of Graph
+tags:
+- Graph
+- BFS
+- Python
+- Java
+- C++
+- JavaScript
+- TypeScript
+description: "This document provides solutions to the problem of performing a Breadth First Search (BFS) traversal of a directed graph in various programming languages."
+---
+
+## Problem
+
+Given a directed graph, perform a Breadth First Traversal starting from the 0th vertex. One can move from node `u` to node `v` only if there's an edge from `u` to `v`. Find the BFS traversal of the graph starting from the 0th vertex, from left to right according to the input graph. Only consider nodes that are directly or indirectly connected to node `0`.
+
+### Examples
+
+**Example 1:**
+
+```
+Input: V = 5, E = 4, adj = {{1,2,3},{},{4},{},{}}
+Output: 0 1 2 3 4
+Explanation:
+0 is connected to 1, 2, 3.
+2 is connected to 4.
+Starting from 0, it will go to 1 then 2 then 3. After this, 2 to 4, thus BFS will be 0 1 2 3 4.
+```
+
+**Example 2:**
+
+```
+Input: V = 3, E = 2, adj = {{1,2},{},{}}
+Output: 0 1 2
+Explanation:
+0 is connected to 1, 2.
+Starting from 0, it will go to 1 then 2, thus BFS will be 0 1 2.
+```
+
+### Your Task
+
+You don't need to read input or print anything. Your task is to complete the function `bfsOfGraph()` which takes the integer `V` denoting the number of vertices and adjacency list as input parameters and returns a list containing the BFS traversal of the graph starting from the 0th vertex from left to right.
+
+**Expected Time Complexity:** $O(V + E)$
+**Expected Auxiliary Space:** $O(V)$
+
+**Constraints**
+- $1 ≤ V, E ≤ 10^4$
+
+## Solution
+
+### Intuition & Approach
+
+Breadth First Search (BFS) is a method to traverse a graph level by level, starting from a given node. We use a queue data structure to facilitate this traversal. The main steps are:
+
+1. Create a boolean list `visited` to mark all vertices as not visited.
+2. Initialize the traversal from the starting vertex (0th vertex).
+3. Use a queue to explore nodes level by level, marking each node as visited once it is processed.
+4. For each node, explore its adjacent vertices that have not been visited yet, marking them as visited and adding them to the queue.
+5. Continue this process until the queue is empty.
+
+### Implementation
+
+
+
+
+```python
+from collections import deque
+
+class Solution:
+
+ def bfsOfGraph(self, V, adj):
+ visited = [False] * V
+ queue = deque([0])
+ visited[0] = True
+ result = []
+
+ while queue:
+ node = queue.popleft()
+ result.append(node)
+ for neighbor in adj[node]:
+ if not visited[neighbor]:
+ queue.append(neighbor)
+ visited[neighbor] = True
+ return result
+```
+
+
+
+
+```java
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.Queue;
+
+class Solution {
+ public ArrayList bfsOfGraph(int V, ArrayList> adj) {
+ ArrayList traversal = new ArrayList<>();
+ Queue queue = new LinkedList<>();
+ boolean[] visited = new boolean[V];
+ queue.add(0);
+ visited[0] = true;
+
+ while (!queue.isEmpty()) {
+ int node = queue.poll();
+ traversal.add(node);
+ for (int neighbor : adj.get(node)) {
+ if (!visited[neighbor]) {
+ queue.add(neighbor);
+ visited[neighbor] = true;
+ }
+ }
+ }
+ return traversal;
+ }
+}
+```
+
+
+
+
+```cpp
+#include
+#include
+
+class Solution {
+public:
+ std::vector bfsOfGraph(int V, std::vector adj[]) {
+ std::vector result;
+ std::vector visited(V, false);
+ std::queue q;
+
+ q.push(0);
+ visited[0] = true;
+
+ while (!q.empty()) {
+ int node = q.front();
+ q.pop();
+ result.push_back(node);
+ for (int neighbor : adj[node]) {
+ if (!visited[neighbor]) {
+ q.push(neighbor);
+ visited[neighbor] = true;
+ }
+ }
+ }
+ return result;
+ }
+};
+```
+
+
+
+
+```javascript
+class Solution {
+ bfsOfGraph(V, adj) {
+ let visited = new Array(V).fill(false);
+ let queue = [0];
+ visited[0] = true;
+ let result = [];
+
+ while (queue.length > 0) {
+ let node = queue.shift();
+ result.push(node);
+ for (let neighbor of adj[node]) {
+ if (!visited[neighbor]) {
+ queue.push(neighbor);
+ visited[neighbor] = true;
+ }
+ }
+ }
+ return result;
+ }
+}
+```
+
+
+
+
+```typescript
+class Solution {
+ bfsOfGraph(V: number, adj: number[][]): number[] {
+ let visited = new Array(V).fill(false);
+ let queue: number[] = [0];
+ visited[0] = true;
+ let result: number[] = [];
+
+ while (queue.length > 0) {
+ let node = queue.shift() as number;
+ result.push(node);
+ for (let neighbor of adj[node]) {
+ if (!visited[neighbor]) {
+ queue.push(neighbor);
+ visited[neighbor] = true;
+ }
+ }
+ }
+ return result;
+ }
+}
+```
+
+
+
+
+---
+
+## Complexity analysis
+
+The provided solutions efficiently perform a Breadth First Search (BFS) traversal of a directed graph. By starting from the 0th vertex and using a queue to manage the traversal, the algorithms ensure that all reachable vertices are visited in the correct order. The solutions operate in $O(V + E)$ time and use $O(V)$ space complexity, where V and E are the numbers of vertices and edges in the graph, respectively.
+
+**Time Complexity:** $O(V + E)$
+**Auxiliary Space:** $O(V)$
+
+## References
+
+- **GeeksforGeeks Problem:** [BFS of graph](https://www.geeksforgeeks.org/problems/bfs-traversal-of-graph/0)
+- **Author GeeksforGeeks Profile:** [GeeksforGeeks](https://www.geeksforgeeks.org/user/GeeksforGeeks/)
\ No newline at end of file
diff --git a/dsa-solutions/gfg-solutions/Easy problems/check-for-balanced-tree.md b/dsa-solutions/gfg-solutions/Easy problems/check-for-balanced-tree.md
new file mode 100644
index 000000000..6b49186e0
--- /dev/null
+++ b/dsa-solutions/gfg-solutions/Easy problems/check-for-balanced-tree.md
@@ -0,0 +1,255 @@
+---
+id: check-for-balanced-tree
+title: Check for balanced Tree
+sidebar_label: 4 Check for balanced tree
+tags:
+ - Binary Tree
+ - Depth-First Search
+ - Recursion
+ - LeetCode
+ - C++
+ - Java
+ - Python
+description: "This is a solution to the Balanced Binary Tree problem on LeetCode."
+---
+
+## Problem Description
+
+Given a binary tree, determine if it is height-balanced.
+
+A height-balanced binary tree is defined as:
+
+- A binary tree in which the left and right subtrees of every node differ in height by no more than 1.
+
+### Examples
+
+**Example 1:**
+
+
+
+```
+Input: root = [3,9,20,null,null,15,7]
+Output: true
+```
+
+**Example 2:**
+
+
+```
+Input: root = [1,2,2,3,3,null,null,4,4]
+Output: false
+```
+
+**Example 3:**
+
+```
+Input: root = []
+Output: true
+```
+
+### Constraints
+
+- The number of nodes in the tree is in the range `[0, 5000]`.
+- $-10^4 <=$ Node.val $<= 10^4$
+
+---
+
+## Solution for Balanced Binary Tree Problem
+
+
+
+
+### Approach 1: Top-Down
+
+#### Intuition
+
+This method checks whether the tree is balanced strictly according to the definition of a balanced binary tree: the difference between the heights of the two subtrees is not greater than 1, and both the left and right subtrees are also balanced. With the helper function depth(), we can easily write the code.
+
+#### Implementation
+
+Implement a helper function `depth(root)` that returns the depth of the tree rooted at root.
+Check if the absolute difference between the depths of the left and right subtrees is not greater than 1.
+Recursively check if both the left and right subtrees are balanced.
+Return true if the tree is balanced, otherwise return false.
+
+#### Code in Different Languages
+
+
+
+
+ ```java
+ class Solution {
+ public int depth(TreeNode root) {
+ if (root == null) return 0;
+ return Math.max(depth(root.left), depth(root.right)) + 1;
+ }
+
+ public boolean isBalanced(TreeNode root) {
+ if (root == null) return true;
+
+ int left = depth(root.left);
+ int right = depth(root.right);
+
+ return Math.abs(left - right) <= 1 && isBalanced(root.left) && isBalanced(root.right);
+ }
+ }
+ ```
+
+
+
+
+ ```python
+ class Solution:
+ def depth(self, root: TreeNode) -> int:
+ if root is None:
+ return 0
+ return max(self.depth(root.left), self.depth(root.right)) + 1
+
+ def isBalanced(self, root: TreeNode) -> bool:
+ if root is None:
+ return True
+
+ left = self.depth(root.left)
+ right = self.depth(root.right)
+
+ return abs(left - right) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right)
+ ```
+
+
+
+
+ ```cpp
+ class Solution {
+ public:
+ int depth(TreeNode* root) {
+ if (root == nullptr) return 0;
+ return max(depth(root->left), depth(root->right)) + 1;
+ }
+
+ bool isBalanced(TreeNode* root) {
+ if (root == nullptr) return true;
+
+ int left = depth(root->left);
+ int right = depth(root->right);
+
+ return abs(left - right) <= 1 && isBalanced(root->left) && isBalanced(root->right);
+ }
+ };
+ ```
+
+
+
+
+#### Complexity Analysis
+
+- **Time Complexity**: O(n log n) in the worst case where n is the number of nodes in the tree. We visit each node once, and for each node, we calculate its depth. Since the depth calculation involves traversing the subtree, the overall time complexity is O(n log n).
+- **Space Complexity**: O(n) for the recursive call stack.
+
+
+
+
+### Approach 2: Bottom-Up
+
+#### Intuition
+
+The second method is based on DFS. Instead of calling depth() explicitly for each child node, we return the height of the current node in DFS recursion. When the subtree of the current node (inclusive) is balanced, the function dfsHeight() returns a non-negative value as the height. Otherwise, -1 is returned. According to the left height and right height of the two children, the parent node could check if the subtree is balanced and decide its return value.
+
+#### Implementation
+
+Implement a helper function dfsHeight(root) that returns the height of the tree rooted at root.
+If the subtree rooted at root is balanced, return its height. Otherwise, return -1.
+Check if the returned height is -1 to determine if the tree is balanced.
+
+#### Code in Different Languages
+
+
+
+
+ ```java
+ class Solution {
+ public int dfsHeight(TreeNode root) {
+ if (root == null) return 0;
+
+ int leftHeight = dfsHeight(root.left);
+ if (leftHeight == -1) return -1;
+ int rightHeight = dfsHeight(root.right);
+ if (rightHeight == -1) return -1;
+
+ if (Math.abs(leftHeight - rightHeight) > 1) return -1;
+ return Math.max(leftHeight, rightHeight) + 1;
+ }
+
+ public boolean isBalanced(TreeNode root) {
+ return dfsHeight(root) != -1;
+ }
+ }
+ ```
+
+
+
+
+ ```python
+ class Solution:
+ def dfsHeight(self, root: TreeNode) -> int:
+ if root is None:
+ return 0
+
+ leftHeight = self.dfsHeight(root.left)
+ if leftHeight == -1:
+ return -1
+ right
+
+ Height = self.dfsHeight(root.right)
+ if rightHeight == -1:
+ return -1
+
+ if abs(leftHeight - rightHeight) > 1:
+ return -1
+ return max(leftHeight, rightHeight) + 1
+
+ def isBalanced(self, root: TreeNode) -> bool:
+ return self.dfsHeight(root) != -1
+ ```
+
+
+
+
+ ```cpp
+ class Solution {
+ public:
+ int dfsHeight(TreeNode* root) {
+ if (root == nullptr) return 0;
+
+ int leftHeight = dfsHeight(root->left);
+ if (leftHeight == -1) return -1;
+ int rightHeight = dfsHeight(root->right);
+ if (rightHeight == -1) return -1;
+
+ if (abs(leftHeight - rightHeight) > 1) return -1;
+ return max(leftHeight, rightHeight) + 1;
+ }
+
+ bool isBalanced(TreeNode* root) {
+ return dfsHeight(root) != -1;
+ }
+ };
+ ```
+
+
+
+
+#### Complexity Analysis
+
+- **Time Complexity**: O(n) in the worst case where n is the number of nodes in the tree. Each node is visited once.
+- **Space Complexity**: O(n) for the recursive call stack.
+
+
+
+
+---
+
+## References
+
+- **GFG Problem**: [Check for Balanced Tree](https://www.geeksforgeeks.org/problems/check-for-balanced-tree/0)
+- **Author GeeksforGeeks Profile:** [GeeksforGeeks](https://www.geeksforgeeks.org/user/GeeksforGeeks/)
+
diff --git a/dsa-solutions/gfg-solutions/Easy problems/delete-middle-of-linked-list.md b/dsa-solutions/gfg-solutions/Easy problems/delete-middle-of-linked-list.md
new file mode 100644
index 000000000..27f5431c3
--- /dev/null
+++ b/dsa-solutions/gfg-solutions/Easy problems/delete-middle-of-linked-list.md
@@ -0,0 +1,175 @@
+---
+id: delete-middle-of-linked-list
+title: Delete Middle of Linked List
+sidebar_label: 5 Delete Middle of Linked List
+tags:
+- Linked List
+- Python
+- Java
+- C++
+- JavaScript
+- TypeScript
+description: "This document provides solutions to the problem of deleting the middle node from a singly linked list in various programming languages."
+---
+
+## Problem
+
+Given a singly linked list, delete the middle of the linked list. For example, if given linked list is 1->2->3->4->5 then linked list should be modified to 1->2->4->5.
+If there are even nodes, then there would be two middle nodes, we need to delete the second middle element. For example, if given linked list is 1->2->3->4->5->6 then it should be modified to 1->2->3->5->6.
+If the input linked list has a single node, then it should return NULL.
+
+### Examples
+
+**Example 1:**
+
+```
+Input:
+LinkedList: 1->2->3->4->5
+Output:
+1 2 4 5
+```
+
+**Example 2:**
+
+```
+Input:
+LinkedList: 2->4->6->7->5->1
+Output:
+2 4 6 5 1
+```
+
+### Your Task
+The task is to complete the function `deleteMid()` which takes head of the linked list and returns head of the linked list with the middle element deleted. If the linked list is empty or contains a single element, then it should return NULL.
+
+**Expected Time Complexity:** $O(n)$
+**Expected Auxiliary Space:** $O(1)$
+
+### Constraints
+- $1 ≤ n ≤ 10^5$
+- $1 ≤ value[i] ≤ 10^9$
+
+## Solution
+
+### Intuition & Approach
+
+The simplest idea is to make two pointers, `fast` and `slow`. Increment the `fast` pointer by two steps and the `slow` pointer by one step until the `fast` pointer reaches the end of the linked list. By then, the `slow` pointer will have reached the exact middle of the list.
+
+To delete the middle node, ensure that the `slow` pointer is at the node just before the middle. This can be done by starting the `fast` pointer from the second node instead of the first. Then, skip the middle node by changing the `next` pointer of the `slow` node to `slow->next->next` or `slow.next.next`.
+
+**Edge Case:** If there is only one node in the linked list, return NULL or None.
+
+### Complexity
+- **Time Complexity:** $O(n)$- **Space Complexity:** O(1)
+
+### Implementation
+
+
+
+
+```python
+class Solution:
+ def deleteMid(self, head):
+ if not head.next:
+ return None
+ slow, fast = head, head.next
+ while fast and fast.next and fast.next.next:
+ fast = fast.next.next
+ slow = slow.next
+ slow.next = slow.next.next
+ return head
+```
+
+
+
+
+```java
+class Solution {
+ public ListNode deleteMid(ListNode head) {
+ if (head == null || head.next == null) {
+ return null;
+ }
+ ListNode slow = head, fast = head.next;
+ while (fast != null && fast.next != null && fast.next.next != null) {
+ fast = fast.next.next;
+ slow = slow.next;
+ }
+ slow.next = slow.next.next;
+ return head;
+ }
+}
+```
+
+
+
+
+```cpp
+class Solution {
+public:
+ ListNode* deleteMid(ListNode* head) {
+ if (head->next == nullptr) {
+ return nullptr;
+ }
+ ListNode* slow = head;
+ ListNode* fast = head->next;
+ while (fast != nullptr && fast->next != nullptr && fast->next->next != nullptr) {
+ fast = fast->next->next;
+ slow = slow->next;
+ }
+ slow->next = slow->next->next;
+ return head;
+ }
+};
+```
+
+
+
+
+```javascript
+function deleteMid(head) {
+ if (!head.next) {
+ return null;
+ }
+ let slow = head, fast = head.next;
+ while (fast !== null && fast.next !== null && fast.next.next !== null) {
+ fast = fast.next.next;
+ slow = slow.next;
+ }
+ slow.next = slow.next.next;
+ return head;
+}
+```
+
+
+
+
+```typescript
+function deleteMid(head: ListNode | null): ListNode | null {
+ if (!head || !head.next) {
+ return null;
+ }
+ let slow: ListNode | null = head, fast: ListNode | null = head.next;
+ while (fast !== null && fast.next !== null && fast.next.next !== null) {
+ fast = fast.next.next;
+ slow = slow.next;
+ }
+ if (slow && slow.next) {
+ slow.next = slow.next.next;
+ }
+ return head;
+}
+```
+
+
+
+
+### Complexity
+- **Time Complexity:** $O(n)$
+- **Space Complexity:** $O(1)$
+
+---
+
+## References
+
+- **GeeksforGeeks Problem:** [Delete Middle of Linked List](https://www.geeksforgeeks.org/problems/delete-middle-of-linked-list/0)
+- **Author GeeksforGeeks Profile:** [GeeksforGeeks](https://www.geeksforgeeks.org/user/GeeksforGeeks/)
+
diff --git a/dsa-solutions/gfg-solutions/Easy problems/delete-without-head-pointer.md b/dsa-solutions/gfg-solutions/Easy problems/delete-without-head-pointer.md
new file mode 100644
index 000000000..777486a10
--- /dev/null
+++ b/dsa-solutions/gfg-solutions/Easy problems/delete-without-head-pointer.md
@@ -0,0 +1,224 @@
+---
+id: delete-without-head-pointer
+title: Delete without Head Pointer
+sidebar_label: 3 Delete without Head Pointer
+tags:
+- Linked List
+- Python
+- Java
+- C++
+- JavaScript
+- TypeScript
+description: "This document provides solutions to the problem of deleting a node from a singly linked list without having a reference to the head pointer in various programming languages."
+---
+
+## Problem
+
+You are given a node `del_node` of a Singly Linked List where you have to delete a value of the given node from the linked list, but you are not given the head of the list.
+
+By deleting the node value, we mean that:
+- The value of the given node should not exist in the linked list.
+- The number of nodes in the linked list should decrease by one.
+- All the values before and after the `del_node` node should be in the same order.
+
+Note:
+- Multiple nodes can have the same values as the `del_node`, but you must only remove the node whose pointer `del_node` is given to you.
+- It is guaranteed that there exists a node with a value equal to the `del_node` value, and it will not be the last node of the linked list.
+
+### Examples
+
+**Example 1:**
+
+```
+Input:
+Linked List = 1 -> 2
+del_node = 1
+Output:
+2
+
+Explanation:
+After deleting 1 from the linked list,
+we have remaining nodes as 2.
+```
+
+**Example 2:**
+
+```
+Input:
+Linked List = 10 -> 20 -> 4 -> 30
+del_node = 20
+Output:
+10 4 30
+
+Explanation:
+After deleting 20 from the linked list,
+we have remaining nodes as 10, 4, 30.
+```
+
+### Your Task
+You don't need to read or print anything. You only need to complete the function `deleteNode()` which takes a reference of the deleting node value and your task is to delete the given node value.
+
+**Expected Time Complexity:** $O(1)$
+**Expected Auxiliary Space:** $O(1)$
+
+### Constraints
+- $2 ≤ n ≤ 10^3$
+- $1 ≤ elements of the linked list ≤ 10^9$
+
+## Solution
+
+### Approach
+
+To delete a node without a reference to the head pointer, we can mimic the effect of deleting the node by copying the value of the next node to the given node (`del_node`) and then deleting the next node.
+
+### Implementation
+
+
+
+
+```python
+class Solution:
+
+ def reverseDLL(self, head):
+ while head:
+ head.next, head.prev = head.prev, head.next
+ if not head.prev:return head
+ head=head.prev
+```
+
+
+
+
+```java
+class Node {
+ int data;
+ Node next;
+ Node prev;
+
+ Node(int data) {
+ this.data = data;
+ this.next = null;
+ this.prev = null;
+ }
+}
+
+class Solution {
+ public Node reverseDLL(Node head) {
+ while (head != null) {
+ Node temp = head.next;
+ head.next = head.prev;
+ head.prev = temp;
+ if (head.prev == null) {
+ return head;
+ }
+ head = head.prev;
+ }
+ return head;
+ }
+}
+```
+
+
+
+
+```cpp
+#include
+using namespace std;
+
+class Node {
+public:
+ int data;
+ Node* next;
+ Node* prev;
+ Node(int data) {
+ this->data = data;
+ this->next = nullptr;
+ this->prev = nullptr;
+ }
+};
+
+class Solution {
+public:
+ Node* reverseDLL(Node* head) {
+ while (head != nullptr) {
+ swap(head->next, head->prev);
+ if (head->prev == nullptr) {
+ return head;
+ }
+ head = head->prev;
+ }
+ return head;
+ }
+};
+```
+
+
+
+
+```javascript
+class Node {
+ constructor(data) {
+ this.data = data;
+ this.next = null;
+ this.prev = null;
+ }
+}
+
+class Solution {
+ reverseDLL(head) {
+ while (head !== null) {
+ [head.next, head.prev] = [head.prev, head.next];
+ if (head.prev === null) {
+ return head;
+ }
+ head = head.prev;
+ }
+ return head;
+ }
+}
+```
+
+
+
+
+```typescript
+class Node {
+ data: number;
+ next: Node | null;
+ prev: Node | null;
+
+ constructor(data: number) {
+ this.data = data;
+ this.next = null;
+ this.prev = null;
+ }
+}
+
+class Solution {
+ reverseDLL(head: Node | null): Node | null {
+ while (head !== null) {
+ [head.next, head.prev] = [head.prev, head.next];
+ if (head.prev === null) {
+ return head;
+ }
+ head = head.prev;
+ }
+ return head;
+ }
+}
+```
+
+
+
+
+### Complexity Analysis
+
+- **Time Complexity:** $O(1)$, as the deletion operation requires constant time regardless of the size of the linked list.
+- **Space Complexity:** $O(1)$, as the algorithm uses only a constant amount of extra space regardless of the input size.
+
+---
+
+## References
+
+- **GeeksforGeeks Problem:** [Delete without head pointer](https://www.geeksforgeeks.org/problems/delete-without-head-pointer/0)
+- **Author GeeksforGeeks Profile:** [GeeksforGeeks](https://www.geeksforgeeks.org/user/GeeksforGeeks/)
diff --git a/dsa-solutions/gfg-solutions/Easy problems/dfs-of-graph.md b/dsa-solutions/gfg-solutions/Easy problems/dfs-of-graph.md
new file mode 100644
index 000000000..9ab48b3e5
--- /dev/null
+++ b/dsa-solutions/gfg-solutions/Easy problems/dfs-of-graph.md
@@ -0,0 +1,204 @@
+---
+id: dfs-of-graph
+title: DFS of Graph
+sidebar_label: 7 DFS of Graph
+tags:
+- Graph
+- DFS
+- Python
+- Java
+- C++
+- JavaScript
+- TypeScript
+description: "This document provides solutions to the problem of performing a Depth First Search (DFS) traversal of a connected undirected graph in various programming languages."
+---
+
+## Problem
+
+You are given a connected undirected graph. Perform a Depth First Traversal of the graph. Use the recursive approach to find the DFS traversal of the graph starting from the 0th vertex from left to right according to the graph.
+
+### Examples
+
+**Example 1:**
+
+```
+Input: V = 5, adj = [[2,3,1], [0], [0,4], [0], [2]]
+Output: 0 2 4 3 1
+Explanation:
+0 is connected to 2, 3, 1.
+1 is connected to 0.
+2 is connected to 0 and 4.
+3 is connected to 0.
+4 is connected to 2.
+Starting from 0, it will go to 2 then 4, and then 3 and 1.
+Thus DFS will be 0 2 4 3 1.
+```
+
+**Example 2:**
+
+```
+Input: V = 4, adj = [[1,3], [2,0], [1], [0]]
+Output: 0 1 2 3
+Explanation:
+0 is connected to 1, 3.
+1 is connected to 0, 2.
+2 is connected to 1.
+3 is connected to 0.
+Starting from 0, it will go to 1 then 2, then back to 0 then 0 to 3.
+Thus DFS will be 0 1 2 3.
+```
+
+### Your Task
+
+You don't need to read input or print anything. Your task is to complete the function `dfsOfGraph()` which takes the integer `V` denoting the number of vertices and adjacency list as input parameters and returns a list containing the DFS traversal of the graph starting from the 0th vertex from left to right according to the graph.
+
+- **Expected Time Complexity:** $O(V + E)$
+- **Expected Auxiliary Space:** $O(V)$
+
+**Constraints**
+- $ 1 ≤ V, E ≤ 10^4 $
+
+## Solution
+
+### Intuition & Approach
+
+To perform a Depth First Search (DFS) traversal of a graph, we can use a recursive approach. Starting from the 0th vertex, we visit each vertex and recursively explore its adjacent vertices that have not been visited yet. By keeping track of visited vertices, we ensure that each vertex is visited only once.
+
+### Implementation
+
+
+
+
+```python
+class Solution:
+
+ def dfsOfGraph(self, V, adj):
+ visited = [False] * V
+ result = []
+ self.dfs(0, adj, visited, result)
+ return result
+
+ def dfs(self, node, adj, visited, result):
+ visited[node] = True
+ result.append(node)
+ for neighbor in adj[node]:
+ if not visited[neighbor]:
+ self.dfs(neighbor, adj, visited, result)
+```
+
+
+
+
+```java
+import java.util.ArrayList;
+import java.util.List;
+
+class Solution {
+ public List dfsOfGraph(int V, ArrayList> adj) {
+ boolean[] visited = new boolean[V];
+ List result = new ArrayList<>();
+ dfs(0, adj, visited, result);
+ return result;
+ }
+
+ private void dfs(int node, ArrayList> adj, boolean[] visited, List result) {
+ visited[node] = true;
+ result.add(node);
+ for (int neighbor : adj.get(node)) {
+ if (!visited[neighbor]) {
+ dfs(neighbor, adj, visited, result);
+ }
+ }
+ }
+}
+```
+
+
+
+
+```cpp
+#include
+
+class Solution {
+public:
+ void dfsOfGraph(int V, std::vector adj[], std::vector& result) {
+ std::vector visited(V, false);
+ dfs(0, adj, visited, result);
+ }
+
+private:
+ void dfs(int node, std::vector adj[], std::vector& visited, std::vector& result) {
+ visited[node] = true;
+ result.push_back(node);
+ for (int neighbor : adj[node]) {
+ if (!visited[neighbor]) {
+ dfs(neighbor, adj, visited, result);
+ }
+ }
+ }
+};
+```
+
+
+
+
+```javascript
+class Solution {
+ dfsOfGraph(V, adj) {
+ let visited = new Array(V).fill(false);
+ let result = [];
+ this.dfs(0, adj, visited, result);
+ return result;
+ }
+
+ dfs(node, adj, visited, result) {
+ visited[node] = true;
+ result.push(node);
+ for (let neighbor of adj[node]) {
+ if (!visited[neighbor]) {
+ this.dfs(neighbor, adj, visited, result);
+ }
+ }
+ }
+}
+```
+
+
+
+
+```typescript
+class Solution {
+ dfsOfGraph(V: number, adj: number[][]): number[] {
+ let visited = new Array(V).fill(false);
+ let result: number[] = [];
+ this.dfs(0, adj, visited, result);
+ return result;
+ }
+
+ private dfs(node: number, adj: number[][], visited: boolean[], result: number[]): void {
+ visited[node] = true;
+ result.push(node);
+ for (let neighbor of adj[node]) {
+ if (!visited[neighbor]) {
+ this.dfs(neighbor, adj, visited, result);
+ }
+ }
+ }
+}
+```
+
+
+
+
+
+### Complexity Analysis
+
+- **Time Complexity:** $ O(V + E) $
+- **Auxiliary Space:** $ O(V)$
+
+---
+
+## References
+
+- **GeeksforGeeks Problem:** [DFS of graph](https://www.geeksforgeeks.org/problems/depth-first-traversal-for-a-graph/0)
+- **Author GeeksforGeeks Profile:** [GeeksforGeeks](https://www.geeksforgeeks.org/user/GeeksforGeeks/)
diff --git a/dsa-solutions/gfg-solutions/Easy problems/implement-two-stacks-in-an-array.md b/dsa-solutions/gfg-solutions/Easy problems/implement-two-stacks-in-an-array.md
new file mode 100644
index 000000000..d910c5868
--- /dev/null
+++ b/dsa-solutions/gfg-solutions/Easy problems/implement-two-stacks-in-an-array.md
@@ -0,0 +1,349 @@
+---
+id: implement-two-stacks-in-an-array
+title: Implement Two Stacks in an Array
+sidebar_label: 10 Implement Two Stacks in an Array
+tags:
+- Data Structures
+- Stacks
+- Python
+- Java
+- C++
+- JavaScript
+- TypeScript
+description: "This document provides solutions to the problem of implementing two stacks in a single array using various programming languages."
+---
+
+## Problem
+
+Your task is to implement two stacks in one array efficiently. You need to implement four methods.
+
+- `twoStacks(n)`: Initialize the data structures and variables to be used to implement two stacks in one array.
+- `push1(x)`: Pushes element into the first stack.
+- `push2(x)`: Pushes element into the second stack.
+- `pop1()`: Pops element from the first stack and returns the popped element. If the first stack is empty, it should return -1.
+- `pop2()`: Pops element from the second stack and returns the popped element. If the second stack is empty, it should return -1.
+
+### Examples
+
+**Example 1:**
+
+```
+Input:
+push1(2)
+push1(3)
+push2(4)
+pop1()
+pop2()
+pop2()
+
+Output:
+3 4 -1
+
+Explanation:
+push1(2) -> stack1 = {2}
+push1(3) -> stack1 = {2, 3}
+push2(4) -> stack2 = {4}
+pop1() -> returns 3, stack1 = {2}
+pop2() -> returns 4, stack2 = {}
+pop2() -> stack2 is empty, returns -1
+```
+
+**Example 2:**
+
+```
+Input:
+push1(1)
+push2(2)
+pop1()
+push1(3)
+pop1()
+pop1()
+
+Output:
+1 3 -1
+
+Explanation:
+push1(1) -> stack1 = {1}
+push2(2) -> stack2 = {2}
+pop1() -> returns 1, stack1 = {}
+push1(3) -> stack1 = {3}
+pop1() -> returns 3, stack1 = {}
+pop1() -> stack1 is empty, returns -1
+```
+
+### Your Task
+
+You don't need to read input or print anything. You are required to complete the four methods `push1`, `push2`, `pop1`, and `pop2`.
+
+**Expected Time Complexity:** $O(1)$ for all the four methods.
+**Expected Auxiliary Space:** $O(1)$ for all the four methods.
+
+**Constraints**
+- 1 ≤ Number of queries ≤ 10^4
+- 1 ≤ Number of elements in the stack ≤ 100
+- The sum of the count of elements in both stacks < size of the given array
+
+## Solution
+
+### Intuition & Approach
+
+To efficiently implement two stacks in one array, we can start one stack from the beginning of the array and the other stack from the end of the array. This way, both stacks grow towards each other and we can manage them independently.
+
+### Implementation
+
+
+
+
+```python
+class TwoStacks:
+ def __init__(self, n=100):
+ self.size = n
+ self.arr = [0] * n
+ self.top1 = -1
+ self.top2 = n
+
+ # Function to push an integer into stack 1
+ def push1(self, x):
+ if self.top1 < self.top2 - 1:
+ self.top1 += 1
+ self.arr[self.top1] = x
+
+ # Function to push an integer into stack 2
+ def push2(self, x):
+ if self.top1 < self.top2 - 1:
+ self.top2 -= 1
+ self.arr[self.top2] = x
+
+ # Function to remove an element from top of stack 1
+ def pop1(self):
+ if self.top1 >= 0:
+ x = self.arr[self.top1]
+ self.top1 -= 1
+ return x
+ else:
+ return -1
+
+ # Function to remove an element from top of stack 2
+ def pop2(self):
+ if self.top2 < self.size:
+ x = self.arr[self.top2]
+ self.top2 += 1
+ return x
+ else:
+ return -1
+```
+
+
+
+
+```java
+class TwoStacks {
+ int size;
+ int top1, top2;
+ int arr[];
+
+ TwoStacks(int n) {
+ size = n;
+ arr = new int[n];
+ top1 = -1;
+ top2 = n;
+ }
+
+ void push1(int x) {
+ if (top1 < top2 - 1) {
+ top1++;
+ arr[top1] = x;
+ }
+ }
+
+ void push2(int x) {
+ if (top1 < top2 - 1) {
+ top2--;
+ arr[top2] = x;
+ }
+ }
+
+ int pop1() {
+ if (top1 >= 0) {
+ int x = arr[top1];
+ top1--;
+ return x;
+ } else {
+ return -1;
+ }
+ }
+
+ int pop2() {
+ if (top2 < size) {
+ int x = arr[top2];
+ top2++;
+ return x;
+ } else {
+ return -1;
+ }
+ }
+}
+```
+
+
+
+
+```cpp
+class TwoStacks {
+ int* arr;
+ int size;
+ int top1, top2;
+public:
+ TwoStacks(int n) {
+ size = n;
+ arr = new int[n];
+ top1 = -1;
+ top2 = n;
+ }
+
+ void push1(int x) {
+ if (top1 < top2 - 1) {
+ arr[++top1] = x;
+ }
+ }
+
+ void push2(int x) {
+ if (top1 < top2 - 1) {
+ arr[--top2] = x;
+ }
+ }
+
+ int pop1() {
+ if (top1 >= 0) {
+ return arr[top1--];
+ } else {
+ return -1;
+ }
+ }
+
+ int pop2() {
+ if (top2 < size) {
+ return arr[top2++];
+ } else {
+ return -1;
+ }
+ }
+};
+```
+
+
+
+
+```javascript
+class TwoStacks {
+ constructor(n = 100) {
+ this.size = n;
+ this.arr = new Array(n).fill(0);
+ this.top1 = -1;
+ this.top2 = n;
+ }
+
+ push1(x) {
+ if (this.top1 < this.top2 - 1) {
+ this.top1++;
+ this.arr[this.top1] = x;
+ }
+ }
+
+ push2(x) {
+ if (this.top1 < this.top2 - 1) {
+ this.top2--;
+ this.arr[this.top2] = x;
+ }
+ }
+
+ pop1() {
+ if (this.top1 >= 0) {
+ const x = this.arr[this.top1];
+ this.top1--;
+ return x;
+ } else {
+ return -1;
+ }
+ }
+
+ pop2() {
+ if (this.top2 < this.size) {
+ const x = this.arr[this.top2];
+ this.top2++;
+ return x;
+ } else {
+ return -1;
+ }
+ }
+}
+```
+
+
+
+
+```typescript
+class TwoStacks {
+ size: number;
+ top1: number;
+ top2: number;
+ arr: number[];
+
+ constructor(n: number = 100) {
+ this.size = n;
+ this.arr = new Array(n).fill(0);
+ this.top1 = -1;
+ this.top2 = n;
+ }
+
+ push1(x: number): void {
+ if (this.top1 < this.top2 - 1) {
+ this.top1++;
+ this.arr[this.top1] = x;
+ }
+ }
+
+ push2(x: number): void {
+ if (this.top1 < this.top2 - 1) {
+ this.top2--;
+ this.arr[this.top2] = x;
+ }
+ }
+
+ pop1(): number {
+ if (this.top1 >= 0) {
+ const x = this.arr[this.top1];
+ this.top1--;
+ return x;
+ } else {
+ return -1;
+ }
+ }
+
+ pop2(): number {
+ if (this.top2 < this.size) {
+ const x = this.arr[this.top2];
+ this.top2++;
+ return x;
+ } else {
+ return -1;
+ }
+ }
+}
+```
+
+
+
+
+## Complexity Analysis
+
+The provided solutions efficiently implement two stacks in a single array using pointers. This approach ensures a time complexity of $O(1)$ for all stack operations and an auxiliary space complexity of $O(1)$. The algorithms are designed to handle up to $10^4$ queries efficiently without relying on dynamic data structures.
+
+**Time Complexity:** $O(1)$ for all the four methods.
+**Auxiliary Space:** $O(1)$ for all the four methods.
+
+---
+
+- **GeeksforGeeks Problem:** [Implement two stack in an array](https://www.geeksforgeeks.org/problems/implement-two-stacks-in-an-array/0)
+- **Author GeeksforGeeks Profile:** [GeeksforGeeks](https://www.geeksforgeeks.org/user/GeeksforGeeks/)
+
diff --git a/dsa-solutions/gfg-solutions/Easy problems/intersection-of-two-sorted-linked-lists.md b/dsa-solutions/gfg-solutions/Easy problems/intersection-of-two-sorted-linked-lists.md
new file mode 100644
index 000000000..e51deb4d5
--- /dev/null
+++ b/dsa-solutions/gfg-solutions/Easy problems/intersection-of-two-sorted-linked-lists.md
@@ -0,0 +1,240 @@
+---
+id: intersection-of-two-sorted-linked-lists
+title: Intersection of Two Sorted Linked Lists
+sidebar_label: 6 Intersection of Two Sorted Linked Lists
+tags:
+- Linked List
+- Python
+- Java
+- C++
+- JavaScript
+- TypeScript
+description: "This document provides solutions to the problem of finding the intersection of two sorted linked lists in various programming languages."
+---
+
+## Problem
+
+Given two linked lists sorted in increasing order, create a new linked list representing the intersection of the two linked lists. The new linked list should be made without changing the original lists.
+
+**Note:** The elements of the linked list are not necessarily distinct.
+
+### Examples
+
+**Example 1:**
+
+```
+Input:
+LinkedList1 = 1->2->3->4->6
+LinkedList2 = 2->4->6->8
+Output:
+2 4 6
+Explanation: For the given two linked list, 2, 4 and 6 are the elements in the intersection.
+```
+
+**Example 2:**
+
+```
+Input:
+LinkedList1 = 10->20->40->50
+LinkedList2 = 15->40
+Output:
+40
+```
+
+### Your Task
+
+You don't have to take any input or print anything. Your task is to complete the function `findIntersection()`, which will take the head of both of the linked lists as input and should find the intersection of the two linked lists and add all the elements in the intersection to the third linked list and return the head of the third linked list.
+
+**Expected Time Complexity:** $O(n + m)$
+**Expected Auxiliary Space:** $O(n + m)$
+
+**Note:** n, m are the sizes of the respective linked lists.
+
+### Constraints
+- $1 ≤ size of linked lists ≤ 5000$
+- $1 ≤ Data in linked list nodes ≤ 10^4$
+
+## Solution
+
+### Intuition & Approach
+
+To find the intersection of two sorted linked lists, we can iterate through both lists simultaneously. By comparing the elements at each step, we can identify common elements and construct a new linked list to represent the intersection. This process allows us to efficiently determine which elements are present in both lists without altering the original structures.
+
+### Implementation
+
+
+
+
+```python
+class ListNode:
+ def __init__(self, x):
+ self.data = x
+ self.next = None
+
+class Solution:
+ def findIntersection(self, head1, head2):
+ intersection = ListNode(0) # dummy node
+ tail = intersection
+
+ while head1 and head2:
+ if head1.data == head2.data:
+ tail.next = ListNode(head1.data)
+ tail = tail.next
+ head1 = head1.next
+ head2 = head2.next
+ elif head1.data < head2.data:
+ head1 = head1.next
+ else:
+ head2 = head2.next
+
+ return intersection.next
+```
+
+
+
+
+```java
+class ListNode {
+ int data;
+ ListNode next;
+ ListNode(int x) { data = x; next = null; }
+}
+
+class Solution {
+ public ListNode findIntersection(ListNode head1, ListNode head2) {
+ ListNode intersection = new ListNode(0); // dummy node
+ ListNode tail = intersection;
+
+ while (head1 != null && head2 != null) {
+ if (head1.data == head2.data) {
+ tail.next = new ListNode(head1.data);
+ tail = tail.next;
+ head1 = head1.next;
+ head2 = head2.next;
+ } else if (head1.data < head2.data) {
+ head1 = head1.next;
+ } else {
+ head2 = head2.next;
+ }
+ }
+
+ return intersection.next;
+ }
+}
+```
+
+
+
+
+```cpp
+struct ListNode {
+ int data;
+ ListNode* next;
+ ListNode(int x) : data(x), next(nullptr) {}
+};
+
+class Solution {
+public:
+ ListNode* findIntersection(ListNode* head1, ListNode* head2) {
+ ListNode* intersection = new ListNode(0); // dummy node
+ ListNode* tail = intersection;
+
+ while (head1 != nullptr && head2 != nullptr) {
+ if (head1->data == head2->data) {
+ tail->next = new ListNode(head1->data);
+ tail = tail->next;
+ head1 = head1->next;
+ head2 = head2->next;
+ } else if (head1->data < head2->data) {
+ head1 = head1->next;
+ } else {
+ head2 = head2->next;
+ }
+ }
+
+ return intersection->next;
+ }
+};
+```
+
+
+
+
+```javascript
+class ListNode {
+ constructor(data) {
+ this.data = data;
+ this.next = null;
+ }
+}
+
+class Solution {
+ findIntersection(head1, head2) {
+ let intersection = new ListNode(0); // dummy node
+ let tail = intersection;
+
+ while (head1 !== null && head2 !== null) {
+ if (head1.data === head2.data) {
+ tail.next = new ListNode(head1.data);
+ tail = tail.next;
+ head1 = head1.next;
+ head2 = head2.next;
+ } else if (head1.data < head2.data) {
+ head1 = head1.next;
+ } else {
+ head2 = head2.next;
+ }
+ }
+
+ return intersection.next;
+ }
+}
+```
+
+
+
+
+```typescript
+class ListNode {
+ data: number;
+ next: ListNode | null;
+
+ constructor(data: number) {
+ this.data = data;
+ this.next = null;
+ }
+}
+
+class Solution {
+ findIntersection(head1: ListNode | null, head2: ListNode | null): ListNode | null {
+ let intersection = new ListNode(0); // dummy node
+ let tail = intersection;
+
+ while (head1 !== null && head2 !== null) {
+ if (head1.data === head2.data) {
+ tail.next = new ListNode(head1.data);
+ tail = tail.next;
+ head1 = head1.next;
+ head2 = head2.next;
+ } else if (head1.data < head2.data) {
+ head1 = head1.next;
+ } else {
+ head2 = head2.next;
+ }
+ }
+
+ return intersection.next;
+ }
+}
+```
+
+
+
+
+**Time Complexity:** $O(n + m)$
+**Auxiliary Space:** $O(n + m)$
+
+## References
+
+- **GeeksforGeeks Problem:** [Intersection of Two Sorted Linked Lists](https://www.geeksforgeeks.org/problems/intersection-of-two-sorted-linked-lists/0)
+- **Author GeeksforGeeks Profile:** [GeeksforGeeks](https://www.geeksforgeeks.org/user/GeeksforGeeks/)
diff --git a/dsa-solutions/gfg-solutions/Easy problems/reverse-a-doubly-linked-list.md b/dsa-solutions/gfg-solutions/Easy problems/reverse-a-doubly-linked-list.md
new file mode 100644
index 000000000..6ed05592e
--- /dev/null
+++ b/dsa-solutions/gfg-solutions/Easy problems/reverse-a-doubly-linked-list.md
@@ -0,0 +1,166 @@
+---
+id: reverse-doubly-linked-list
+title: Reverse a Doubly Linked List
+sidebar_label: 2 Reverse a Doubly Linked List
+tags:
+- Doubly Linked List
+- Python
+- Java
+- C++
+- JavaScript
+- TypeScript
+description: "This document explores different approaches to reversing a doubly linked list in-place, including solutions in Python, Java, C++, JavaScript, and TypeScript."
+---
+
+## Problem
+
+Given a doubly linked list of n elements, the task is to reverse this list in-place.
+
+### Examples
+
+**Example 1:**
+
+```
+Input:
+LinkedList: 3 <--> 4 <--> 5
+Output:
+5 4 3
+
+Explanation:
+After reversing the list, elements are 5 <--> 4 <--> 3.
+```
+
+**Example 2:**
+
+```
+Input:
+LinkedList: 75 <--> 122 <--> 59 <--> 196
+Output:
+196 59 122 75
+
+Explanation:
+After reversing the list, elements are 196 <--> 59 <--> 122 <--> 75.
+```
+
+### Your Task
+Your task is to complete the given function `reverseDLL()`, which takes head reference as an argument and reverses the elements in-place such that the tail becomes the new head and all pointers are pointing in the right order. You need to return the new head of the reversed list.
+
+**Expected Time Complexity:** $O(N)$
+**Expected Auxiliary Space:** $O(1)$
+
+### Constraints
+- $1 ≤ number of nodes ≤ 10^4$
+- $0 ≤ value of nodes ≤ 10^4$
+
+## Solution
+
+### Approach
+
+To reverse a doubly linked list in-place, we can use three pointers: `previous_node`, `current_node`, and `next_node`. The algorithm traverses the list, updating the pointers at each step until the entire list is reversed.
+
+### Python Code
+
+
+
+
+```python
+class Solution:
+ def reverseDLL(self, head):
+ while head:
+ head.next, head.prev = head.prev, head.next
+ if not head.prev:
+ return head
+ head = head.prev
+```
+
+
+
+
+```java
+class Solution {
+ public Node reverseDLL(Node head) {
+ while (head != null) {
+ Node temp = head.prev;
+ head.prev = head.next;
+ head.next = temp;
+ if (head.prev == null) {
+ return head;
+ }
+ head = head.prev;
+ }
+ return null;
+ }
+}
+```
+
+
+
+
+```cpp
+class Solution {
+public:
+ Node* reverseDLL(Node* head) {
+ while (head != nullptr) {
+ Node* temp = head->prev;
+ head->prev = head->next;
+ head->next = temp;
+ if (head->prev == nullptr) {
+ return head;
+ }
+ head = head->prev;
+ }
+ return nullptr;
+ }
+};
+```
+
+
+
+
+```javascript
+class Solution {
+ reverseDLL(head) {
+ while (head) {
+ [head.next, head.prev] = [head.prev, head.next];
+ if (!head.prev) {
+ return head;
+ }
+ head = head.prev;
+ }
+ return null;
+ }
+}
+```
+
+
+
+
+```typescript
+class Solution {
+ reverseDLL(head: Node): Node | null {
+ while (head) {
+ [head.next, head.prev] = [head.prev, head.next];
+ if (!head.prev) {
+ return head;
+ }
+ head = head.prev;
+ }
+ return null;
+ }
+}
+```
+
+
+
+
+### Complexity Analysis
+
+- **Time Complexity:** $O(N),$ where N is the number of elements in the doubly linked list. We traverse the entire list once.
+- **Space Complexity:** $O(1)$, as we only use a constant amount of extra space for pointers.
+
+---
+
+## References
+
+- **GeeksforGeeks Problem:** [Reverse a Doubly Linked List](https://www.geeksforgeeks.org/reverse-a-doubly-linked-list/)
+- **Author GeeksforGeeks Profile:** [GeeksforGeeks](https://www.geeksforgeeks.org/user/GeeksforGeeks/)
diff --git a/dsa-solutions/gfg-solutions/Easy problems/reverse-a-linked-list.md b/dsa-solutions/gfg-solutions/Easy problems/reverse-a-linked-list.md
new file mode 100644
index 000000000..126a9dbad
--- /dev/null
+++ b/dsa-solutions/gfg-solutions/Easy problems/reverse-a-linked-list.md
@@ -0,0 +1,189 @@
+---
+id: reverse-linked-list
+title: Reverse a Linked List
+sidebar_label: 1 Reverse a Linked List
+tags:
+- Linked List
+- Python
+- Java
+- C++
+- JavaScript
+- TypeScript
+description: "This document explores different approaches to reversing a linked list, including solutions in Python, Java, C++, JavaScript, and TypeScript."
+---
+
+## Problem
+
+Given a linked list of N nodes, the task is to reverse this list.
+
+### Examples
+
+**Example 1:**
+
+```
+Input:
+LinkedList: 1->2->3->4->5->6
+Output:
+6 5 4 3 2 1
+
+Explanation:
+After reversing the list, elements are 6->5->4->3->2->1.
+```
+
+**Example 2:**
+
+```
+Input:
+LinkedList: 2->7->8->9->10
+Output:
+10 9 8 7 2
+
+Explanation:
+After reversing the list, elements are 10->9->8->7->2.
+```
+
+### Your Task
+The task is to complete the function `reverseList()` with head reference as the only argument and should return the new head after reversing the list.
+
+**Expected Time Complexity:** $ O(N) $
+**Expected Auxiliary Space:** $ O(1) $
+
+### Constraints
+- $ 1 ≤ N ≤ 10^4 $
+
+## Solution
+
+### Approach
+
+To reverse a linked list, we can follow these steps:
+
+1. Initialize three pointers: `prev` (previous node), `curr` (current node), and `nextNode` (next node).
+2. Start with `prev = None` and `curr = head`, where `head` is the head of the original linked list.
+3. Traverse the linked list:
+ - Store `nextNode` as `curr.next`.
+ - Reverse the link by pointing `curr.next` to `prev`.
+ - Move `prev` to `curr` and `curr` to `nextNode`.
+4. After traversing, update the new head to `prev`.
+5. Return the new head.
+
+### Implementation
+
+
+
+
+```python
+class Solution:
+ # Function to reverse a linked list.
+ def reverseList(self, head):
+ prev = None
+ curr = head
+
+ while curr:
+ nextNode = curr.next
+ curr.next = prev
+ prev = curr
+ curr = nextNode
+
+ head = prev
+ return head
+```
+
+
+
+
+```java
+class Solution {
+ public ListNode reverseList(ListNode head) {
+ ListNode prev = null;
+ ListNode curr = head;
+
+ while (curr != null) {
+ ListNode nextNode = curr.next;
+ curr.next = prev;
+ prev = curr;
+ curr = nextNode;
+ }
+
+ head = prev;
+ return head;
+ }
+}
+```
+
+
+
+
+```cpp
+class Solution {
+public:
+ ListNode* reverseList(ListNode* head) {
+ ListNode* prev = nullptr;
+ ListNode* curr = head;
+
+ while (curr != nullptr) {
+ ListNode* nextNode = curr->next;
+ curr->next = prev;
+ prev = curr;
+ curr = nextNode;
+ }
+
+ head = prev;
+ return head;
+ }
+};
+```
+
+
+
+
+```javascript
+function reverseList(head) {
+ let prev = null;
+ let curr = head;
+
+ while (curr) {
+ let nextNode = curr.next;
+ curr.next = prev;
+ prev = curr;
+ curr = nextNode;
+ }
+
+ head = prev;
+ return head;
+}
+```
+
+
+
+
+```typescript
+function reverseList(head: ListNode | null): ListNode | null {
+ let prev: ListNode | null = null;
+ let curr: ListNode | null = head;
+
+ while (curr !== null) {
+ let nextNode: ListNode | null = curr.next;
+ curr.next = prev;
+ prev = curr;
+ curr = nextNode;
+ }
+
+ head = prev;
+ return head;
+}
+```
+
+
+
+
+### Complexity Analysis
+
+- **Time Complexity:** $O(N)$, where N is the number of nodes in the linked list. We traverse the entire list once.
+- **Space Complexity:** $O(1)$, as we only use a constant amount of extra space for pointers.
+
+---
+
+## References
+
+- **GeeksforGeeks Problem:** [Reverse a Linked List](https://www.geeksforgeeks.org/reverse-a-linked-list/)
+- **Author GeeksforGeeks Profile:** [GeeksforGeeks](https://www.geeksforgeeks.org/user/GeeksforGeeks/)
diff --git a/dsa-solutions/gfg-solutions/Easy problems/square-root.md b/dsa-solutions/gfg-solutions/Easy problems/square-root.md
new file mode 100644
index 000000000..9777b7f9e
--- /dev/null
+++ b/dsa-solutions/gfg-solutions/Easy problems/square-root.md
@@ -0,0 +1,200 @@
+---
+id: square-root
+title: Square Root
+sidebar_label: 9 Square Root
+tags:
+- Math
+- Binary Search
+- Python
+- Java
+- C++
+- JavaScript
+- TypeScript
+description: "This document provides solutions to the problem of finding the square root of a given integer using various programming languages."
+---
+
+## Problem
+
+Given an integer `x`, find the square root of `x`. If `x` is not a perfect square, then return the floor value of √x.
+
+### Examples
+
+**Example 1:**
+
+```
+Input: x = 5
+Output: 2
+Explanation: Since 5 is not a perfect square, the floor of the square root of 5 is 2.
+```
+
+**Example 2:**
+
+```
+Input: x = 4
+Output: 2
+Explanation: Since 4 is a perfect square, its square root is 2.
+```
+
+### Your Task
+
+You don't need to read input or print anything. The task is to complete the function `floorSqrt()` which takes `x` as the input parameter and returns its square root. Note: Try solving the question without using the sqrt function. The value of `x` ≥ 0.
+
+**Expected Time Complexity:** $O(log N)$
+**Expected Auxiliary Space:** $O(1)$
+
+**Constraints**
+- $1 ≤ x ≤ 10^7$
+
+## Solution
+
+### Intuition & Approach
+
+To find the square root of a number without using the built-in `sqrt` function, we can use binary search. This approach leverages the fact that the square root of `x` must lie between `0` and `x`. By repeatedly narrowing down the range using binary search, we can efficiently find the floor value of the square root.
+
+### Implementation
+
+
+
+
+```python
+class Solution:
+ def floorSqrt(self, x: int) -> int:
+ if x == 0 or x == 1:
+ return x
+ start, end = 1, x
+ ans = 0
+ while start <= end:
+ mid = (start + end) // 2
+ if mid * mid == x:
+ return mid
+ if mid * mid < x:
+ start = mid + 1
+ ans = mid
+ else:
+ end = mid - 1
+ return ans
+```
+
+
+
+
+```java
+class Solution {
+ long floorSqrt(long x) {
+ if (x == 0 || x == 1) {
+ return x;
+ }
+ long start = 1, end = x, ans = 0;
+ while (start <= end) {
+ long mid = (start + end) / 2;
+ if (mid * mid == x) {
+ return mid;
+ }
+ if (mid * mid < x) {
+ start = mid + 1;
+ ans = mid;
+ } else {
+ end = mid - 1;
+ }
+ }
+ return ans;
+ }
+}
+```
+
+
+
+
+```cpp
+class Solution {
+public:
+ long long int floorSqrt(long long int x) {
+ if (x == 0 || x == 1)
+ return x;
+ long long int start = 1, end = x, ans = 0;
+ while (start <= end) {
+ long long int mid = (start + end) / 2;
+ if (mid * mid == x)
+ return mid;
+ if (mid * mid < x) {
+ start = mid + 1;
+ ans = mid;
+ } else {
+ end = mid - 1;
+ }
+ }
+ return ans;
+ }
+};
+```
+
+
+
+
+```javascript
+class Solution {
+ floorSqrt(x) {
+ if (x === 0 || x === 1) {
+ return x;
+ }
+ let start = 1, end = x, ans = 0;
+ while (start <= end) {
+ let mid = Math.floor((start + end) / 2);
+ if (mid * mid === x) {
+ return mid;
+ }
+ if (mid * mid < x) {
+ start = mid + 1;
+ ans = mid;
+ } else {
+ end = mid - 1;
+ }
+ }
+ return ans;
+ }
+}
+```
+
+
+
+
+```typescript
+class Solution {
+ floorSqrt(x: number): number {
+ if (x === 0 || x === 1) {
+ return x;
+ }
+ let start = 1, end = x, ans = 0;
+ while (start <= end) {
+ let mid = Math.floor((start + end) / 2);
+ if (mid * mid === x) {
+ return mid;
+ }
+ if (mid * mid < x) {
+ start = mid + 1;
+ ans = mid;
+ } else {
+ end = mid - 1;
+ }
+ }
+ return ans;
+ }
+}
+```
+
+
+
+
+## Complexity Analysis
+
+The provided solutions efficiently find the floor value of the square root of a given integer `x` using binary search. This approach ensures a time complexity of $ O(log N) and an auxiliary space complexity of $O(1)$. The algorithms are designed to handle large values of `x` up to 10^7 efficiently without relying on built-in square root functions.
+
+**Time Complexity:** $O(log N)$
+**Auxiliary Space:** $O(1)$
+
+---
+
+## References
+
+- **GeeksforGeeks Problem:** [Square root](https://www.geeksforgeeks.org/problems/square-root/0)
+- **Author GeeksforGeeks Profile:** [GeeksforGeeks](https://www.geeksforgeeks.org/user/GeeksforGeeks/)
\ No newline at end of file