TL;DR
取得链表的第 N 个节点。系列目次见 前言和目次 。
需求
完成一个 getNth()
要领,传入一个链表和一个索引,返回索引代表的节点。索引以 0 为肇端,第一个元素索引为 0 ,第二个为 1 ,以此类推。比方:
getNth(1 -> 2 -> 3 -> null, 0).data === 1
getNth(1 -> 2 -> 3 -> null, 1).data === 2
传入的索引必需是在效范围内,即 0..length-1
,假如索引不合法或许链表为空都须要抛出非常。
递归版本
假定函数定义为 getNth(head, idx)
,递归历程为:当 idx
为零,直接返回该节点,不然递归挪用 getNth(head.next, idx - 1)
。再处置惩罚下边境状况就完成了,代码以下:
function getNth(head, idx) {
if (!head || idx < 0) throw 'invalid argument'
if (idx === 0) return head
return getNth(head.next, idx - 1)
}
轮回版本
我挑选的 for
轮回,如许方便把边境状况搜检都放到轮回里去。假如轮回完毕还没有查到节点,那肯定是链表或许索引不合法,直接抛非常即可。对照这两个版本和 02 Length & Count 的例子,不难看出轮回能够比递归更轻易地处置惩罚边境状况,由于一些前提搜检能够写进轮回的头部,递归就得本身写 if/else
逻辑。
function getNthV2(head, idx) {
for (let node = head; node && idx >= 0; node = node.next, idx--) {
if (idx === 0) return node
}
throw 'invalid argument'
}