1. leetcode 876 链表的中间结点
1.1 题目描述
给定一个头结点为 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 和 100 之间。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/middle-of-the-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
1.2 代码实现
思路:快慢指针,慢指针每次走1步,快指针每次走2步,因为快指针的速度是慢指针速度的2倍,因此快指针走到末尾(这里的末尾是null或链表最后一个结点)时,慢指针刚好走到中间。
(情况2:返回第二个中间结点:快指针走到了null)
/**
* 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; }
* }
*/
class Solution {
public ListNode middleNode(ListNode head) {
ListNode slow = head;
ListNode fast = head;
//注意这里的条件,是与的关系
// fast == null,说明slow走到第二个中间结点
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
}
2. leetcode 19 删除链表的倒数第N个结点
2.1 题目描述
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
进阶:你能尝试使用一趟扫描实现吗?
示例 1:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
提示:
链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.2 代码实现
通过做题想到的:
(1)首先删除结点有2种情况,删除第一个结点和删除其他结点;
(2)想要通过一次遍历就能删除指定的倒数第N个结点,设置快慢指针,快指针在起点比慢指针多走了n-1步,当快指针到达链表最后一个结点,慢指针刚好到待删除的结点。
/**
* 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; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode slow = head;
ListNode fast = head;
ListNode preSlow = null;
//起点,fast比slow快n-1步
while(fast != null && n > 1){
fast = fast.next;
n--;
}
while(fast.next != null){
preSlow = slow;
slow = slow.next;
fast = fast.next;
}
//说明待删除结点就是head
if(preSlow == null){
head = head.next;
return head;
}
preSlow.next = slow.next;
return head;
}
}
时间:O(n).