實現這個算法,能夠用遞歸和非遞歸。由於單向鏈表只能向後遍歷,因此通常會想到用遞歸這種方法,而後當遞歸遍歷到鏈表末端時,該方法會回傳一個置爲0的計數器。node
以後的每一次調用都會將這個計數器加1,當計數器等於K時,表示咱們訪問的是鏈表倒數第K個元素。算法
方法Athis
- public static int nToLast(LinkedListNode head,int k){
- if(head==null){
- return 0;
- }
- int i = nToLast(head.next,k)+1;//當遍歷到最後一個元素時,計數器i開始自增。
- if(i==k){
- System.out.println(head.data);
- }
- return i;
- }
可是這個方法只能打印倒數第K個值,不能返回該元素,由於咱們沒法用通常的返回語句回傳一個結點和一個計數器。指針
用一個簡單的類包裝計數器值,就能夠模仿按引用傳值。遞歸
- public class MyCount
- {
- public int value = 0;
- }
- LinkedListNode nToLast(LinkedListNode head,int k,MyCount i){
- LinkedListNode node = nToList(head.next,k,i);
- i.value = i.value+1;
- if(i.value == k){
- return head;
- }
- return node;
- }
迭代法,一個更直接的方法,咱們能夠使用兩個指針p1和p2,並將他們指向鏈表中相距k個結點的兩個結點,具體作法是將p1和p2指向鏈表首結點,而後將 p2向後移動k個結點,以後,咱們以相同的速度移動這兩個指針,p2會在移動length-k步後抵達鏈表末尾結點,這時,p1就指向鏈表倒數第k個結 點。ast
- LinkedListNode nToList(LinkedListNode head,int k){
- if(k<=0)
- return null;
- LinkedListNode p1 = head;
- LinkedListNode p2 = head;
-
- for(int i=0;i<k-1;i++){
- if(p2==null)
- return null;
- p2 = p2.next;
- }
- if(p2==null)
- return null;
- while(p2.next!=null){
- p1 = p1.next;
- p2 = p2.next;
- }
- return p1;
- }
或者class
- class Node{
- Node(int value, Node nnode){
- this.value=value;
- this.nnode=nnode;
- }
- }
- public static Node findknode(Node head, int k){
- if ((Null==head) || (Null==head.nnode))
- return head;
- cur=head;
- knode=head;
- nextnode=Null;
- count=0;
- while(cur!=Null){
- count+=1;
- if(count>=k){
- nextnode=knode.nnode;
- knode=nextnode;
- }
- nextnode=cur.nnode;
- cur=nextnode;
- }
- return knode;
- }