Given a non-empty, singly linked list with head node head
, return a middle node of linked list.html
If there are two middle nodes, return the second middle node.node
Example 1:git
Input: [1,2,3,4,5] Output: Node 3 from this list (Serialization: [3,4,5]) The returned node has value 3. (The judge's serialization of this node is [3,4,5]). Note that we returned a ListNode object ans, such that: ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, and ans.next.next.next = NULL.
Example 2:github
Input: [1,2,3,4,5,6] Output: Node 4 from this list (Serialization: [4,5,6]) Since the list has two middle nodes with values 3 and 4, we return the second one.
Note:数组
1
and 100
.
这道题给了一个链表,让咱们找其中间结点。因为链表不像数组,不能经过坐标位置来直接访问元素,而是只能从头结点开始,使用 next 指针来访问以后的结点,为了知道当前结点的位置,还得使用计数器来记录。因为在不知道链表的总长度以前,是没法知道中间结点的位置的,那么能够首先遍历一遍,统计出链表的长度,此时长度有了,除以2就是中间结点的位置了,再从头遍历一遍,就能够找出中间结点的位置了,参见代码以下:this
解法一:spa
class Solution { public: ListNode* middleNode(ListNode* head) { ListNode *cur = head; int cnt = 0; while (cur) { ++cnt; cur = cur->next; } cnt /= 2; while (cnt > 0) { --cnt; head = head->next; } return head; } };
因为链表没法经过坐标位置来访问元素,但咱们能够将全部的结点按顺序存入到一个数组中,那么以后就能够直接根据坐标位置来访问结点了,参见代码以下:指针
解法二:code
class Solution { public: ListNode* middleNode(ListNode* head) { vector<ListNode*> vec(100); int cur = 0; while (head) { vec[cur++] = head; head = head->next; } return vec[cur / 2]; } };
上面两种方法一个多用了时间,一个多用了空间,其实都不是最优的解法,最好的方法实际上是使用快慢指针来作。在以前那道 Linked List Cycle 链表中找环的题,咱们介绍过快慢指针,就是两个指针,慢指针一次走一步,快指针一次走两步,那么这里当快指针走到末尾的时候,慢指针恰好走到中间,这样就在一次遍历中,且不须要额外空间的状况下解决了问题,参见代码以下:htm
解法三:
class Solution { public: ListNode* middleNode(ListNode* head) { ListNode *slow = head, *fast = head; while (head && head->next) { slow = slow->next; head = head->next->next; } return slow; } };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/876
相似题目:
参考资料: