Linked List remove method by value with Javascript - javascript

Trying to get this linked list remove method to work. should remove a node from the middle if that is where the value is found, and preserve the rest of the sequence. should not modify the list sequence if the last node is the node to be removed. it also should replace the start node with the second node when the first node value is x and the remove function is called with the value x.
remove(valueToRemove) {
let currentNode = this.firstNode;
let previousNode;
let foundValue = valueToRemove = currentNode.value;
while (!foundValue) {
previousNode = currentNode;
currentNode = currentNode.next;
if (!currentNode) {
return;
}
foundValue = valueToRemove === currentNode.value;
}
let nextNode = currentNode.next;
if (currentNode === this.firstNode) {
this.firstNode = nextNode;
} else {
previousNode.next = nextNode;
}
this.listSize--;
}

In the below code you are equating the values hence overriding the valueToRemove
let foundValue = valueToRemove = currentNode.value;
change it to
let foundValue = valueToRemove === currentNode.value;

Related

Check Palindrome Linked List

I intended to reverse the original LinkedList and compare it with reversed one. If it is identical return true. However, I keep getting the wrong results. Where I did wrong?
var isPalindrome = function(head) {
if(head == null || head.next == null) return true;
let reversedHead = reverse(head)
let count = 0
while (head != null && reversedHead != null) {
if(head.val != reversedHead.val) {
return false
}
head = head.next
reversedHead = reversedHead.next
}
if (head == null && reversedHead == null){
return true
} else {
return false
}
};
var reverse =(head)=> {
let prev = null
let next = new ListNode()
let curr = new ListNode()
curr = head
while(curr){
next = curr.next
curr.next = prev
prev = curr
curr = next
}
return prev
}
After you call:
let reversedHead = reverse(head)
You will have reversed the list, i.e. the head has become the tail, and a tail's next reference is null. Hence your loop will quickly end, as after:
head = head.next
... head will be null.
You need to rethink the algorithm. There are several ways to do it...
Instead of an inplace reversal, you could let reverse return a completely new linked list that will have the reversed order:
function reverse(head) { // Does not modify the given list. Returns a new one.
let node = head;
let reversedHead = null;
while (node) {
reversedHead = new ListNode(node.val, reversedHead);
node = node.next;
}
return reversedHead;
}
I assume here that the ListNode constructor accepts a second argument:
class ListNode {
constructor(val, next=null) {
this.val = val;
this.next = next;
}
}

Javascript - Merge two sorted linked lists understanding

I'm trying to figure out why in the following function, at certein point they do mergedTail.next = temp; mergedTail = temp; Instead of to have only mergedTail = temp;:
let merge_sorted = function(head1, head2) {
// if both lists are empty then merged list is also empty
// if one of the lists is empty then other is the merged list
if (!head1) {
return head2;
} else if (!head2) {
return head1;
}
let mergedHead = null;
if (head1.data <= head2.data) {
mergedHead = head1;
head1 = head1.next;
} else {
mergedHead = head2;
head2 = head2.next;
}
let mergedTail = mergedHead;
while (head1 && head2) {
let temp = null;
if (head1.data <= head2.data) {
temp = head1;
head1 = head1.next;
} else {
temp = head2;
head2 = head2.next;
}
mergedTail.next = temp;
mergedTail = temp;
}
if (head1) {
mergedTail.next = head1;
} else if (head2) {
mergedTail.next = head2;
}
return mergedHead;
};
Many thanks.
mergedTail always refers to the last element of the merged list. temp is set to the element that should be appended to that list next.
By setting mergedTail.next = temp, the element temp is appended to the merged list. But now mergedTail no longer refers to the last element, but to the second-to-last element. So we assign mergedTail = temp to move it one step ahead, and maintain our invariant.
I would personally have preferred mergedTail = mergedTail.next, which is equivalent and maybe slightly less efficient, but makes the intent clearer.

Traversing nodes: Why check if node was included already?

In this breadth first traversal of a DOM, what is the purpose of visitedNodes array and how
does !visitedNodes.includes(currentNode) work? What if I have 2 identical div's with the same class? Wouldn't that check skip the 2nd div since it's identical? That doesn't seem like ideal behavior, right?
function bfs() {
const nodesToVisit = [];
const visitedNodes = [];
nodesToVisit.push(document.getElementsByClassName("a")[0]);
const log = document.getElementById("results");
while (nodesToVisit.length > 0) {
let currentNode = nodesToVisit.pop(); // from the front!
if (currentNode && !visitedNodes.includes(currentNode)) {
visitedNodes.push(currentNode);
if (currentNode.nodeType == 1) {
let logItem = document.createElement("p");
let logText = document.createTextNode(currentNode.className);
logItem.appendChild(logText);
log.appendChild(logItem);
}
[].slice.call(currentNode.childNodes).reverse()
.forEach(function(node) {
nodesToVisit.push(node);
})
}
}
}

