「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战」
前言
今天,我们来复习下前面的一些算法知识点,当然,题目是不一样的,略有不同,首先复习的是我们链表相关的题型。
题目描述
面试题 02.02. 返回倒数第 k 个节点
实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。
解题思路
题给示例:
我们有这样一个链表1->2->3->4->5,要返回倒数第2个节点的值,我们倒数第2个节点的值就是4;
遇到这种倒数链表的问题,我们可以采用双指针的方法来处理:
首先我们需要定义两个指针pre,cur,我们希望两个指针相差k位,这样,当cur走到null时,跟cur相差k的pre指向的节点,就是我们要求得的倒数第k个节点。
开始解题
var kthToLast = function(head, k) {
let ret = new ListNode(-1,head);
let pre = ret, cur = head; // 定义两个指针pre指向head前一位的虚头为初始位,cur指向head
while(--k) { // cur先走k-1步, 因为cur本身已经在第一位了
cur = cur.next;
}
while(cur) { // 让pre和cur同时走,cur为null时, 因为cur比pre先走k步,所以pre就是倒数第k个节点
cur = cur.next;
pre = pre.next;
}
return pre.val;
};
剑指 Offer 22. 链表中倒数第k个节点
这题与上题略有不同的是,它要输出该链表中倒数第k个节点,啥意思呢?看例子: 同样是有1->2->3->4->5的链表,返回倒数第2个节点结果为4->5,其实就是从倒数第k个节点到链表末尾;
解题思路
我们只需要在上题,第2个while循环中,让pre走到倒数第k-1个节点,返回出去就能得到我们的结果了,while的循环条件中我们让cur走到null的前一位即可。
开始解题
var getKthFromEnd = function(head, k) {
let ret = new ListNode(-1,head);
let pre = ret, cur = head; // 定义两个指针pre指向head前一位的虚头为初始位,cur指向head
while(--k) { // cur先走k-1步, 因为cur本身已经在第一位了
cur = cur.next;
}
while(cur.next) { // 让pre和cur同时走,cur为null前一位时, 因为cur比pre先走k步,所以pre就是倒数第k-1个节点
cur = cur.next;
pre = pre.next;
}
return pre.next;
};
为什么这两题我都用了虚头
我们要得到的是cur比pre多走k步,那如果cur刚好走了k步,pre是不是就该是head的前一位虚头了,我们需要保证k是小于等于链表的节点个数的,不然就没有意义了,如果刚好等于,那pre就是虚头,pre指向的就是我们倒数k个节点