个人评价:链表中指针的基础操作,加入合理的双指针操作
题目难度:🌟 (参考 LeeCode 简单🌟 、中等🌟 🌟 、困难🌟 🌟 🌟 )
另,通常算法题会考察分析时间复杂度和空间复杂度,可参考笔者之前的文章
链表中倒数第k个节点
题目描述
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。
例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。
示例:
给定一个链表: 1->2->3->4->5, 和 k = 2.
返回链表 4->5.
解题思路
需要到达倒数 k 个数,显然需要遍历到达链表尾部,可想到使用双指针:快指针到达 null,慢指针比快指针少走 k 次。
- 快、慢指针初始为 head
- 快指针先走 k 次
- 快、慢指针一起走,直至快指针指向 null 停止;慢指针即为所需
Go 代码如下:
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func getKthFromEnd(head *ListNode, k int) *ListNode {
slow, fast := head, head
for ; k > 0; k-- {
fast = fast.Next
}
for fast != nil {
slow, fast = slow.Next, fast.Next
}
return slow
}
总结
相比数组,由于链表不存在下标,寻址通常会使用指针,且通常我们不希望增加额外的空间复杂度。因此,使用快慢指针在链表相关算法题中就比较常见了。
相对其他的数据结构,链表笔者认为是相当具有实用性的(很多源码实现基于链表),而且面试链表题,一定程度上可以看出面试者的基本功,尤其是指针的使用及操作。
链表的边界判断、空指针引用等也是需要注意的!
继续刷链表题鸭~ 就决定是你了=》下一篇 19.删除链表的倒数第 N 个结点
更多基础链表题:「数据结构&算法」必知必会系列:7. 常见数据结构——链表(下)