【LeetCode】876.链表的中间节点

题目描述

给定一个头结点为 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 之间。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        ListNode *p = head, *q = head; //p-fast q-slow
        while(p != NULL && p->next != NULL){
            q = q->next;
            p = p->next->next;
        }
        return q;
    }
};

心得
这一题主要考察快慢指针,由于对指针不熟悉,这道题想了很久,最后查看了题解,末尾附上参考资料,里面还包含了很多指针的相关解法。


第一道题有两种解法:
1常规解法
对指针进行两次遍历,第一次遍历获得指针的长度,第二次找到中间节点。
缺点:如果指针过长,那么遍历时间开销将会很大。
2 快慢指针
使用两个指针变量,刚开始都位于链表的第 1 个结点,一个永远一次只走 1 步,一个永远一次只走 2 步,一个在前,一个在后,同时走。这样当快指针走完的时候,慢指针就来到了链表的中间位置。

结束条件的考虑
要分成指针长度为奇数和偶数两种情况
【LeetCode】876.链表的中间节点_第1张图片

另外,如果题目变成:如果有两个中间结点,则返回第二个中间结点。
那么循环条件将变成:p->next! != NULL && p->next->next != NULL
【LeetCode】876.链表的中间节点_第2张图片


参考文献:指针相关问题

你可能感兴趣的:(LeetCode刷题,链表,leetcode,数据结构)