问题主要在于the problem 的呈现方式。输入看起来就像数组一样,因为它们的格式与 JS 数组完全一样。但是输入应该是一个链表。在入门代码的顶部有这样的评论:
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
尽管从描述中肯定不是很明显,但这是他们将提供给您的代码的ListNode 的一个实例。 (参数名称head 是一个提示,因为这是传统上赋予单链表中初始节点的名称。)
因此,您需要能够提供这样的对象作为您自己的测试的输入。我们可以通过多种方式做到这一点。我们可以简单地将以下内容用于显示为[1, 1, 2, 3, 3] 的内容:
const head1 = new ListNode (
1,
new ListNode (
1,
new ListNode (
2,
new ListNode (
3,
new ListNode (
3,
// No `next`. This is the end of the lined list.
)
)
)
)
)
或者,我们可以利用这样一个事实,虽然我们有一个构造函数,但它只有静态属性,完全跳过构造函数来使用它进行测试:
const head2 =
{val: 1, next: {val: 2, next: {val: 2, next: {val: 3, next: {val: 3, next: null}}}}}
这两个看起来都很尴尬,所以也许我们可以编写代码来将数组转换为正确的链表并返回。但首先,我们如何显示这些?我们可以console .log 结果,但比较它们很尴尬。将它们转换为更有用的格式会很好,这也是为我们的转换代码预热的好方法。这是一个简单的display 函数,我觉得它很有用:
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'
所以现在我们想从一个简单的数组开始,然后把它变成一个链表。这是一个相当简单的递归过程:
const fromArray = ([x, ...xs]) => xs .length > 0
? new ListNode (x, fromArray (xs))
: new ListNode (x)
这里我们将数组视为递归结构,值后跟 null 或另一个数组。通过将我们的输入解构为[x, ...xs],这是自动的,我们可以使用xs 上的length 属性来确定我们何时达到基本情况。
使用display,我们可以很容易地验证这一点:
console .log (display (fromArray ([8, 6, 7, 5, 3, 0, 9])))
//=> 8 -> 6 -> 7 -> -> 5 -> 3 -> 0 -> 9
为了完整起见,让我们也写一个相反的方法:
const toArray = (node) => [
node .val,
... (node .next ? toArray (node .next) : [])
]
这使用相同类型的递归结构,但相反,将node .next 的结果(如果存在)传播到node .val 之后的数组中
所以现在我们可以把所有这些放在一起
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]))))
我们可以看到这个解决方案适用于样本输入。既然您拥有这些工具,那么看看您是否可以提出自己的方法可能会很有趣。 (一个提示:我的方法可能使用toArray 和fromArray,中间有一些魔法;它的效率可能比这里的方法低,但它很有趣。)