算法系列-力扣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;

}

```

相关推荐
数模竞赛Paid answer19 小时前
2025年MathorCup数学建模A题汽车风阻预测解题文档与程序
算法·数学建模·mathorcup
Old Uncle Tom1 天前
OpenClaw 记忆系统 -- 记忆预加载
java·数据结构·算法·agent
会编程的土豆1 天前
洛谷题单入门1 顺序结构
数据结构·算法·golang
生信碱移1 天前
PACells:这个方法可以鉴定疾病/预后相关的重要细胞亚群,作者提供的代码流程可以学习起来了,甚至兼容转录组与 ATAC 两种数据类型!
人工智能·学习·算法·机器学习·数据挖掘·数据分析·r语言
智者知已应修善业1 天前
【51单片机中的打飞机设计】2023-8-25
c++·经验分享·笔记·算法·51单片机
智者知已应修善业1 天前
【51单片机按键调节占空比3位数码管显示】2023-8-24
c++·经验分享·笔记·算法·51单片机
JasmineX-11 天前
数据结构(笔记)——双向链表
c语言·数据结构·笔记·链表
.5481 天前
## Sorting(排序算法)
python·算法·排序算法
wuweijianlove1 天前
算法的平均复杂度建模与性能回归分析的技术7
算法·数据挖掘·回归
子琦啊1 天前
【算法复习】字符串 | 两个底层直觉,吃透高频题
linux·运维·算法