Reputation: 185
class LinkedListNode {
constructor(value) {
this.value = value;
this.next = null;
}
}
let head = new LinkedListNode("head");
let x = [1, 1, 1, 1, 4, 10, 10, 3, 10, 9, 5, 5, 5, 8];
for (let ele of x) {
let y = new LinkedListNode(ele);
let pointer = head;
while (pointer.next != null) {
pointer = pointer.next;
}
pointer.next = y;
}
Can someone explain why the following 'solution' leads to an infinite loop?
let removeDup = function(sll) {
let array = []
let pointer = sll;
while (pointer) {
if (array.includes(pointer.value)){
} else {
array.push(pointer.value);
sll.next = pointer;
sll = sll.next;
}
pointer = pointer.next;
}
}
It appears that if I
let pointer = sll.next;
or
let array = [sll.value]
then it works fine but if I run it as is then it leads to an infinite loop. I can see why it may make a linked list with 2 duplicates of the first value but I can't understand why it makes an infinite loop. Alternatively, if anyone can point me in the right direction for debugging this then that would be appreciated also!
Upvotes: 0
Views: 392
Reputation: 26191
You may write a micro Linked List library perhaps. Here is one with function descriptions;
toList
: takes an array converts it into a listfoldList
: Something like reduce. Takes a list, a function and an accumulator.sum
: takes a list and gives it's sum :)prt
: pretty print a listnub
: remove dupes from a list.function List(e){
this.data = e;
this.next = null;
}
List.fromArray = function([a,...as]){
var h = new List(a),
t = as.reduce((l,e) => [l[0],l[1].next = new List(e)], [h,h]);
return t[0];
};
List.prototype.fold = function (f,a){
var newa = f(a, this.data);
return this.next ? this.next.fold(f, newa)
: newa
};
List.prototype.log = function(){
return this.fold((a,e) => a + e + " -> ", "") + "null";
};
List.prototype.nub = function(){
var o = this.fold((a,e) => (a[e] = e, a), {}),
a = Object.values(o);
return List.fromArray(a);
}
var arr = [1, 1, 1, 1, 4, 10, 10, 3, 10, 9, 5, 5, 5, 8],
lst = List.fromArray(arr),
sum = l => l.fold((a,e) => a + e, 0), // just for fun
res = lst.nub().log();
console.log(res);
nub
is O(n).
Upvotes: 0
Reputation: 5703
You can use a debugger, but for primitive people like me, you can also use console.log
let count = 0
while (pointer && count++<5) {
//whatever
}
Even if you fail in your algorithm you will still exit
Be creative and spam console.log wherever you see fit. put some string to remind you what junk you outputed
while (pointer) {
if (array.includes(pointer.value)){
console.log('cached skip')
} else {
console.log('pointervalue', pointer.value)
array.push(pointer.value);
sll.next = pointer;
sll = sll.next;
console.log('sllendloop', sll)
}
pointer = pointer.next;
}
Note: do not use array for cache because it is O(n) look
You may use a Set (O(1)) instead
const removeDup = function(sll) {
const dupes = new Set()
let cur = { next: null }
// you can also as you suggested initialize cur as sll
// in which case you must mark it as "consumed" idem add the value to dupes
let sllIter = sll
while (sllIter) {
if (dupes.has(sllIter.value)) {
// early continue to avoid nesting else
// subjective preference
sllIter = sllIter.next
continue
}
dupes.add(sllIter.value)
// link our node to the currently being iterated node
cur.next = sllIter;
// advance our node
cur = sllIter
// advance iter
sllIter = sllIter.next
}
return sll
}
const l = (value, next) => ({ value, next })
const sllStr = ({ value: a, next: b }) => b ? `${a} -> ${sllStr(b)}`: a
const sll = l(1, l(1, l(2, l(1, l(2, l(3))))))
console.log(sllStr(removeDup(sll))) // 1 -> 2 -> 3
Upvotes: 0
Reputation: 3126
Looks like you end up defining a node that references itself within your else condition.
You may be looking for something like this:
class LinkedListNode {
constructor(value) {
this.value = value;
this.next = null;
}
}
let head = new LinkedListNode("head");
let x = [1, 1, 1, 1, 4, 10, 10, 3, 10, 9, 5, 5, 5, 8];
for (let ele of x) {
let y = new LinkedListNode(ele);
let pointer = head;
while (pointer.next != null) {
pointer = pointer.next;
}
pointer.next = y;
}
function removeDup(currentNode = sll) {
const seen = {};
let lastUnique;
while (currentNode) {
if (seen[currentNode.value]) {
lastUnique.next = currentNode.next;
} else {
seen[currentNode.value] = true;
lastUnique = currentNode;
}
currentNode = currentNode.next;
}
}
removeDup(head);
let outputNode = head;
while (outputNode) {
outputNode = outputNode.next;
if (outputNode) {
console.log(outputNode.value);
}
}
Upvotes: 1