算法---LeetCode 876. 链表的中间结点(链表问题常用技巧)

1. 题目

原题链接

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

示例 1:

输入:[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.

示例 2:

输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。

提示:

给定链表的结点数介于 1 和 100 之间。

Related Topics 链表 双指针
👍 353 👎 0

2. 题解

2.1 解法1: 快慢指针

    class Solution {
        public ListNode middleNode(ListNode head) {
            if (head == null) {
                return null;
            }
            ListNode fast = head;
            ListNode slow = head;
            while (fast != null && fast.next != null) {
                fast = fast.next.next;
                slow = slow.next;
            }
            return slow;
        }
    }

2.2 解法2: 两次遍历

第一次遍历计算链表的长度, 然后得出中点位置, 然后再遍历找到中间结点

    class Solution {
        public ListNode middleNode(ListNode head) {
            if (head == null) {
                return null;
            }
            ListNode cur = head;
            int len = 0;
            while (cur != null) {
                len++;
                cur = cur.next;
            }
            int k = len / 2;
            cur = head;
            while (k > 0) {
                cur = cur.next;
                k--;
            }
            return cur;
        }
    }

3. 链表问题常用技巧

  1. 使用递归函数,避免复杂的更改指针变量指向操作,使得求解问题变得简单。
    「力扣」第 206 题:反转链表;
    「力扣」第 24 题:两两交换链表中的节点;
    「力扣」第 25 题:K 个一组翻转链表;
    「力扣」第 328 题:奇偶链表;
    「力扣」第 203 题:移除链表元素;
    「力扣」第 21 题:合并两个有序链表。
  2. 设置「虚拟头结点」,避免对链表第 1 个结点做单独讨论,这个思想在数组里我们见过,叫「哨兵」;
    「力扣」第 2 题:两数相加;
    「力扣」第 82 题:删除排序链表中的重复元素 II。
  3. 使用「快慢指针」,本题就是。确切地说,叫「同步指针」可能更好一些;
  4. 打草稿很重要: 绝大多数时候在草稿纸上写写画画就能得到解决链表问题的办法,特别是在链表中做一些更改指针变量指向操作的问题
  5. 为链表编写测试函数,进行调试(在下面的参考代码中有),主要是:
    从数组得到一个链表;
    根据当前结点打印当前结点以及后面的结点。
    这两个方法可以非常方便地帮助我们调试关于链表的程序。

快慢指针(注意链表长度为偶数时,返回第 2 个结点的细节)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值