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

题目来源

思路

 1、题目的意思就是要找出中间节点,奇数个节点返回中间节点,偶数个节点返回第二个中间节点。比较容易想到的思路是,先循环遍历一遍链表,就知道了链表的长度,这样下次遍历一半就可以找出中间节点了。

2、第二个思路类似于比例尺,1:2的比例去遍历,即定义两个速度不一样的指针,快指针的速度是慢指针速度的两倍,这样一来,当快指针跑完链表,慢指针就在链表的中间节点处,这个思路比较巧妙。

代码实现

思路1

/**

*Java

*/

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode middleNode(ListNode head) {
        int num=0;//记录链表长
        ListNode p = head;

        while( p != null )
        {
            p = p.next;
            num++;
        }
        p=head;
        for( int i = 1 ; i <= num/2 ; i++ )
        {
            p = p.next;
        }

        return p;
    }
}

思路2

/**

*C语言

*/

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* middleNode(struct ListNode* head){
    struct ListNode *fast = head , *slow = head;

    while( fast != NULL && (fast->next != NULL) )
    {
        fast = fast->next->next;
        slow = slow->next;
    }

    return slow;
}

/**

*Java

*/

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode middleNode(ListNode head) {
        ListNode fast = head , slow = head;

        while( fast != null && fast.next != null )
        {
            fast = fast.next.next;
            slow = slow.next;
        }

        return slow;
    }
}

 

行路难,行路难,多歧路,今安在?

长风破浪会有时,直挂云帆济沧海。

——李白

 

posted @ 2020-08-03 20:36  Rego  阅读(87)  评论(0编辑  收藏  举报