首页 > 编程语言 >leetcode算法入门 Day5 双指针(四)

leetcode算法入门 Day5 双指针(四)

时间:2023-01-14 12:33:30浏览次数:40  
标签:结点 slow Day5 head fast next leetcode 指针

876. 链表的中间结点

给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。

输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/middle-of-the-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  最简单的想法是遍历两次,第一次求出链表长度,第二次删除中间节点,但是显然这中这与考察的目的不符,而且效率极低。
  那么有没有办法在一次遍历就完成操作呢?联系题目下双指针的tag想到利用快慢指针来完成这一操作。
  令快指针每次走两格,而慢指针顺序遍历,这样当快指针遍历结束后真好慢指针到达中央位置,代码如下:

class Solution {

    public ListNode middleNode(ListNode head) {
        ListNode fast=head,slow=head;
        while(fast!=null&&fast.next!=null) //此处必须判断fast和fast->next是否为空,不然出现null.next报错。
        {
            fast=fast.next.next;
            slow=slow.next;
        }
        return slow;
    }
}

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

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

head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

  本题最初的想法还是直接求长度然后遍历,但是联想到之前看到的一篇限流相关文章中提到的滑动窗口,突然意识到可以利用这种方法来完成。
  即首先初始时设定fast指针比slow指针快n个元素,那么当fast指针到最后一个元素时,slow真好说想要删除节点的前驱进行删除即可。
  注意:当n的长度>=n时,即删除首节点,此时直接操作slow节点即可。

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode fast=head,slow=head;
        for(int i=0;i<n&&fast!=null;i++)
        {
            fast=fast.next;
        }
        if(fast==null) //如果fast==null,说明此时需要删除的节点即为首节点
        {
            head=head.next;
        }
        else{
            while(fast.next!=null)
            {
                fast=fast.next;
                slow=slow.next;
            }
            slow.next=slow.next.next;
        }
        return head;
    }
}

标签:结点,slow,Day5,head,fast,next,leetcode,指针
From: https://www.cnblogs.com/zz-gy/p/17051580.html

相关文章