Skip to content

Commit fdb8bd8

Browse files
committed
feat(book/sorting): add questions and solutions
1 parent 65e302b commit fdb8bd8

13 files changed

+337
-0
lines changed

book/D-interview-questions-solutions.asc

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,101 @@ This algorithm only works with DFS.
843843

844844
//
845845

846+
:leveloffset: +1
847+
848+
=== Solutions for Sorting Questions
849+
(((Interview Questions Solutions, sorting)))
850+
851+
:leveloffset: -1
852+
853+
854+
[#sorting-q-merge-intervals]
855+
include::content/part04/sorting-algorithms.asc[tag=sorting-q-merge-intervals]
856+
857+
The first thing we need to understand is all the different possibilities for overlaps:
858+
859+
// image::merge-intervals-cases.png[merge intervals cases] // blurry
860+
// image::intervals-overlap-cases.jpg[merge intervals cases] // too big
861+
// image::intervals-overlap-cases.svg[merge intervals cases] // errors
846862

863+
// my own image
864+
image::intervals-overlap-cases-owned.png[merge intervals cases]
847865

866+
One way to solve this problem, is sorting by start time. That will eliminate half of the cases!
848867

868+
Since A will always start before B, only 3 cases apply:
869+
- No overlap: `[[1, 3], [4, 6]]`.
870+
- Overlap at the end: `[[1, 3], [2, 4]]`.
871+
- Eclipse: `[[1, 9], [3, 7]]`.
872+
873+
*Algorithm*:
874+
875+
* Sort intervals by start time
876+
* If the `curr`ent interval's start time is _equal_ or less than the `last` interval's end time, then we have an overlap.
877+
** Overlaps has two cases: 1) `curr`'s end is larger 2) `last`'s end is larger. For both cases `Math.max` works.
878+
* If there's no overlap, we add the interval to the solution.
879+
880+
*Implementation*:
881+
882+
[source, javascript]
883+
----
884+
include::interview-questions/merge-intervals.js[tags=description;solution]
885+
----
886+
887+
For the first interval, it will be added straight to the solution array. For all others, we will do the comparison.
888+
889+
*Complexity Analysis*:
890+
891+
- Time: `O(n log n)`. Standard libraries has a sorting time of `O(n log n)`, then we visit each interval in `O(n)`.
892+
- Space: `O(n)`. In the worst-case is when there's no overlapping intervals. The size of the solution array would be `n`.
893+
894+
895+
896+
897+
898+
899+
900+
//
901+
902+
[#sorting-q-sort-colors]
903+
include::content/part04/sorting-algorithms.asc[tag=sorting-q-sort-colors]
904+
905+
We are asked to sort an array with 3 possible values. If we use the standard sorting method `Array.sort`, that will be `O(n log n)`. However, we are asked to solve in linear time and constant space complexity.
906+
907+
The concept on quicksort can help here. We can choose 1 as a pivot and move everything less than 1 to the left and everything bigger than 1 to the right.
908+
909+
*Algorithm*:
910+
911+
* Initialize 3 pointers: `left = 0`, `right = len - 1` and `current = 0`.
912+
* While the `current` pointer is less than `right`
913+
** If `current` element is less than pivot 1, swap it to the left and increase the `left` and `current` pointer.
914+
*** We can safely increase the current pointer
915+
** If `current` element is bigger than pivot 1, swap it to the right and decrease `right` pointer.
916+
*** Here, we don't increase the `current` pointer because the number that we swapped with could be another 2 and we might need to keep swapping while decreasing `right`.
917+
918+
*Implementation*:
919+
920+
[source, javascript]
921+
----
922+
include::interview-questions/sort-colors.js[tags=description;solution]
923+
----
924+
925+
We are using the destructive assigment to swap the elements. Here's another version a little bit more compact.
926+
927+
[source, javascript]
928+
----
929+
include::interview-questions/sort-colors.js[tags=compact]
930+
----
931+
932+
*Complexity Analysis*:
933+
934+
- Time: `O(n)`. We only visit each number once.
935+
- Space: `O(1)`. Operations are in-place. Only O(1) space variables were used.
936+
937+
938+
939+
940+
941+
942+
943+
//

book/content/part04/sorting-algorithms.asc

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,78 @@ We explored many algorithms some of them simple and other more performant. Also,
139139
// | Tim sort | O(n log n) | O(log n) | Yes | No | No | Yes
140140
|===
141141
// end::table[]
142+
143+
144+
145+
146+
147+
148+
149+
150+
151+
==== Practice Questions
152+
(((Interview Questions, sorting)))
153+
154+
155+
156+
157+
158+
// tag::sorting-q-merge-intervals[]
159+
===== Merge Intervals
160+
161+
*so-1*) _Given an array of intervals `[start, end]`, merge all overlapping intervals._
162+
163+
// end::sorting-q-merge-intervals[]
164+
165+
// _Seen in interviews at: X._
166+
167+
*Starter code*:
168+
169+
[source, javascript]
170+
----
171+
include::../../interview-questions/merge-intervals.js[tags=description;placeholder]
172+
----
173+
174+
*Examples*:
175+
176+
[source, javascript]
177+
----
178+
merge([[0, 2], [2, 4]]); // [[0, 4]] (0-2 overlaps with 2-4)
179+
merge([[2, 2], [3, 4]]); // [[2, 2], [3, 4]] (no overlap)
180+
merge([[1, 10], [3, 4]]); // [[1, 10]] (1-10 covers the other)
181+
----
182+
183+
184+
_Solution: <>_
185+
186+
187+
188+
189+
190+
191+
// tag::sorting-q-sort-colors[]
192+
===== Sort Colors (The Dutch flag problem)
193+
194+
*so-2*) _Given an array with 3 possible values (0, 1, 2), sort them in linear time and in-place. Hint: similar to quicksort, where the pivot is 1._
195+
196+
// end::sorting-q-sort-colors[]
197+
198+
// _Seen in interviews at: Amazon, Microsoft, Facebook._
199+
200+
*Starter code*:
201+
202+
[source, javascript]
203+
----
204+
include::../../interview-questions/sort-colors.js[tags=description;placeholder]
205+
----
206+
207+
*Examples*:
208+
209+
[source, javascript]
210+
----
211+
sortColors([0, 2, 1]); // [0, 1, 2]
212+
sortColors([2, 0, 2, 1, 0, 1, 0]); // [0, 0, 0, 1, 1, 2, 2]
213+
sortColors([1, 1, 1]); // [1, 1, 1]
214+
----
215+
216+
_Solution: <>_
3.69 KB
Loading
Loading
1.38 KB
Loading
14.3 KB
Loading
199 KB
Loading

book/images/intervals-overlap-cases.svg

Lines changed: 1 addition & 0 deletions
Loading

book/images/merge-intervals-cases.png

28.3 KB
Loading
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// const { } = require('../../src/index');
2+
3+
// tag::description[]
4+
/**
5+
* Merge overlapping intervals.
6+
* @param {[numer, number][]} intervals - Array with pairs [start, end]
7+
* @returns {[numer, number][]} - Array of merged pairs [start, end]
8+
*/
9+
function merge(intervals) {
10+
// end::description[]
11+
// tag::placeholder[]
12+
// write your code here...
13+
// end::placeholder[]
14+
// tag::solution[]
15+
const ans = [];
16+
17+
intervals.sort((a, b) => a[0] - b[0]); // sort by start time
18+
19+
for (let i = 0; i < intervals.length; i++) {
20+
const last = ans[ans.length - 1];
21+
const curr = intervals[i];
22+
if (last && last[1] >= curr[0]) { // check for overlaps
23+
last[1] = Math.max(last[1], curr[1]);
24+
} else ans.push(curr);
25+
}
26+
return ans;
27+
// end::solution[]
28+
// tag::description[]
29+
}
30+
// end::description[]
31+
32+
module.exports = { merge };

0 commit comments

Comments
 (0)