Open azl397985856 opened 2 years ago
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
class Solution:
def middleNode(self, head: ListNode) -> ListNode:
slow = head
fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow
显然。
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
示例 1:
输入:[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. 示例 2:
输入:[1,2,3,4,5,6] 输出:此列表中的结点 4 (序列化形式:[4,5,6]) 由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。
提示:
给定链表的结点数介于 1 和 100 之间。
fast->next
有可能会出现访问空指针fast
走一步,用一个 if
来判断是否可以走第二步,如果不行则直接返回此时的 slow
//language: c++
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode* fast = head;
ListNode* slow = fast;
while(fast->next != nullptr)
{
//奇数个结点
fast = fast->next;
slow = slow->next;
if(fast->next == nullptr)//偶数个才会碰到这种情况
return slow;//第二个中间结点
else fast = fast -> next;
// cout<<slow->val<<" ";
// cout<<fast->val<<endl;
}
return slow;
}
};
O(1)
O(n)
,其中 n
为链表长度class Solution(object):
def middleNode(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head:
return None
fast = head
slow = head
while(fast and fast.next):
slow = slow.next
fast = fast.next.next
return slow
通过之前的练习,大家一眼就可以看出来这个题可以用快慢指针来做。 不用也可以,遍历两次的复杂度还是不变的。但是实际耗费的时间还是快慢指针更快。
class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode *slow, *fast;
slow = fast = head;
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
return fast->next ? slow->next : slow;
}
};
复杂度分析
思路:使用快慢指针
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; //slow每次比fast慢一步 } return slow; } } 时间复杂度:O(N) 空间复杂度:O(1)
被折磨了两天,发现还是简单题适合我
class Solution:
def middleNode(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
fast = head
slow = head
while fast.next and fast.next.next:
fast = fast.next.next
slow = slow.next
return slow.next if fast.next else slow
class Solution(object):
def middleNode(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
p=head
num=0
while p!=None:
num+=1
p=p.next
num/=2
while num>0:
head=head.next
num-=1
return head
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* middleNode(ListNode* head) {
auto fast = head;
auto slow = head;
while (fast != nullptr && fast->next != nullptr) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
};
LeetCode题目连接: 876. 链表的中间结点 https://leetcode-cn.com/problems/middle-of-the-linked-list/
快慢指针
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def middleNode(self, head: ListNode) -> ListNode:
fast = slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
return slow
复杂度分析
// 1-5
class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode * fast = head;
ListNode * low = head;
while (fast != NULL && fast->next != NULL) {
low = low->next;
fast = fast->next->next;
}
return low;
}
};
C++ Code:
/**
* 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) {
if (head == nullptr || head->next == nullptr) {
return head;
}
auto slow = head;
auto fast = head;
while (fast != nullptr && fast->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
};
复杂度分析
这个题要求是获取中间节点。获取链表的中间节点很容易就能想到两个方法,快慢指针和哈希表。
这个题不管哈希表还是快慢指针都很简单。
哈希表的做法是遍历一遍链表,遍历时将每个链表节点根据遍历的索引放入哈希表,之后直接判断总数是奇数还是偶数,并计算中间数,中间数直接忽略小数取整。
奇数就直接返回 中间数 - 1 位置的链表节点。偶数就返回 中间数 + 1 位置的链表节点。
哈希表的情况下时间和空间复杂度都是O( n )
快慢指针的做法是,设置两个指针。快指针一次走两步,慢指针一次走一步。
如果快指针正好两步两步的走到头,说明是奇数,则返回慢指针的节点。
如果快指针最后一次只走一步就到头了,说明是偶数,就返回慢指针的下一节点。
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/
function middleNode(head: ListNode | null): ListNode | null {
if (!head){
return null;
}
let lowerPoter: ListNode = head;
let fastPoter: ListNode = head;
while(fastPoter.next) {
fastPoter = fastPoter.next;
if (!fastPoter.next){
return lowerPoter.next;
}
fastPoter = fastPoter.next;
lowerPoter = lowerPoter.next;
}
return lowerPoter;
};
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode middleNode(ListNode head) {
if (head == null){
return null;
}
ListNode lowerPoter = head;
ListNode fastPoter = head;
while(fastPoter.next != null) {
fastPoter = fastPoter.next;
if (fastPoter.next == null){
return lowerPoter.next;
}
fastPoter = fastPoter.next;
lowerPoter = lowerPoter.next;
}
return lowerPoter;
}
}
时间复杂度:O( n )
空间复杂度:O( 1 )
思路 用两个指针记为快指针和慢指针, 快指针每次走 2 步, 慢指针每次走 1 步,当快指针走到末尾的时候,慢指针刚好到达链表中点。
class Solution: def middleNode(self, head: ListNode) -> ListNode: slow = fast = head while fast and fast.next: fast = fast.next.next slow = slow.next return slow
时间复杂度: O(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) {
if (head == nullptr || head->next == nullptr) {
return head;
}
auto slow = head;
auto fast = head;
while (fast != nullptr && fast->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
};
JavaScript Code:
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var middleNode = function(head) {
slow = fast = head;
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
};
复杂度分析
令 n 为数组长度。
class Solution: def middleNode(self, head: ListNode) -> ListNode: a=b=head
while a.next and a.next.next:
a=a.next.next
b=b.next
return b if not a.next else b.next
先获取链表的长度,然后折中一下就是中间位置,在从头遍历到中位数即可
class Solution {
public:
ListNode* middleNode(ListNode* head) {
int nodeSize = 0;
int minNum = 0;
ListNode* result = head;
// 找到节点的长度
while(head != nullptr){
++nodeSize;
head = head->next;
}
// 单数
minNum = nodeSize /2;
for(int i = 0; i < minNum; ++i){
result = result->next;
}
return result;
}
};
思路 双指针算法,快慢指针,快指针每次走慢指针的2倍,当快指针走完的时候慢指针便到了中点,若是奇数的话快指针指向的节点的下一个节点为空时慢指针指向的便是中点,若为偶数,快指针指向的节点为空,则慢指针指向的便是两个中间节点的第二个节点 代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode middleNode(ListNode head) {
ListNode slow = head, fast = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
}
复杂度 时间复杂度O(N) 空间复杂度O(1)
快慢指针
public ListNode middleNode(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while(fast.next != null && fast.next.next != null){
fast = fast.next.next;
slow = slow.next;
}
if(fast.next != null && fast.next.next == null) slow = slow.next;
return slow;
}
JavaScript Code:
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var middleNode = function (head) {
let slow = fast = head;
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next
}
return slow
};
const l1 = new ListNode(1);
const l2 = new ListNode(2);
const l3 = new ListNode(3);
const l4 = new ListNode(4);
const l5 = new ListNode(5);
const l6 = new ListNode(6);
l1.next = l2;
l2.next = l3;
l3.next = l4;
l4.next = l5;
l5.next = l6;
console.log(middleNode(l1))
复杂度分析
令 n 为数组长度。
遍历链表的长度 获取中间点
public static ListNode middleNode(ListNode head) {
int length=0;
ListNode res=head;
ListNode temp=head;
while (temp!=null){
++length;
temp=temp.next;
}
int mid= length / 2;
for(int i=0;i<mid;i++){
res=res.next;
}
return res;
}
复杂度分析 -时间复杂度:O(n) -空间复杂度:O(n)
class Solution {
public ListNode middleNode(ListNode head) {
if(head == null || head.next == null) return head;
ListNode slow = head; ListNode fast = head;
while(fast!=null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
}
class Solution { public: ListNode middleNode(ListNode head) { ListNode slow, fast; slow = fast = head;
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
return fast->next ? slow->next : slow;
}
};
class Solution:
def middleNode(self, head: ListNode) -> ListNode:
A = [head]
while A[-1].next:
A.append(A[-1].next)
return A[len(A) // 2]
C++ Code:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* middleNode(ListNode* head) {
if(!head->next)
return head;
ListNode* slow = head;
ListNode* fast = head->next;
while(fast->next&&fast->next->next)
{
fast = fast->next->next;
slow = slow->next;
}
return slow->next;
}
};
这是一道送分题,快慢双指针,无需多言
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var middleNode = function(head) {
let slow = head
let fast = head
while (fast && fast.next) {
slow = slow.next
fast = fast.next.next
}
return slow
};
时间O(n),空间O(1)
快慢指针法
class Solution:
def middleNode(self, head: ListNode) -> ListNode:
fast,slow=head,head
while fast and fast.next:
fast=fast.next.next
slow=slow.next
return slow
slow
和快指针 fast
head
fast
&& fast.next
快指针的下一个两个中有任何一个不存在了slow
慢指针就走到中点了const midleNode = head => {
let [slow, fast] = [head, head];
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
时间复杂度 O(n) // 需要走完整个链表 空间复杂度 O(1)
var middleNode = function (head) {
let slow = (fast = head);
while (slow && fast && fast.next) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
};
class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode *slow, *fast;
slow = fast = head;
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
return fast->next ? slow->next : slow;
}
};
Two pointers
Time: O(n), n = len of list
Space: O(1)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode middleNode(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
}
https://leetcode-cn.com/problems/middle-of-the-linked-list/
思路:快慢指针,慢指针走一步,快指针走两步,快指针走到末尾时,慢指针指向一半
class Solution {
public ListNode middleNode(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
}
复杂度:
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; } }
class Solution:
def middleNode(self, head: ListNode) -> ListNode:
fast = slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
return slow
复杂度
快慢指针找中间节点
class Solution {
public ListNode middleNode(ListNode head) {
ListNode slow, fast;
slow=fast=head;
while(fast.next!=null&&fast.next.next!=null){
fast=fast.next.next;
slow=slow.next;
}
if(fast.next==null){
return slow;
}else{
return slow.next;
}
}
}
时间复杂度:O(n) 空间复杂度:O(1)
快慢指针
class Solution {
public ListNode middleNode(ListNode head) {
ListNode p = head, q = head;
while (q != null && q.next != null) {
q = q.next.next;
p = p.next;
}
return p;
}
}
双指针 class Solution: def middleNode(self, head: ListNode) -> ListNode: fast = slow = head while fast and fast.next: slow = slow.next fast =fast.next.next
return slow
双指针
var middleNode = function(head) {
let A = [head];
while (A[A.length - 1].next != null)
A.push(A[A.length - 1].next);
return A[Math.trunc(A.length / 2)];
};
Fast and slow pointers
class Solution {
public ListNode middleNode(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
if (fast == null) {
return slow.next;
}
if (fast.next == null) {
return slow;
}
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
}
Space: O(1) Time: O(n)
''' class Solution: def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]: point1 = point2 = head while point2 and point2. next != None: point1 = point1.next point2 = point2.next.next
return point1
''' Time complexity O(n) Space complexity O(1)
class Solution:
def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:
fast = head
slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
return slow
class Solution {
public ListNode middleNode(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
if (fast == null) {
return slow.next;
}
if (fast.next == null) {
return slow;
}
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
}
var middleNode = function(head) { let fast = head; let slow = head; while (fast && fast.next ) { slow = slow.next; fast = fast.next.next; } return slow; };
快慢指针 代码
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var middleNode = function(head) {
if (!head || !head.next) return head;
let temp = {next: head};
let fast = temp.next.next;
let slow = temp.next;
while(fast && fast.next) {
fast = fast.next.next;
slow = slow.next;
}
if (fast) {
return slow.next;
} else {
return slow;
}
};
时间复杂度:O(N) 空间复杂度:O(1)
876. 链表的中间结点
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/middle-of-the-linked-list/
前置知识
暂无
题目描述