今天的题很简单了,我的思路就是遍历两次,第一次记录长度,第二次遍历到一半就就行,直接贴代码了
时间复杂度:O(N),其中 N 是给定链表的结点数目。
空间复杂度:O(1),只需要常数空间存放变量和指针。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* middleNode(ListNode* head) {
vector<int>num(0);
int i = 0;
ListNode *p = head;
while(p)
{
i++;
p = p->next;
}
//第二次遍历一半即可
p = head;
int j = 0;
while(j < i/2)
{
j++;
p = p->next;
}
return p;
}
};
}
};
官方改进
用两个指针来进行操作,slow一次移动一个位置,fast一次移动两个位置,这样当 fast 到达链表的末尾时,slow 必然位于中间。
时间复杂度:O(N),其中 N 是给定链表的结点数目。
空间复杂度:O(1),只需要常数空间存放 slow 和 fast 两个指针。
class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head;
while (fast != NULL && fast->next != NULL) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
};
官方数组解法
时间复杂度:O(N),其中 N 是给定链表中的结点数目。
空间复杂度:O(N),即数组用去的空间。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* middleNode(ListNode* head) {
vector<ListNode*>num;
ListNode *p = head;
while(p)
{
num.push_back(p);
p = p->next;
}
return num[num.size()/2];
}
};