前言:剑指offer刷题系列
问题:
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。
例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。
示例:
给定一个链表: 1->2->3->4->5, 和 k = 2.
返回链表 4->5.
思路:
这段代码定义了一个名为 getKthFromEnd 的函数,它接受两个参数:head 和k。head 是一个链表的头节点,k 是一个整数。
首先,代码创建了两个变量 a 和 b,并将它们都初始化为头节点。
接着,代码进入一个循环,循环次数为 k-1。在循环中,将 a 设置为 a.next。
然后,代码进入另一个循环,循环条件是 a 和 a.next 都不为 null。在循环中,将 b 设置为 b.next,将 a 设置为 a.next。
最后,返回 b。
这段代码的作用是找到链表中倒数第 k 个节点。它使用了双指针的方法,先让指针a 向前移动 k-1 步,然后同时移动指针a 和指针b,直到指针 a 到达链表尾部。此时指针 b 指向的就是倒数第 k 个节点。
基于上述思考,代码如下:
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var getKthFromEnd = function(head, k) {
let a=head,b = head
for(let i = 0;i < k-1;i++){
a = a.next
}
while(a && a.next){
b = b.next
a = a.next
}
return b
};
执行结果如下图:
修改后的代码,看起来更舒适:
var getKthFromEnd = function(head, k) {
let fast = head,slow = fast
while(k--){
fast = fast.next
}
while(fast){
fast = fast.next
slow = slow.next
}
return slow
};
python 版本
思路
就是使用快慢指针思想,让快指针先走k个节点,然后两个指针一起走,当快指针到链尾时,慢指针就是倒数第k个节点
代码如下
class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
first = head
last = head
while k:
first = first.next
k -= 1
while first:
first = first.next
last = last.next
return last
执行结果如下:
学到的知识点:
- 快慢指针是一种常用的算法技巧,它使用两个指针,一个快指针和一个慢指针,以不同的速度遍历数据结构(如链表或数组)。快慢指针常用于解决一些特定的问题,例如判断链表是否有环,寻找链表的中间节点,寻找链表的倒数第 k 个节点等。
- 快慢指针可以用来判断链表是否有环。具体方法是,使用两个指针,一个快指针和一个慢指针,同时从链表头节点开始遍历链表。快指针每次移动两步,慢指针每次移动一步。如果链表中存在环,那么快指针和慢指针最终会在环内相遇;如果链表中不存在环,那么快指针会先到达链表尾部。