/**
* 功能:找出单向链表中倒数第k个节点。
*/
三种方法:
1、方法一:
3、方法三:
/*递归访问整个链表,当到达链表末端是,方法传回一个置为0的计数器,之后的每次调用都会将这个计数器加1.
当计数器=k时,得到倒数第k个元素。*/
//不返回该元素:只打印倒数第k个结点的值,直接通过返回值传回计数器值。
public static int nthToLast(LinkedListNode head, int k){
if( head== null)
return 0;
int i= nthToLast(head.next,k)+1;
if( i== k)
System. out.println( head. data);
return i;
}
2、
方法二:
//创建包裹类:用一个简单的类(或一个单元素数组)包裹计数器的值,就可以模仿引用传递。
public static LinkedListNode nthToLast2(LinkedListNode head, int k,IntWrapper i){
if( head== null)
return null;
LinkedListNode node= nthToLast2(head.next,k,i);
i. value++;
if( i. value== k){
return head;
}
return node;
}
/*
* 内部类是动态的,也就是开头以public class开头。而主程序是public static class main。
* 在Java中,类中的静态方法不能直接调用动态方法。只有将某个内部类修饰为静态类,然后才能够在静态类中调用该类的成员变量与成员方法。
* 所以在不做其他变动的情况下,最简单的解决办法是将public class改为public static class。
*/
public static class IntWrapper{
public int value=0;
}
3、方法三:
/**
* 使用两个指针p1和p2,将它们指向链表中相距K个节点的两个节点。
* 具体做法:首先均指向首节点,将p1向前移动k个节点。然后以相同速度移动,当p1指向末端空节点时,p2
* 即为倒数第k个节点。
* @param head
* @param k
* @return
*/
public static LinkedListNode nthToLast3(LinkedListNode head, int k){
if( head== null)
return null;
LinkedListNode p1= head;
LinkedListNode p2= head;
for( int i=0; i< k; i++){
if( p1== null) //移动前,检查是否为空
return null;
p1= p1. next;
}
if( p1== null) //移动后,当p1指向第k个元素时,检查是否为空
return null;
while( p1!= null){
p1= p1. next;
p2= p2. next;
}
return p2;
}