【LeetCode-链表】链表的中间节点

题目描述

给定一个带有头结点 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.

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

题目链接: https://leetcode-cn.com/problems/middle-of-the-linked-list/

思路1

使用快慢指针。slow 和 fast 都从链表头 head 出发,slow 每次走一步,fast 每次走两步,当 fast 为空时,slow 就是中间节点。代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        if(head==nullptr) return nullptr;

        ListNode* slow = head;
        ListNode* fast = head;
        while(fast!=nullptr && fast->next!=nullptr){
            fast = fast->next->next;
            slow = slow->next;
        }
        return slow;
    }
};

拓展

上面的那种写法在链表长度是偶数的情况下,返回的中间两个节点的后一个节点。如果想返回前一个节点,则只需要将循环的条件fast!=nullptr && fast->next!=nullptr改成fast->next!=nullptr && fast->next->next!=nullptr

class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        if(head==nullptr || head->next == nullptr) return nullptr;

        ListNode* slow = head;
        ListNode* fast = head;
        while(fast->next!=nullptr && fast->next->next!=nullptr){
            fast = fast->next->next;
            slow = slow->next;
        }
        return slow;
    }
};

思路2

还有一种方法就是先求链表的长度 n,然后再从头遍历到第 n/2 个节点即可。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        if(head==nullptr) return nullptr;

        int len = getLen(head);
        ListNode* dummy = new ListNode(0);
        dummy->next = head;
        ListNode* curNode = dummy;
        for(int i=0; i<len/2; i++){
            curNode = curNode->next;
        }
        return curNode->next;
    }

    int getLen(ListNode* head){
        int len = 0;
        while(head!=nullptr){
            len++;
            head = head->next;
        }
        return len;
    }
};

参考

思路 1 拓展参考了:https://leetcode-cn.com/problems/middle-of-the-linked-list/solution/kuai-man-zhi-zhen-zhu-yao-zai-yu-diao-shi-by-liwei/

posted @ 2020-07-13 15:46  Flix  阅读(384)  评论(0编辑  收藏  举报