1. 程式人生 > 實用技巧 >連結串列 876.連結串列的中間節點

連結串列 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;
    }
}

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

長風破浪會有時,直掛雲帆濟滄海。

——李白