题目
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。
解题思路
递归法
这应该是最直观的方法:
递归到链表结束,回溯到时候开始计数,直到 k === 0
时,取当前的 head
节点。
代码
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var getKthFromEnd = function(head, k) {
const helper = (head) => {
if (!head) {
return
}
helper(head.next)
if (--k === 0) {
res = head
}
}
let res = null
helper(head)
return res
};
直接遍历法
遍历拿到链表的长度 (N),倒数第 (k) 个节点就是第 (N - k) 个节点。
代码
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var getKthFromEnd = function(head, k) {
const getListLength = (head) => {
if (!head) {
return 0
}
let fast = head.next
let count = 0
while (fast && fast.next) {
count++
fast = fast.next.next
}
return fast ? 2 * count : 2 * count + 1
}
const N = getListLength(head)
for (let i = N - k; i > 0; i--) {
head = head.next
}
return head
};
双指针法
设置快慢指针,其中 fast
先走 (k) 步,然后 slow
和 fast
一起走,直到 fast
为空时,slow
就走了 (N - k) 步,此时 slow
指向倒数第 (k) 个节点。
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var getKthFromEnd = function(head, k) {
let slow = head
let fast = head
while (k) {
fast = fast.next
k--
}
while (fast) {
slow = slow.next
fast = fast.next
}
return slow
};
搜索「tony老师的前端补习班」关注我的微信公众号,那么就可以第一时间收到我的最新文章。