第一种方法
看到这道题的第一想法便是先求一下链表的长度(size),然后再根据一些判断条件遍历链表走到相应的位置即可。
分析:我们要找倒数第k个节点,那么只需要走到size-k的位置即可。(可以简单的记为相加等于size)
如下图:我们可以将链表看成一个数组,我们要找倒数第2个节点,我们只需要走5-2=3步即可.
代码如下:
public class Solution {
public int getSize(ListNode head)
{
int count=0;
ListNode cur=head;
while(cur!=null)
{
count++;
cur=cur.next;
}
return count;
}
public ListNode FindKthToTail(ListNode head,int k) {
ListNode cur=head;
int size=getSize(head);
if(head==null)
{
return null;
}
if(k<=0||k>size)
{
return null;
}
for(int i=0;i<size-k;i++)
{
cur=cur.next;
}
return cur;
}
}
第二种方法
双指针法,这道题有点类似于之前的找中间节点的那道题,所以类比快慢指针也可以解决这道题。我们先定义两个引用fast和slow(都从头开始=dead),让fast先走k步,然后fast和slow一起走,最后当fast为空时,返回slow即可。
如下图:还是找倒数第2个节点,想让fast走2步,然后fast和
slow一起走。
开始
中间
尾部
代码如下:
public class Solution {
public int getSize(ListNode head){
ListNode cur=head;
int count=0;
while(cur!=null)
{
cur=cur.next;
count++;
}
return count;
}
public ListNode FindKthToTail(ListNode head,int k) {
int size=getSize(head);
if(head==null||k<=0||k>size)
{
return null;
}
ListNode fast=head;
ListNode slow=head;
for(int i=0;i<k;i++)
{
fast=fast.next;
}
while (fast!=null)
{
fast=fast.next;
slow=slow.next;
}
return slow;
}
}
改进:在使用第二种方法的时候我们可以不需要遍历链表长度也可以解决,我们只需要在for循环里加一个if判断即可(判断fast.next是否为null,如果为null返回即可)
代码如下:
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=0;i<k-1;i++)
{
if(fast.next==null)
{
return null;
}
fast=fast.next;
}
while(fast.next!=null)
{
fast=fast.next;
slow=slow.next;
}
return slow;
}
}