Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(book/linkedlist): add question solution
  • Loading branch information
amejiarosario committed Aug 25, 2020
commit 707827d543db38d0026f3b44605c8a2b4549d8c8
21 changes: 17 additions & 4 deletions book/D-interview-questions-solutions.asc
Original file line number Diff line number Diff line change
Expand Up @@ -105,18 +105,31 @@ The runtime is `O(n)` and a space complexity of `O(1)`.
[#linkedlist-q-merge-lists]
include::content/part02/linked-list.asc[tag=linkedlist-q-merge-lists]

For this problem we need to visit each node in both list and recontruct them in ascending order. Note: We don't need to copy the values into a new node.

Another case to take into consideration is that list might have different length. So, if one list runs out, we have to keep taking elements from the remaining list.

Algorithm:

- TODO
- Next TODO
- Have a pointer for each list
- While there's a pointer that is not null, visite them
- Compare each list's node's value and take the one that is smaller.
- Advance the pointer of the taken node to the next one.

Implementation:

[source, javascript]
----
include::interview-questions/merge-lists.js[tag=description]
include::interview-questions/merge-lists.js[tag=solution]
----

The runtime is `` and a space complexity of ``.
Notice that we used a "dummy" node or "sentinel node" to have some starting point for the solution list.

Complexity Analysis:

- Time: `O(m+n)`. Visiting each node from the list 1 and list 2 has a time complexity `O(m + n)`, where m and n represents the length of each list repectively.
- Space: `O(1)`. We resuse the same nodes and only change their `next` pointers. We only create one additional node "the sentinel node".



Expand All @@ -134,4 +147,4 @@ The runtime is `` and a space complexity of ``.
// include::interview-questions/merge-lists.js[tag=solution]
// ----

// The runtime is `` and a space complexity of ``.
// The runtime is `` and a space complexity of ``.
25 changes: 12 additions & 13 deletions book/interview-questions/merge-lists.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,23 @@ const ListNode = require('../../src/data-structures/linked-lists/node');
function mergeTwoLists(l1, l2) {
// end::description[]
// tag::solution[]
const l0 = new ListNode();
let i0 = l0;
let i1 = l1;
let i2 = l2;
const sentinel = new ListNode();
let p0 = sentinel;
let p1 = l1;
let p2 = l2;

while (i1 || i2) {
if (!i1 || (i2 && i1.value > i2.value)) {
i0.next = i2;
i2 = i2.next;
while (p1 || p2) {
if (!p1 || (p2 && p1.value > p2.value)) {
p0.next = p2;
p2 = p2.next;
} else {
i0.next = i1;
i1 = i1.next;
p0.next = p1;
p1 = p1.next;
}

i0 = i0.next;
p0 = p0.next;
}

return l0.next;
return sentinel.next;
}
// end::solution[]

Expand Down
28 changes: 25 additions & 3 deletions book/interview-questions/merge-lists.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const { mergeTwoLists } = require('./merge-lists');
const LinkedList = require('../../src/data-structures/linked-lists/linked-list');
// const ListNode = require('../../src/data-structures/linked-lists/node');

describe('Linked List: Merge Lists', () => {
function asString(root) {
Expand All @@ -14,9 +13,32 @@ describe('Linked List: Merge Lists', () => {
it('should merge in asc order', () => {
const l1 = new LinkedList([2, 3, 4]).first;
const l2 = new LinkedList([1, 2]).first;
console.log({l1: asString(l1), l2: asString(l2)});
const actual = mergeTwoLists((l1, l2));
const actual = mergeTwoLists(l1, l2);
const expected = '1 -> 2 -> 2 -> 3 -> 4';
expect(asString(actual)).toEqual(expected);
});

it('should handle empty list 1', () => {
const l1 = new LinkedList().first;
const l2 = new LinkedList([1, 2]).first;
const actual = mergeTwoLists(l1, l2);
const expected = '1 -> 2';
expect(asString(actual)).toEqual(expected);
});

it('should handle empty list 1', () => {
const l1 = new LinkedList([2, 3, 4]).first;
const l2 = new LinkedList().first;
const actual = mergeTwoLists(l1, l2);
const expected = '2 -> 3 -> 4';
expect(asString(actual)).toEqual(expected);
});

it('should handle empty lists', () => {
const l1 = new LinkedList().first;
const l2 = new LinkedList().first;
const actual = mergeTwoLists(l1, l2);
const expected = '';
expect(asString(actual)).toEqual(expected);
});
});