数据结构与算法 | Leetcode 876. middle-of-the-linked-list

原文连接: https://wangwei.one/posts/jav...

前面,咱们实现了 删除单链表倒数第N个节点 操做,本篇来聊聊,如何求一个链表的中间节点。html

求链表的中间结点

Leetcode 876. Middle of the Linked List

给定一个非空的单链表,要求返回它的中间节点,若是中间节点有两个则返回第二个。java

例如:算法

Input: [1,2,3,4,5]
Output: Node 3 from this list
Input: [1,2,3,4,5,6]
Output: Node 4 from this list

解法一

第一种解法的思路比较容易想获得,先计算出链表的总长度,再计算出中间节点的下标,而后得遍历获得对应的节点便可。数据结构

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode middleNode(ListNode head) {
        if(head == null){
            return null;
        }
        int len = 0;
        for(ListNode curr = head; curr != null; ){
            len++;
            curr = curr.next;
        }
        int targetIndex = 0;
        ListNode target = null;
        for(ListNode curr = head; curr != null; ){
            if(targetIndex == len / 2){
                target = curr;
                break;
            }
            targetIndex++;
            curr = curr.next;
        }
        return target;
    }
}

解法二

第二种解法,使用快慢指针,让快指针的移动速度是慢指针的两倍,等到快指针到达终点时,慢指针刚好抵达中间节点。post

一段小路上,A车行驶的速度是B车的两倍,等到A车到达终点时,B车刚好达到小路的中间位置。

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    
    public ListNode middleNode(ListNode head) {
        if(head == null){
            return null;
        }
        
        ListNode slow = head;
        ListNode fast = head;
        
        for(ListNode curr = slow; slow != null; ){               
            if(fast == null || fast.next == null){
                break;
            }else{
                fast = fast.next.next;
            }
            slow = slow.next;
        }
        return slow;        
    }
}

到目前为止,咱们已经使用快慢指针解决三个单链表相关的问题了:this

单链表环检测

删除单链表倒数第N个节点spa

求链表的中间结点指针

解法三

解法三也比较巧妙, 遍历单链表,只有当下标为奇数时,指针才向前移动,到最后,指针所指即为中间节点。code

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    
    public ListNode middleNode(ListNode head) {
        if(head == null){
            return null;
        }
        ListNode target = head;
        int index = 0;
        for(ListNode curr = head; curr != null; ){
            if(index % 2 == 1){
                target = target.next;
            }
            index++;
            curr = curr.next;
        }
        return  target;    
    }
}

以上三种解法的时间复杂度均为O(n),在leetcode上的运行时间为 1ms,超过 82.96%htm

相关练习

参考资料

相关文章
相关标签/搜索