[路飞]_程序员必刷力扣题: 链表中倒数第k个节点

183 阅读2分钟

「这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

链表中倒数第k个节点

力扣链接

输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。

例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。

示例 1:

给定一个链表: 1->2->3->4->5, 和 k = 2.

返回链表 4->5.

利用数组存储节点

思路

返回第倒数第k个节点,我们知道,链表只能next访问下一位节点,并不能倒数访问上一个节点

所以我们只能遍历过每一个节点,并记录位置信息

方法很多,这里我们通过遍历链表,并且把链表的没一个节点都按顺序保存在数组stack中,这样我们就可以直接通过访问数组下标来直接获取对应的节点了stack[stack.length-k]

var getKthFromEnd = function(head, k) {
    var stack = []
    while(head){
        stack.push(head)
        head = head.next
    }
    return stack[stack.length-k]
};

双指针

思路

另外我们可以通过双指针的方式来获取,如何使用双指针呢?

其实双指针就是通过快慢指针之间的间距为k来标记长度为k的一段链表,

  • 指定双指针的位置,slow从头开始,fast要提前走k步,这样他们之间相差k个节点
  • 只要fast有值,则不断向后移动
  • 当fast链表末尾null的时候,因为间距为k,slow正好是倒数第k个节点

此时直接返回k节点

var getKthFromEnd = function(head, k) {
    if(!head) return head
    var slow = fast = head
    var n = 0
    while(n<k){
        fast = fast.next
        n++
    }
    while(fast){
        fast = fast.next
        slow = slow.next
    }
    return slow
};

迭代

思路

迭代是通过遍历链表获取链表的长度n,那么倒数第k个元素就是,n-k

所以第二次遍历链表 到n-k的位置,就是倒是第k各节点了

var getKthFromEnd = function(head, k) {
    if(!head) return head
    var node = head
    var n = 0
    //第一次遍历获取链表程度n
    while(node){
        node = node.next
        n++
    }
    var m = 0;
    var res = head
    //第二次遍历获取链表倒数第k个节点,正数第n-k+1
    while(m<n-k){
        res = res.next
        m++
    }
    return res
};