LeetCode算法第五天(双指针)--JS

第一题:

题目描述:

给你单链表的头结点 head ,请你找出并返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

来源:力扣(LeetCode)
链接:力扣

解题思路:

刚接触关于单链表的算法题,是按照之前数组的常规思维去做,当输出 head.length 的时候才发现了错误,因为单链表无法通过访问下标拿到元素,因此可以通过遍历元素存储到数组中,然后通过遍历获取 数组和单链表 的长度,通过 IndexList.length / 2 的位置拿出元素。

看到有大佬对代码进行了优化,运用了双指针,主要思路为:定义两个指针 slow 与 fast 同时遍历链表。slow 一次走一步,fast 一次走两步;当 fast 到达链表的末尾时,slow 必然位于中间。

补充一个小知识:

向下取整:Math.floor()

向上取整:Math.ceil()

只删除小数,不向上/下舍入:Math.trunc()

var middleNode = function(head) {
    // 将链表转换为数组
    let List = [head];
    while(List[List.length-1].next != null) {
        // 追加元素从而得到数组长度
        List.push(List[List.length-1].next)
    }
    return List[Math.trunc(List.length / 2)];
};

双指针法:

var middleNode = function(head) {
    slow = fast = head;
    while (fast && fast.next) {
        slow = slow.next;
        fast = fast.next.next;
    }
    return slow;
};

此方法链接:https://leetcode.cn/problems/middle-of-the-linked-list/solution/lian-biao-de-zhong-jian-jie-dian-by-leetcode-solut/

第二题:

题目描述:

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

来源:力扣(LeetCode)
链接:力扣

解题思路:

单链表的题太致命了,因为要删除倒数的元素,而 .next 是从前向后遍历头节点。

因此定义在倒数第n个元素之前的 那个元素为 pre_n,并让快指针比慢指针先走 n-1 步,在慢指针开始走的第一步时 便到达了所要删除的那个元素的位置。

此时,跳过那个元素,存储了 慢指针之前所遍历的元素之外(pre_n内),让pre_n.next 是 left.next,就成功跳过了那个元素。如果是删除第一个元素则直接返回 left.next

var removeNthFromEnd = function(head, n) {
    // 定义倒数第 n 个结点 的前一个结点
    let pre_n = null;
    // 定义慢指针,用于找到要删除的元素,返回其之后的部分
    let left = head;
    // 定义快指针,用于遍历整个链表,比慢指针先走n-1步
    let right = head;
    // 以 [1,2,3,4,5]  n=4 为例
    for(let i=1; i<=n-1; i++) {
        right = right.next;
        // 1 [2,3,4,5]  2 [3,4,5]  3 [4,5]
        // console.log(i, right);  
    }
    // 如果不是删除最后一个元素
    while(right.next != null) {
        // 前一个结点的值为 left 的之前一次的值
        pre_n = left; // [1,2,3,4,5]
        left = left.next; // [2,3,4,5]
        right = right.next; // [5]
    }
    // 如果删除是第一个元素
    if(pre_n == null) {
        return left.next; // [2,3,4,5]
    }
    else {
        // 跳过 倒数第n个结点
        pre_n.next = left.next;
    }
    return head;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

低保和光头哪个先来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值