题目
剑指 Offer 18. 删除链表的节点
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点。
示例:
输入: head = [4,5,1,9], val = 5 输出: [4,1,9] 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9. 复制代码
分析
链表问题首先考虑使用双指针
本题可以使用快慢指针的方式来求解
- 快指针查找符合要求的节点
- 慢指针保存上一个非目标节点
- 匹配到目标节点时让慢指针指向快指针的后一个节点即可完成删除操作(当目标节点在头部时,直接操作头节点)
- 最后返回头节点
实现
function deleteNode(head: ListNode | null, val: number): ListNode | null { let fast = head let slow = null while (fast) { if (fast.val === val) { if (slow) { slow.next = fast.next } else { head = fast.next } return head } slow = fast fast = fast.next } }; 复制代码
题目
剑指 Offer 22. 链表中倒数第k个节点
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。
例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。
示例:
给定一个链表: 1->2->3->4->5, 和 k = 2. 返回链表 4->5. 复制代码
分析
链表问题继续使用双指针分析求解
- 定义快慢指针
- 快指针先出发,慢指针等待 k 个位置出发
- 快指针遍历完时,慢指针所指的节点就是题目所求
实现一
function getKthFromEnd(head: ListNode | null, k: number): ListNode | null { let fast = head let slow = null let i = 1 while (fast) { if (i >= k) { slow = head head = head.next } if (fast.next) { fast = fast.next } else { return slow } i ++ } }; 复制代码
实现二
看了下别人的解法,这种解法更好理解些,顺便也记录下来
function getKthFromEnd(head: ListNode | null, k: number): ListNode | null { let fast = head let slow = head while (k > 0) { [fast, k] = [fast.next, k - 1 ] } while (fast) { [fast, slow] = [fast.next, slow.next] } return slow };