【小f的刷题笔记】(JS)链表 - 单链表的倒数第 k 个节点 LeetCode19 & 单链表的中点 LeetCode876

【链表】

一、单链表的倒数第 k 个节点:

要求:只遍历一遍,链表有多长未知


LeetCode19

链接:

19.删除链表的倒数第N个结点

题目:

在这里插入图片描述

思路:

因为没有给头结点,我们就先定义一个哑结点,作为链表的头结点。
要删除倒数第n个结点,就要先找到倒数第n+1个结点x,然后再用x.next = x.next.next删掉倒数第n个。

封装一个找倒数第k个结点的函数,传入头结点和k。
先定义两个指针p1和p2都指向头结点,先让p1走k步,然后p1和p2一起走,直到p1===null,即两个指针一起走了n-k步,所以p2就指向了正数第n-k+1个结点,即为倒数第k个

在这里插入图片描述

🌟 链表注意点:

1️⃣ 设链表有n个结点,倒数第k个结点,就是正数第n-k+1个结点

2️⃣ 链表最后都会接一个空指针

代码:
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} n
 * @return {ListNode}
 */
var removeNthFromEnd = function(head, n) {
    // 还是先定义一个哑结点
    const dummy = new ListNode(-1)
    // 把哑结点跟链表连上,连在链表之前
    dummy.next = head
    // 要删除倒数第n个结点,就是要先找到倒数第n+1个结点
    let x = findEnd(dummy, n+1)
    // 删除那一个结点
    x.next = x.next.next
    return dummy.next
};

var findEnd = function(head, k) {
    // 先定义p1和p2同时指向头结点
    let p1 = head
    let p2 = head
    // 先让p1走k步
    for(let i=0; i<k; i++) {
        p1 = p1.next
    }
    // p1 和 p2 一起走n-k步,这样p2就是指向了n-k+1个节点,即倒数第k个节点
    while(p1 !== null) {
        p1 = p1.next
        p2 = p2.next
    }
    return p2
}


二、单链表的中点

要求:只遍历一遍,链表有多长未知

LeetCode876

链接:

876.链表的中间结点

题目:

在这里插入图片描述

思路:

【快慢指针】:

慢指针走一步,快指针走两步,当快指针走到链表末尾时,慢指针就走到了链表的中点

在这里插入图片描述

注意:

这里可以继续前进的条件是,当前快指针和当前快指针的下一个结点都非空 -> 当有两个中间结点时,找出来的是后一个

👉 如果题目要求在两个中间结点的时候,返回前一个中间结点,此时快指针可以前进的条件改为:当前快指针的下一个结点和当前快指针的下下一个结点都非空

代码:
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var middleNode = function(head) {
    // 快慢指针
    let slow = head, fast = head
    while(fast !== null && fast.next !== null) {
        // 慢指针走一步,快指针走两步
        slow = slow.next
        fast = fast.next.next
    }
    return slow
};

写在最后:
学校突然宣布放假了
的确不大喜欢计划被打乱的感觉
那就重新规划吧

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值