22 链表中倒数第k个节点
为了实现只遍历一次就能找到倒数第
k
k
k个节点,我们可以定义两个指针。第一个指针从链表的头指针开始遍历向前走
k
−
1
k-1
k−1步,第二个指针保持不动;从第
k
k
k步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在
k
−
1
k-1
k−1,当第一个(走在前面的)指针到达链表的尾结点时,第二个(走在后面的)指针正好指向倒数第k个节点。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode l = head;
ListNode r = head;
int i=1;
while(r!=null & i<k){
r = r.next;
i++;
}
if(r==null){
//说明链表长度不够
return null;
}
while(r.next!=null){
l=l.next;
r=r.next;
}
return l;
}
}
时间复杂度
O
(
n
)
O(n)
O(n)。
空间复杂度
O
(
1
)
O(1)
O(1)。
当我们用一个指针遍历链表不能解决问题的时候,可以尝试使用两个指针来遍历链表。可以让其中一个指针遍历的速度快一些(比如一次在链表上走两步),或者让他先在链表上走若干步。
相关题目
求链表中间节点。如果链表中的节点总数为奇数,则返回中间节点;如果节点总数是偶数,则返回中间两个节点的任意一个。
为了解决这个问题,我们也可以定义两个指针,同时从链表的头结点出发,一个指针一次走一步,另一个指针一次走两步。当走的快的指针走到链表的末尾时,走的慢的指针正好在链表中间。