diff --git a/book/D-interview-questions-solutions.asc b/book/D-interview-questions-solutions.asc
index d7228268..fb9b27c1 100644
--- a/book/D-interview-questions-solutions.asc
+++ b/book/D-interview-questions-solutions.asc
@@ -843,6 +843,90 @@ This algorithm only works with DFS.
 
 //
 
+:leveloffset: +1
+
+=== Solutions for Sorting Questions
+(((Interview Questions Solutions, sorting)))
+
+:leveloffset: -1
+
+
+[#sorting-q-merge-intervals]
+include::content/part03/sorting-algorithms.asc[tag=sorting-q-merge-intervals]
+
+The first thing we need to understand is all the different possibilities for overlaps:
+
+image::merge-intervals-cases.png[merge intervals cases]
+
+One way to solve this problem, is sorting by start time. That will eliminate half of the cases!
+
+Since A will always start before B, only 3 cases apply:
+- No overlap: `[[1, 3], [4, 6]]`.
+- Overlap at the end: `[[1, 3], [2, 4]]`.
+- Eclipse: `[[1, 9], [3, 7]]`.
+
+*Algorithm*:
+
+* Sort intervals by start time
+* If the `curr`ent interval's start time is _equal_ or less than the `last` interval's end time, then we have an overlap.
+** Overlaps has two cases: 1) `curr`'s end is larger 2) `last`'s end is larger. For both cases `Math.max` works.
+* If there's no overlap, we add the interval to the solution.
+
+*Implementation*:
+
+[source, javascript]
+----
+include::interview-questions/merge-intervals.js[tags=description;solution]
+----
+
+For the first interval, it will be added straight to the solution array. For all others, we will do the comparison.
+
+*Complexity Analysis*:
+
+- Time: `O(n log n)`. Standard libraries has a sorting time of `O(n log n)`, then we visit each interval in `O(n)`.
+- Space: `O(n)`. In the worst-case is when there's no overlapping intervals. The size of the solution array would be `n`.
+
+
+
+
+
+
+
+//
+
+[#sorting-q-FILENAME]
+include::content/part03/sorting-algorithms.asc[tag=sorting-q-FILENAME]
+
+RESTATE REQUIREMENTS AND DESCRIPTIONS
+
+*Algorithm*:
+
+* STEP 1
+* STEP 2
+** STEP 2.1
+** STEP 2.2
+
+*Implementation*:
+
+[source, javascript]
+----
+include::interview-questions/FILENAME.js[tags=description;solution]
+----
+
+IMPLEMENTATION NOTES
+
+*Complexity Analysis*:
+
+- Time: `O(?)`. WHY?
+- Space: `O(?)`. WHY?
+
+
+
+
+
+
+
+//
 
 
 
diff --git a/book/content/part04/sorting-algorithms.asc b/book/content/part04/sorting-algorithms.asc
index 67ea34a4..5a8f21a4 100644
--- a/book/content/part04/sorting-algorithms.asc
+++ b/book/content/part04/sorting-algorithms.asc
@@ -139,3 +139,77 @@ We explored many algorithms some of them simple and other more performant. Also,
 // | Tim sort       | O(n log n) | O(log n)    | Yes    | No       | No     | Yes
 |===
 // end::table[]
+
+
+
+
+
+
+
+
+
+==== Practice Questions
+(((Interview Questions, sorting)))
+
+
+
+
+
+// tag::sorting-q-merge-intervals[]
+===== TITLE
+
+*so-1*) _Given an array of intervals `[start, end]`, merge all overlapping intervals._
+
+// end::sorting-q-merge-intervals[]
+
+// _Seen in interviews at: X._
+
+*Starter code*:
+
+[source, javascript]
+----
+include::../../interview-questions/merge-intervals.js[tags=description;placeholder]
+----
+
+*Examples*:
+
+[source, javascript]
+----
+merge([[0, 2], [2, 4]]); // [[0, 4]] (0-2 overlaps with 2-4)
+merge([[2, 2], [3, 4]]); // [[2, 2], [3, 4]] (no overlap)
+merge([[1, 10], [3, 4]]); // [[1, 10]] (1-10 covers the other)
+----
+
+
+_Solution: <<sorting-q-merge-intervals>>_
+
+
+
+
+
+
+// tag::sorting-q-FILENAME[]
+===== TITLE
+
+*sorting_INITIALS-NUMBER*) _._
+
+// end::sorting-q-FILENAME[]
+
+// _Seen in interviews at: X._
+
+*Starter code*:
+
+[source, javascript]
+----
+include::../../interview-questions/FILENAME.js[tags=description;placeholder]
+----
+
+*Examples*:
+
+[source, javascript]
+----
+FN([]); // 3 (EXPLANATION)
+----
+
+
+_Solution: <<sorting-q-FILENAME>>_
diff --git a/book/images/merge-intervals-cases.png b/book/images/merge-intervals-cases.png
new file mode 100644
index 00000000..574438a9
Binary files /dev/null and b/book/images/merge-intervals-cases.png differ
diff --git a/book/images/merge-intervals-cases.png:Zone.Identifier b/book/images/merge-intervals-cases.png:Zone.Identifier
new file mode 100644
index 00000000..e69de29b
diff --git a/book/interview-questions/merge-intervals.js b/book/interview-questions/merge-intervals.js
new file mode 100644
index 00000000..3c62d5cc
--- /dev/null
+++ b/book/interview-questions/merge-intervals.js
@@ -0,0 +1,27 @@
+// const {  } = require('../../src/index');
+
+// tag::description[]
+function merge(intervals) {
+  // end::description[]
+  // tag::placeholder[]
+  // write your code here...
+  // end::placeholder[]
+  // tag::solution[]
+  const ans = [];
+
+  intervals.sort((a, b) => a[0] - b[0]); // sort by start time
+
+  for (let i = 0; i < intervals.length; i++) {
+    const last = ans[ans.length - 1];
+    const curr = intervals[i];
+    if (last && last[1] >= curr[0]) { // check for overlaps
+      last[1] = Math.max(last[1], curr[1]);
+    } else ans.push(curr);
+  }
+  return ans;
+  // end::solution[]
+  // tag::description[]
+}
+// end::description[]
+
+module.exports = { merge };
diff --git a/book/interview-questions/merge-intervals.spec.js b/book/interview-questions/merge-intervals.spec.js
new file mode 100644
index 00000000..da875e4d
--- /dev/null
+++ b/book/interview-questions/merge-intervals.spec.js
@@ -0,0 +1,30 @@
+const { merge } = require('./merge-intervals');
+// const {  } = require('../../src/index');
+
+[merge].forEach((fn) => {
+  describe(`TOPIC: ${fn.name}`, () => {
+    it('should work with null/empty', () => {
+      const actual = fn([]);
+      const expected = [];
+      expect(actual).toEqual(expected);
+    });
+
+    it('should work with small case', () => {
+      const actual = fn([[1, 3]]);
+      const expected = [[1, 3]];
+      expect(actual).toEqual(expected);
+    });
+
+    it('should work with other case', () => {
+      const actual = fn([[0, 1], [1, 3], [3, 5], [6, 6]]);
+      const expected = [[0, 5], [6, 6]];
+      expect(actual).toEqual(expected);
+    });
+
+    it('should work with other case', () => {
+      const actual = fn([[10, 99], [20, 50], [9, 11], [98, 100]]);
+      const expected = [[9, 100]];
+      expect(actual).toEqual(expected);
+    });
+  });
+});