题目描述
输入一个链表,输出该链表中倒数第k个结点。
思路一
简单方法,找倒数第k个转换成正数第i-k个 i为链表长度
/*
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;
}
int i = 1;
ListNode temp = head;
while(temp.next!=null){
i++;
temp = temp.next;
}
if (i < k) return null;
//输出第i-k+1的值
temp = head;
for(int j = 0;j<i-k;j++){
temp =temp.next;
}
return temp;
}
}
时间复杂度:O(2*n),n为链表的总长度,如果k总是在倒数第一个节点,那么此方法需要遍历链表2次
空间复杂度:O(1)
思路二
严格的O(n)解法,快慢指针


我们从图中可以看出,倒数第k个节点与最后的空节点之间有2个指针,此时的2正好就是k,于是我们可以想到可以通过平移来到达最后的状态。
如图:

如果懂了上面的过程,接下来再说说具体编程要怎么写?

使用如图的快慢指针,首先让快指针先行k步,然后让快慢指针每次同行一步,直到快指针指向空节点,慢指针就是倒数第K个节点。
/*
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 fast = head;
ListNode slow =head;
for(int i = 1; i <k;i++){
if(fast.next!=null){
fast = fast.next;
}else{
return null;
}
}
while(fast.next!=null){
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
时间复杂度:O(n),不管如何,都只遍历一次单链表
空间复杂度:O(1)
本文介绍两种高效算法来找到链表中的倒数第K个节点,包括使用链表长度计算的方法及快慢指针技巧,并分析了它们的时间和空间复杂度。
1983

被折叠的 条评论
为什么被折叠?



