赞
踩
这是LeetCode上的 [876,链表的中间结点],难度为 [简单]
题意
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
示例1
输入:[1,2,3,4,5]
输出:此列表中的结点 3
示例2
输入:[1,2,3,4,5,6]
输出:此列表中的结点 4
题解(快慢指针)
思路分析
求链表中间结点需要清楚一下两个问题
当链表为偶数时,按理说是不存在中间结点,但题意要求它只需返回中间链的下一个结点作为中间结点(可以理解为从中间链断开分成两个链表,返回的是下一段链表的头结点),此时中间结点的左半段和右半段的结点并不相同
当链表为奇数时,存在中间结点,此时中间结点的左半段和右半段的结点相同
步骤
代码实现
public class Solution { public ListNode middleNode(ListNode head) { // 定义两个结点(快慢指针),初始为头结点 ListNode slow = head; ListNode fast = head; /* 遍历链表,循环终止分为两种情况 当fast为null时,即fast是尾结点的下一个结点时,循环终止,此时slow为中间链的下一结点 当fast的下一个结点为null时,即fast是尾结点时,循环终止,此时slow为链表的中间结点*/ while (fast != null && fast.next != null) { // slow每次移动一个结点 slow = slow.next; // fast每次移动两个结点 fast = fast.next.next; } return slow; } }
结点类
public class ListNode { Integer val; ListNode next; public ListNode() { } public ListNode(Integer val) { this.val = val; } public ListNode(Integer val, ListNode next) { this.next = next; } }
测试类
public class Test { @org.junit.Test public void test() { ListNode head = new ListNode(1); ListNode one = new ListNode(2); ListNode two = new ListNode(3); ListNode three = new ListNode(4); ListNode four = new ListNode(5); ListNode five = new ListNode(6); head.next = one; one.next = two; two.next = three; three.next = four; four.next = five; ListNode n = new Solution().middleNode(head); System.out.println(n.val); } }
复杂度分析
假设链表长度为n
时间复杂度:需要遍历链表,故时间复杂度为O(n)
空间复杂度:只声明了两个结点slow,fast,为常数,故空间复杂度为O(1)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。