输出单向链表中倒数第K个节点,好比咱们如今有int类型的1,2,3,4,5,6,7,8组成的一个单向链表,求倒数第三个元素。如图所示:java
咱们正常的思路就是从后往前推倒数第K个元素,这里有这样几个问题。首先是单向链表的限制,链表节点只有next指针指向下一个元素,因此咱们只能从前日后推;其次咱们须要知道最后一个元素后才能从后往前倒推,这里就只能经过next指针由前日后遍历,这是第一次循环,而后从后往前推又要开始遍历,这是第二次循环;另外若是从后往前推这也是个问题;或者说第一次循环时知道了单项链表长度,而后经过倒数第K个,咱们能推导出是正数第几个,这样再从前日后循环一次就能获取这个节点,可是这样仍是循环了两次。node
这里咱们只介绍目前了解到的最优的解决方案,其余方法就不一一介绍了。测试
咱们经过两个指针和一次循环就能获得想要的节点,步骤以下:this
咱们能够按上图中的链表来试算下。有 1,2,3,4,5,6,7,8这样顺序的一个单项链表,求倒数第3个节点。倒数第三个节点与最后一个节点的距离是3-1=2。先定义P1指针,从头节点移动2步,到达节点3的位置停下来,这时定义P2节点指向头节点,也就是节点1,而后P1和P2节点同时向后移动,当P1节点移动到最后一个节点8时,此时P1移动到了节点6处,而节点6就是倒数第3个节点,ok,节点6就是咱们要的节点。3d
代码实现:指针
public class SingleLinkedNode { //节点上存储的数据 private Object data; //该节点的下一个节点 private SingleLinkedNode next; public SingleLinkedNode(Object data){ this.data = data; } ...... }
public static SingleLinkedNode getReverseKPathNode(SingleLinkedNode head , int k){ //定义两个指针P1和P2,这里直接用节点表示 SingleLinkedNode P1 = head; SingleLinkedNode P2 = head; //P1移动到K-1位置停下来 for(int i=1;i<=k-1;i++){ P1=P1.getNext(); } //P1和P2同时向后移动,直到P1节点移动到最后一个节点 while(P1.getNext()!=null){ P1 = P1.getNext(); P2 = P2.getNext(); } //此时P2节点就是倒数第K个节点 return P2; }
测试:code
public static void main(String[] args){ SingleLinkedNode node1 = new SingleLinkedNode(1); SingleLinkedNode node2 = new SingleLinkedNode(2); SingleLinkedNode node3 = new SingleLinkedNode(3); SingleLinkedNode node4 = new SingleLinkedNode(4); SingleLinkedNode node5 = new SingleLinkedNode(5); SingleLinkedNode node6 = new SingleLinkedNode(6); SingleLinkedNode node7 = new SingleLinkedNode(7); SingleLinkedNode node8 = new SingleLinkedNode(8); node1.setNext(node2); node2.setNext(node3); node3.setNext(node4); node4.setNext(node5); node5.setNext(node6); node6.setNext(node7); node7.setNext(node8); System.out.println(getReverseKPathNode(node1,3).getData()); }
执行结果为:6,。正确blog