题目:输入一个链表,输出该链表中倒数第 k 个结点。为了符合大多数人的习惯,本题从1 开始计数,即链表的尾结点是倒数第1 个结点。例如一个链表有6个结点,从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是值为4的结点。
——来源于《剑指offer》
-
思路:使用两个指针,left和right都从链表的开头开始移动,right指针先移动到k-1的位置,然后left再和right一起移动,知道right移动到链表的尾部,left指向的位置就是倒数第k个结点
-
注意:
- 处理头结点为null的情况
- 处理当k等于0,或者大于链表长度的情况
-
代码实现:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
if (head == null || k <= 0) {
return null;
}
ListNode left = head;
ListNode right = head;
for (int i = 0; i < k - 1; i++) {
if (right.next != null) {
right = right.next;
} else {
return null;
}
}
while (right.next != null) {
left = left.next;
right = right.next;
}
return left;
}
}
相关题目:
- 求链表的中间结点。如果链表中结点总数为奇数,返回中间结点;如果结点总数是偶数,返回中间两个结点的任意一个。为了解决这个问题,我们也可以定义两个指针,同时从链表的头结点出发,一个指针一次走一步,另一个指针一次走两步。当走得快的指针走到链表的末尾时,走得慢的指针正好在链表的中间。
- 判断一个单向链表是否形成了环形结构。和前面的问题一样,定义两个指针,同时从链表的头结点出发,一个指针一次走一步,另一个指针一次走两步。如果走得快的指针追上了走得慢的指针,那么链表就是环形链表;如果走得快的指针走到了链表的末尾(m_pNext指向NULL)都没有追上第一个指针,那么链表就不是环形链表。