算法系列-力扣876-求链表的中间节点

求链表中间节点,如果有两个中间节点取后面那个

链表定义

```

// @lc code=start

/**

* 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; }

* }

*/

```

方法一:计数取一半

解题方法:

先计算链表一共有多少个节点n

n/2,得到中间节点的下标(从0开始)

1 -> 2 -> 3 -> 4 -> 5

坐标节点就是链表的中间节点

时间复杂度:O(n)

空间复杂度:O(1)

```

public ListNode middleNode(ListNode head) {

/**

* 先计算链表一共有多少个节点n

* n/2,得到中间节点的下标(从0开始)

* 1 -> 2 -> 3 -> 4 -> 5

* 坐标节点就是链表的中间节点

* */

int n=0;

ListNode p=head;

while (p!=null){

n++;

p=p.next;

}

int mid=n/2;

ListNode midNode=head;

for (int i = 0; i < mid; i++) {

midNode=midNode.next;

}

return midNode;

}

```

方法二:双指针

解题方法:

定义快慢两个指针,快指针每次移动2步,慢指针每次移动1步

注意:指针需要从头节点前开始移动,因此需要定义一个哑结点,快指针和慢指针都从哑节点开始

当快指针移动了2k步后,慢指针移动了k步

假设2k=n,k=n/2

当n为偶数时,慢指针的后续节点就是中间节点

当n为奇数时,慢指针就是中间节点

是否是偶数节点看快指针每次是否都能移动两步

时间复杂度:O(n)

空间复杂度:O(1)

```

public ListNode middleNode(ListNode head) {

/**

* 定义快慢两个指针,快指针每次移动2步,慢指针每次移动1步

* 注意:指针需要从头节点前开始移动,因此需要定义一个哑结点,快指针和慢指针都从哑节点开始

* 当快指针移动了2k步后,慢指针移动了k步

* 假设2k=n,k=n/2

* 当n为偶数时,慢指针的后续节点就是中间节点

* 当n为奇数时,慢指针就是中间节点

* 是否是偶数节点看快指针每次是否都能移动两步

* -1 -> 1 -> 2 -> 3 -> 4 -> 5 -> null

* -1 -> 1 -> 2 -> 3 -> 4 -> null

* */

if(head == null){

return null;

}

ListNode dummy = new ListNode(-1);

dummy.next=head;

ListNode slow=dummy;

ListNode fast=dummy;

ListNode midNode=null;

Boolean isEvent=true;

while (fast.next!=null){

slow=slow.next;

if(fast.next.next!=null) {

fast = fast.next.next;

} else{

fast=fast.next;

isEvent=false;

}

}

midNode = isEvent ? slow.next : slow;

return midNode;

}

```

方法三:双指针优化

解题方法:

定义快慢两个指针,快指针每次移动2步,慢指针每次移动1步

快指针和慢指针都从头节点开始移动

当快指针移动到链尾时,慢指针移动了k步,n>1

当n为偶数时,n-1必然是奇数

即快指针移动了2(k-1)+1步

此时快慢指针距离原点距离

快2(k-1)+1+1 简化 2k

慢k+1

即慢指针正好处于链表中间位置。

当n为奇数时,n-1必然是偶数

,快指针移动了2k步

此时快慢指针距离原点距离

2k+1

k+1

即慢指针正好处于链表中间位置

时间复杂度:O(n)

空间复杂度:O(1)

方法二的本质是下面的公式:

偶数

快2k

慢k

中间k+1

奇数

快2k-1

慢k

中间k

即快慢指针的初始位置+1就把公式统一了。

```

public ListNode middleNode(ListNode head) {

if(head == null){

return null;

}

ListNode slow=head;

ListNode fast=head;

while (fast!=null && fast.next!=null){

slow=slow.next;

fast = fast.next.next;

}

return slow;

}

```

相关推荐
Greedy Alg7 小时前
LeetCode 239. 滑动窗口最大值
数据结构·算法·leetcode
空白到白7 小时前
机器学习-KNN算法
人工智能·算法·机器学习
闪电麦坤958 小时前
数据结构:排序算法的评判标准(Criteria Used For Analysing Sorts)
数据结构·算法·排序算法
爱coding的橙子8 小时前
每日算法刷题Day65:8.27:leetcode dfs11道题,用时2h30min
算法·leetcode·深度优先
不懂机器人8 小时前
linux网络编程-----TCP服务端并发模型(epoll)
linux·网络·tcp/ip·算法
Mercury_Lc9 小时前
【链表 - LeetCode】25. K 个一组翻转链表
数据结构·leetcode·链表
地平线开发者9 小时前
理想汽车智驾方案介绍 3|MoE+Sparse Attention 高效结构解析
算法·自动驾驶
小O的算法实验室10 小时前
2025年KBS SCI1区TOP,矩阵差分进化算法+移动网络视觉覆盖无人机轨迹优化,深度解析+性能实测
算法·论文复现·智能算法改进
艾莉丝努力练剑11 小时前
【C语言16天强化训练】从基础入门到进阶:Day 11
c语言·学习·算法
浩少70213 小时前
LeetCode-22day:多维动态规划
算法·leetcode·动态规划