3道链表力扣题
- 一、删除链表中的节点
-
- [🌏 题目链接](#🌏 题目链接)
- [📕 示例](#📕 示例)
- [🍀 分析](#🍀 分析)
- [💻 代码](#💻 代码)
- 二、反转链表
-
- [🌏 题目链接](#🌏 题目链接)
- [📕 示例](#📕 示例)
- [🍀 分析](#🍀 分析)
-
- [① 递归](#① 递归)
- [② 迭代](#② 迭代)
- 三、判断一个链表是否有环
-
- [🌏 题目链接](#🌏 题目链接)
- [📕 示例](#📕 示例)
- [🍀 分析](#🍀 分析)
- [💻 代码](#💻 代码)
一、删除链表中的节点
🌏 题目链接
【删除链表中的节点】https://leetcode.cn/problems/delete-node-in-a-linked-list/description/
📕 示例
🖊 输入:
head = [4, 5, 1, 9], node = 5
🖊 输出:
[4, 1, 9]
🖊 解释: 指定链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为
4 -> 1 -> 9
🖊 输入:
head = [4, 5, 1, 9], node = 1
🖊 输出:
[4, 5, 9]
🖊 解释: 指定链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为
4 -> 5 -> 9
🍀 分析
java
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
🖊 每一个节点就是一个
ListNode
对象🖊
val
属性存储了具体的数据🖊
next
属性存储了一个节点的内存地址
java
public class Solution {
public void deleteNode(ListNode node) {
}
}
🖊
deleteNode(ListNode node)
方法中,参数node 是要被"删除"的节点🖊 在该题中能够获得到的已知条件就只有这个要被删除的节点 node
🖊 已知: 要被删除的节点node
🖊 根据已知可以得到: ① 要被删除的节点往后的所有节点
node.next.next...
(这里就考虑它的下一个节点node.next
);② 可以得到节点的val
和node
🖊 这里的删除第三个节点,并不是把该节点从内存中移除,而是让第三个节点的值不再是【1】,而是它的下一个节点的值【9】。并且第三个节点的 next 存储它的下一个节点的 next
💻 代码
java
class Solution {
public void deleteNode(ListNode node) {
// 用被删除节点的下一个节点的值覆盖被删除节点的值
node.val = node.next.val;
// 被删除节点的next指向它下一个节点的next
node.next = node.next.next;
}
}
二、反转链表
🌏 题目链接
【206.反转链表】https://leetcode.cn/problems/reverse-linked-list/description/
📕 示例
🖊 输入:
head = [1, 2, 3, 4, 5]
🖊 输出:
[5, 4, 3, 2, 1]
🖊 输入:
head = [1, 2]
🖊 输出:
[2,1]
🖊 输入:head = []
🖊 输出:
[]
🍀 分析
java
class Solution {
public ListNode reverseList(ListNode head) {
}
}
🖊
reverseList(ListNode head)
方法只有一个参数 head(头指针),它指向了头节点
① 递归
👆 如上图所示,假如
reverseList
方法编写成功的话,reverseList(head)
方法调用后,该链表的头指针会指向方法调用之前的尾节点(如上图的newHead
)👆 原本的
head = [5, 4, 3, 2, 1]
也变成了head = [1, 2, 3, 4, 5]
🖊 假如
reverseList(head.next)
调用成功,则整个链表如上图所示
java
public class Solution {
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) return head;
// 递归
ListNode newHead = reverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
}
② 迭代
🖊 已知条件就只有一个头指针
head
,只能通过这个 head 进行反转
java
public class Solution {
/**
* 头插法(迭代)
*/
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode newHead = null;
do {
ListNode tmp = head.next;
head.next = newHead;
newHead = head;
head = tmp;
} while (head != null);
return newHead;
}
}
三、判断一个链表是否有环
🌏 题目链接
141.判断一个链表是否有环:https://leetcode.cn/problems/linked-list-cycle/description/
📕 示例
🍀 分析
🖊 使用快慢指针思想完成
🖊
fast
指针每次next
两步;slow
指针每次next
一步。若有环的话,快慢指针必然相遇🖊 如果
fast
指向 null 或fast.next
指向 null,则链表没有环
💻 代码
java
public class Solution {
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null) return false;
ListNode slow = head;
ListNode fast = head.next;
// 【fast == null || fast.next == null】都代表链表无环
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) return true;
}
return false;
}
}
🍀 完整代码