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
solution to linkedList problem 2
  • Loading branch information
amejiarosario committed Aug 25, 2020
commit 6e4a777896fb95674cb8504b033e73a77b613786
8 changes: 4 additions & 4 deletions book/D-interview-questions-solutions.asc
Original file line number Diff line number Diff line change
Expand Up @@ -109,24 +109,24 @@ For this problem we need to visit each node in both list and recontruct them in

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:
*Algorithm*:

- 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:
*Implementation*:

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

Notice that we used a "dummy" node or "sentinel node" to have some starting point for the solution list.
Notice that we used a "dummy" node or "sentinel node" to have some starting point for the final list.

Complexity Analysis:
*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 Down
25 changes: 23 additions & 2 deletions book/content/part02/linked-list.asc
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,11 @@ For the next two linear data structures <<part02-linear-data-structures#stack>>
==== Interview Questions
(((Interview Questions, Arrays)))




// tag::linkedlist-q-merge-lists[]
===== Max Subarray
===== Merge Linked Lists into One

LL-1) Merge two sorted lists into one (and keep them sorted)
// end::linkedlist-q-merge-lists[]
Expand All @@ -302,4 +305,22 @@ include::../../interview-questions/merge-lists.js[tag=description]
}
----

_Solution: <<linkedlist-q-merge-lists>>_
_Solution: <<linkedlist-q-merge-lists>>_




// tag::linkedlist-q-linkedlist-same-data[]
===== Check if two strings lists are the same

LL-2) Given two linked lists with strings, check if are the same
// end::linkedlist-q-linkedlist-same-data[]

[source, javascript]
----
include::../../interview-questions/linkedlist-same-data.js[tag=description]
// write you code here
}
----

_Solution: <<linkedlist-q-linkedlist-same-data>>_
81 changes: 81 additions & 0 deletions book/interview-questions/linkedlist-same-data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// const ListNode = require('../../src/data-structures/linked-lists/node');

// tag::description[]
/**
* Check if two lists has the same string data.
* Note: each lists can be huge, they have up to 10 million nodes.
*
* @examples
* hasSameData(['he', 'll', 'o'], ['hel', 'lo']); // true
* hasSameData(['hel', 'lo'], ['hi']); // false
*
* @param {ListNode} l1 - The root node of list 1
* @param {ListNode} l2 - The root node of list 2
*/
function hasSameData(l1, l2) {
// end::description[]
// tag::solution[]
let p1 = l1;
let p2 = l2;
let i1 = -1;
let i2 = -1;

const findNextPointerIndex = (p, i) => {
let node = p;
let index = i;
while (node && index >= node.value.length) {
node = node.next;
index = 0;
}
return [node, index];
};

while (p1 && p2) {
[p1, i1] = findNextPointerIndex(p1, i1 + 1);
[p2, i2] = findNextPointerIndex(p2, i2 + 1);
if ((p1 && p2 && p1.value[i1] !== p2.value[i2])
|| ((!p1 || !p2) && p1 !== p2)) return false;
}
return true;
}
// end::solution[]

function hasSameDataBrute1(l1, l2) {
function toString(node) {
const str = [];
for (let curr = node; curr; curr = curr.next) {
str.push(curr.value);
}
return str.join('');
}

// console.log({s1: toString(l1), s2: toString(l2) });
return toString(l1) === toString(l2);
}

function hasSameData1(l1, l2) {
let p1 = l1;
let p2 = l2;

let i1 = 0;
let i2 = 0;

while (p1 || p2) {
if (!p1 || !p2 || p1.value[i1] !== p2.value[i2]) return false;

if (i1 < p1.value.length - 1) i1++;
else {
p1 = p1.next;
i1 = 0;
}

if (i2 < p2.value.length - 1) i2++;
else {
p2 = p2.next;
i2 = 0;
}
}
return true;
}

module.exports = { hasSameData, hasSameDataBrute1, hasSameData1 };
41 changes: 41 additions & 0 deletions book/interview-questions/linkedlist-same-data.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const { hasSameData } = require('./linkedlist-same-data');
const LinkedList = require('../../src/data-structures/linked-lists/linked-list');

describe('Linked List: has same data', () => {
it('should work with same data and shape', () => {
const l1 = new LinkedList(['hi']).first;
const l2 = new LinkedList(['hi']).first;
expect(hasSameData(l1, l2)).toEqual(true);
});

it('should work with different data', () => {
const l1 = new LinkedList(['ab']).first;
const l2 = new LinkedList(['a']).first;
expect(hasSameData(l1, l2)).toEqual(false);
});

it('should work with same data and but different shape', () => {
const l1 = new LinkedList(['h', 'e', 'l', 'l', 'o']).first;
const l2 = new LinkedList(['hello']).first;
expect(hasSameData(l1, l2)).toEqual(true);
});

it('should work with different data', () => {
const l1 = new LinkedList(['he', 'll', 'o']).first;
const l2 = new LinkedList(['ho', 'la']).first;
expect(hasSameData(l1, l2)).toEqual(false);
});

it('should handle empty', () => {
const l1 = new LinkedList(['hi']).first;
const l2 = new LinkedList(['', 'h', '', 'i']).first;
expect(hasSameData(l1, l2)).toEqual(true);
});

xit('should work with large data', () => {
const size = 1e6; // 1e7 takes 4sec.
const l1 = new LinkedList(Array(size).fill('x')).first;
const l2 = new LinkedList(Array(size).fill('z')).first;
expect(hasSameData(l1, l2)).toEqual(false);
});
});
1 change: 1 addition & 0 deletions book/interview-questions/max-subarray.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* @examples
* maxSubArray([1, -3, 10, -5]); // => 10
* maxSubArray([-3,4,-1,2,1,-5]); // => 6
*
* @param {number[]} a - Array
*/
function maxSubArray(a) {
Expand Down
4 changes: 3 additions & 1 deletion book/interview-questions/merge-lists.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ const ListNode = require('../../src/data-structures/linked-lists/node');
* mergeTwoLists([2,4,6], [1,3]); // => [1,2,3,4,6]
* mergeTwoLists([2,4,6], []); // => [2,4,6]
* mergeTwoLists([], [1,3]); // => [1,3]
* @param {number[]} prices - Array with daily stock prices
*
* @param {ListNode} l1 - The root node of list 1
* @param {ListNode} l2 - The root node of list 2
*/
function mergeTwoLists(l1, l2) {
// end::description[]
Expand Down