algorithm-base/animation-simulation/链表篇/面试题 02.03. 链表中间节点.md
2021-07-29 02:33:38 +00:00

152 lines
4.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

> 如果阅读时发现错误或者动画不可以显示的问题可以添加我微信好友 **[tan45du_one](https://raw.githubusercontent.com/tan45du/tan45du.github.io/master/个人微信.15egrcgqd94w.jpg)** ,备注 github + 题目 + 问题 向我反馈
>
> 感谢支持该仓库会一直维护希望对各位有一丢丢帮助
>
> 另外希望手机阅读的同学可以来我的 <u>[**公众号袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入。
#### [876. 链表的中间结点](https://leetcode-cn.com/problems/middle-of-the-linked-list/)
给定一个头结点为 head 的非空单链表返回链表的中间结点
如果有两个中间结点则返回第二个中间结点
**示例 1**
```java
输入[1,2,3,4,5]
输出3
```
> 说明因为只有一个中间节点
**示例 2**
```java
输入[1,2,3,4,5,6]
输出4
```
> 说明有两个中间节点所以返回后面那个
**题目解析**
又精心筛选了一个题目本来想写一下删除节点的题目然后发现这个题目更符合目前的节奏所以先写一下这个题目明天再给大家写删除节点的题目
大家先不要看我的题解先自己想一下怎么做这个这个题目是想让我们找出中间节点昨天的题目是让我们倒数第 K 个节点想一下这两个题目有什么联系呢
先说一下刚开始刷题的小伙伴可能会想到的题解两次遍历链表第一次遍历获取链表长度第二次遍历获取中间链表
这个方法很 OK利用数组先将所有链表元素存入数组里然后再直接获得中间节点这个也很 OK那么我们有没有一次遍历且不开辟辅助空间的方法呢
昨天的题目是一前一后双指针两个指针之间始终相差 k-1 我们今天也利用一下双指针的做法吧
这种类型的双指针是我们做链表的题目经常用到的叫做快慢指针
一个指针走的快一个指针走的慢这个题目我们可以让快指针一次走两步慢指针一次走一步当快指针到达链表尾部的时候慢指针不就到达中间节点了吗
链表中节点的个数有可能为奇数也有可能为偶数这是两种情况但是我们输出是相同的那就是输出 slow 指针指向的节点也就是两个中间节点的第二个
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210321131249789.gif)
**题目代码**
Java Code:
```java
class Solution {
public ListNode middleNode(ListNode head) {
ListNode fast = head;//快指针
ListNode slow = head;//慢指针
//循环条件,思考一下跳出循环的情况
while (fast!=null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
//返回slow指针指向的节点
return slow;
}
}
```
C++ Code:
```cpp
class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode * fast = head;//快指针
ListNode * slow = head;//慢指针
//循环条件,思考一下跳出循环的情况
while (fast != nullptr && fast->next != nullptr) {
fast = fast->next->next;
slow = slow->next;
}
//返回slow指针指向的节点
return slow;
}
};
```
JS Code:
```js
var middleNode = function (head) {
let fast = head; //快指针
let slow = head; //慢指针
//循环条件,思考一下跳出循环的情况
while (fast && fast.next) {
fast = fast.next.next;
slow = slow.next;
}
//返回slow指针指向的节点
return slow;
};
```
Python Code:
```python
class Solution:
def middleNode(self, head: ListNode) -> ListNode:
fast = head # 快指针
slow = head # 慢指针
# 循环条件思考一下跳出循环的情况
while fast is not None and fast.next is not None:
fast = fast.next.next
slow = slow.next
# 返回slow指针指向的节点
return slow
```
Swift Code
```swift
class Solution {
func middleNode(_ head: ListNode?) -> ListNode? {
var fast = head //快指针
var slow = head //慢指针
//循环条件,思考一下跳出循环的情况
while fast != nil && fast?.next != nil {
fast = fast?.next?.next
slow = slow?.next
}
//返回slow指针指向的节点
return slow
}
}
```
Go Code:
```go
func middleNode(head *ListNode) *ListNode {
// 快慢指针
fast, slow := head, head
for fast != nil && fast.Next != nil {
fast = fast.Next.Next
slow = slow.Next
}
return slow
}
```