i have been working on the leetcode problems these days but i always get stuck with the problems where the solutions have the .next syntax. normally i used to run the solutions in my VScode console to see what it happens. but my Vscode console doesn't recognize the .next syntax so...
can someone explain me by this " 83. Remove Duplicates from Sorted List " solution ? https://leetcode.com/problems/remove-duplicates-from-sorted-list/description/
var deleteDuplicates = function(head) {
var current = head;
while(current) {
if(current.next !== null && current.val == current.next.val) {
current.next = current.next.next;
} else {
current = current.next;
}
}
return head;
};
deleteDuplicates([1,1,2,3,3])
i tried put the solution on my Vscode console and use console.log() to see what is happening but for some reason my console doesn't recognize the .next syntax, despite it works perfectly on the leetcode console
CodePudding user response:
The issue is mostly in the way the problem is presented. The input looks to all the world like it's arrays, as they are formatted exactly as JS arrays. But the input is supposed to be a linked list. At the top of the starter code there is this comment:
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
Although it certainly isn't obvious from the description, it's an instance of a listNode
that they will supply to your code. (The parameter name head
is meant to be a hint for that, since that is the name traditionally given to the initial node in a singly-linked list.)
So you need to be able to supply such an object as input for your own testing. We could do this in several ways. We could simply use the following for what they show as [1, 1, 2, 3, 3]
:
const head1 = new ListNode (
1,
new ListNode (
2,
new ListNode (
2,
new ListNode (
3,
new ListNode (3)
)
)
)
)
Or, we could take advantage of the fact that although we have a constructor function, all it has is static properties, and skip the constructor altogether to use this for testing:
const head2 =
{val: 1, next: {val: 2, next: {val: 2, next: {val: 3, next: {val: 3, next: null}}}}}
Both of those seem awkward, so perhaps we can write code to convert an array to a proper linked list and back. But first, how do we display these? We can console .log
the results, but comparing them is awkward. It would be nice to turn them into a more useful format, and this is also a good way to warm up for our conversion code. Here's a simple display
function that I would find useful:
const display = (node) =>
node .val (node .next ? ` -> ${display (node .next)}`: '')
console .log (display (head1)) //=> '1 -> 1 -> 2 -> 3 -> 3'
console .log (display (head2)) //=> '1 -> 1 -> 2 -> 3 -> 3'
So now we want to start with a simple array and turn that into a linked list. It's a fairly simple recursive process:
const fromArray = ([x, ...xs]) => xs .length > 0
? new ListNode (x, fromArray (xs))
: new ListNode (x)
Here we treat the array as a recursive structure, with a value followed by either null
or another array. By destructuring our input into [x, ...xs]
, this is automatic, and we can use the length
property on xs
to determine when we've hit our base case.
Using display
we can verify this pretty easily:
console .log (display (fromArray ([8, 6, 7, 5, 3, 0, 9])))
//=> 8 -> 6 -> 7 -> -> 5 -> 3 -> 0 -> 9
For completeness, let's also write one that goes the other way:
const toArray = (node) => [
node .val,
... (node .next ? toArray (node .next) : [])
]
This uses the same sort of recursive structure, but in reverse, spreading the result of node .next
-- if it exists -- into an array right after node .val
So now we can put all this together as
function ListNode(val, next) {
this.val = (val===undefined ? 0 : val)
this.next = (next===undefined ? null : next)
}
const fromArray = ([x, ...xs]) => xs .length > 0
? new ListNode (x, fromArray (xs))
: new ListNode (x)
const display = (node) =>
node .val (node .next ? ` -> ${display (node .next)}`: '')
const deleteDuplicates = (head) => {
let current = head
while (current) {
if (current .next !== null && current .val == current .next .val) {
current .next = current .next .next
} else {
current = current .next
}
}
return head
}
console .log (display (deleteDuplicates (fromArray ([1, 1, 2, 3, 3]))))
And we can see that this solution works for the sample input. It might be interesting to see if you can come up with your own approach now that you have these tools. (One hint: my approach might use toArray
and fromArray
with some magic in the middle; it's probably less efficient that the approach here, but it's interesting.)
CodePudding user response:
Honestly, my best answer to you would be run your code in node.js inside Replit online IDE.