《剑指offer》刷题——【代码的鲁棒性】面试题22:链表中倒数第K个节点(java实现)
一、题目描述
输入一个链表,输出该链表中倒数第k个结点。
二、题目分析
方法一:两次遍历,O(n^2)
- 第一次遍历:统计出链表中节点的个数
- 第二次遍历:通过 n-k+1 ,找到倒数第k个节点
方法二:双指针,O(n)
- 双指针
- 第一个指针从链表的头指针开始遍历,向前走k-1 步,第二个指针保持不动
- 从第k步开始,第二个指针也开始从链表的头指针开始遍历
- 当第一个指针到达链表尾时,第二个指针刚好指向倒数第k个节点
- 特殊情况考虑:
- 链表为空
- 链表节点数小于k
- 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) {
//链表为空,或者k=0
if(head==null || k==0){
return null;
}
ListNode pre = head;//第一个指针
ListNode behind = null;//第二个指针
//遍历
for(int i=0; i<k-1; i++){
//当链表节点小于k,返回null,否则第一个指针向后走k-1步
if(pre.next != null){
pre = pre.next;
}
else{
return null;
}
}
behind = head; //第二个指针从头开始
//第k步开始,两个指针一起走,直到第一个指针到达链尾
while(pre.next != null){
pre = pre.next;
behind = behind.next;
}
return behind;//返回第二个指针
}
}
四、相关题目
链表的中间节点。如果链表中的节点总数为奇数,则返回中间节点;若节点总数是偶数,则返回中间两个节点的任意一个。
解决方案:
- 定义两个指针,同时从链表的头结点出发
- 快指针:一次走两步
- 慢指针:一次走一步
- 当走得快的指针走到链表的末尾时,走得慢的指针刚好在链表的中间