码不停题:LeetCode 75-Day4【链表】
876. 链表的中间结点
❓题目描述
给定一个头结点为
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解析
解题的思路:首先需要找到中间节点的位置,那就必须获取到节点的长度
- 如果节点长度为偶数,则从中间节点位置开始遍历
- 如果节点长度为奇数,则从中间节点位置+ 1开始遍历
📝代码实现
class Solution {
public ListNode middleNode(ListNode head) {
int length = getNodeLength(head);
//长度为偶数
if(length % 2 == 0){
//遍历节点,从中间节点截取即可
for(int i = length / 2; i < length; i++){
head = head.next;
}
}
//若为奇数,则 length / 2 + 1
else
{
for(int i = length / 2 + 1; i < length; i++){
head = head.next;
}
}
return head;
}
/*
* 遍历节点 获取长度
*/
public int getNodeLength(ListNode head){
int length = 0;
while(null != head){
length++;
head = head.next;
}
return length;
}
}
📈复杂度分析
时间复杂度:O(n),其中 n 是链表的长度。需要遍历链表1.5次。
空间复杂度:O(1)
💡思路2解析
解题的思路:首先需要找到中间节点的位置,另一种思路就是快慢指针,快指针每次都比慢指针多遍历一次,当快指针遍历结束时,此时慢指针刚好到中间节点
📝代码实现
class Solution {
public ListNode middleNode(ListNode head) {
//初始化快慢指针,都从头结点开始
ListNode fast = head; ListNode slow = head;
//当快指针不为空,且下一节点不为空时
while(null != fast && null != fast.next){
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
}
📈复杂度分析
时间复杂度:O(n),其中 n 是链表的长度。需要遍历链表1次。
空间复杂度:O(1)
142. 环形链表 II
❓题目描述
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
👉题目示例
示例 1:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PYTcL2Nc-1657376558071)(🧡 LeetCodeImages/circularlinkedlist.png)]](https://img-blog.csdnimg.cn/4d5041cbb1b34d49bb4182338adf4347.png)
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AaOcNuDp-1657376558073)(🧡 LeetCodeImages/circularlinkedlist_test2-16573751940283.png)]](https://img-blog.csdnimg.cn/cd5f9d7e0a75441c86bcfb8223515a2e.png)
输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wb72pC9O-1657376558074)(🧡 LeetCodeImages/circularlinkedlist_test3-16573752092085.png)]](https://img-blog.csdnimg.cn/f7c701d34c4f427aa051cd19f4a639dc.png)
输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。
💡题目解析
💡思路解析
因是环行链表,每次遍历的时候记录遍历的节点,如若遇到重复的节点,则说明该节点是环形节点
📝代码实现
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode pos = head;
//set集合存储节点
Set<ListNode> visited = new HashSet<ListNode>();
while (pos != null) {
//如果包含,则说明该节点是环形节点
if (visited.contains(pos)) {
return pos;
} else {
visited.add(pos);
}
//重新赋值
pos = pos.next;
}
return null;
}
}
📈复杂度分析
时间复杂度:O(N),其中 N 为链表中节点的数目。我们恰好需要访问链表中的每一个节点。
空间复杂度:O(N),其中 N为链表中节点的数目。我们需要将链表中的每个节点都保存在哈希表当中。
浙公网安备 33010602011771号