Implement the addInPos method inside the LinkedList prototype in Javascript

I need to implement the addInPos method inside the LinkedList prototype but I don't know what it is bad in my code...because the test no pass.
Implement the addInPos method inside the LinkedList prototype that must add an element in the indicated position. Both data will be provided as a parameter (pos, value). Where "pos" will be the position in which the "value" value should be added. In the event that the position in which the insertion is to be made is invalid, that is, it exceeds the size of the current list, it must return false.
If the node was added correctly return true.
Note: the zero position corresponds to the head of the LinkedList.
My code:
LinkedList.prototype.addInPos = function(pos, value) {
if(pos > this.size) {
return false;
}
const newNode = new Node(pos, value);
let current = this.head;
let previous;
if(pos === 0) {
newNode.next = current;
current.prev = newNode;
this.head = newNode;
} else {
for(let i = 0; i < pos; i++){
previous = current;
current = current.next;
}
newNode.next = current;
newNode.prev = previous;
current.prev = newNode;
previous.next = newNode;
}
}
Thanks.
With your structure ideally insertAt function would look like:
var insertAt = function(head, item, index) {
var curr = head;
var count = 0;
while (curr !== null) {
if (count === index) {
var newNode = { data: item, next: curr.next, prev: curr };
curr.next = newNode;
break;
}
count++;
curr = curr.next;
}
};
insertAt(head, 2, 3);
Let me know if this works.
Also look at this LinkedList class I have created, insertAt function is currently missing, but from this stack question, I am planning to add it in my class as well.
Class GitHub
NPM package - #dsinjs/linked-list
Complete documentation

Copy List with Random Pointer - Copy not point to -

I'm trying to solve the problem below:
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.
The Linked List is represented in the input/output as a list of n nodes. Each node is represented as a pair of [val, random_index] where:
val: an integer representing Node.val
random_index: the index of the node (range from 0 to n-1) where random pointer points to, or null if it does not point to any node.
Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
Output: [[7,null],[13,0],[11,4],[10,2],[1,0]]
My idea was loop the head and create a new node with the same value and set it to my ans Node. It will be a copy because I'm creating a new one. Then, I loop again for the random pointer which looks in my ans Node the node with the value that I should point to. It works perfectly for the input above. However, if I have an input with duplicate values, the findeNode method might return an invalid Node. For example it fails for the input below:
[[3,null],[5,17],[4,null],[-9,6],[-10,3],[5,15],[0,11],[6,null],[-6,16],[3,16],[-6,11],[9,12],[-2,1],[-3,11],[-1,10],[2,11],[-3,null],[-9,7],[-2,4],[-8,null],[5,null]]
My output:
[[3,null],[5,3],[4,null],[-9,null],[-10,3],[5,15],[0,11],[6,null],[-6,13],[3,13],[-6,11],[9,12],[-2,1],[-3,11],[-1,8],[2,11],[-3,null],[-9,7],[-2,4],[-8,null],[5,null]]
Correct output:
[[3,null],[5,17],[4,null],[-9,6],[-10,3],[5,15],[0,11],[6,null],[-6,16],[3,16],[-6,11],[9,12],[-2,1],[-3,11],[-1,10],[2,11],[-3,null],[-9,7],[-2,4],[-8,null],[5,null]]
Node definition:
function Node(val, next, random) {
this.val = val;
this.next = next;
this.random = random;
};
My code:
var copyRandomList = function(head) {
if(!head) return head;
let ans = new Node(0);
let temp = ans;
let cur = head;
while(cur) {
const node = new Node(cur.val);
temp.next = node;
cur = cur.next;
temp = temp.next;
}
cur = head;
temp = ans.next;
while(cur) {
const randomNode = cur.random;
if(!randomNode) {
temp.random = null;
} else {
const node = findNode(ans, randomNode.val);
temp.random = node;
}
cur = cur.next;
temp = temp.next;
}
return ans.next;
};
const findNode = (list, val) => {
if(!val)
return null;
while(list) {
if(list.val === val)
return list;
list = list.next;
}
return null;
}

Categories

Resources