题目:
输入一个链表,输出该链表中倒数第k个结点。
分析:
如果是双向链表,可以遍历到最后一个,再通过prev指针找到倒数第k个。
如果是单向链表,访问倒数第k个,需要遍历n-k+1个结点,但是获取n的时候,需要遍历一遍链表,这不是最佳的解决方案。
为了实现只遍历链表一次就能找到倒数第k个结点,我们可以定义两个指针,第一个指针从链表的头指针开始遍历走k-1步,第二个指针保持不动,从第k步开始,第二个指针从链表头开始遍历,两个指针距离保持k-1,走在前面的指针到达链表的尾结点时,走在后面的指针正好指向倒数第k个结点。
需要注意的点:如果输入的k大于链表的总长度了,就不存在倒数第k个的问题了。如果输入的k<1,也是无意义的值。
解法:
package com.wsy;
class Node {
private int value;
private Node next;
public Node() {
}
public Node(int value, Node next) {
this.value = value;
this.next = next;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
public class Main {
public static void main(String[] args) {
int k = 6;
find(init(), k);
}
public static Node init() {
Node node7 = new Node(7, null);
Node node6 = new Node(6, node7);
Node node5 = new Node(5, node6);
Node node4 = new Node(4, node5);
Node node3 = new Node(3, node4);
Node node2 = new Node(2, node3);
Node node1 = new Node(1, node2);
return node1;
}
public static void find(Node head, int k) {
if (head == null || k < 1) {
System.out.println("error!");
return;
}
Node quick = head;
Node slow = head;
for (int i = 0; i < k - 1; i++) {
if (quick.getNext() != null) {
quick = quick.getNext();
} else {
System.out.println("error!");
return;
}
}
while (quick.getNext() != null) {
quick = quick.getNext();
slow = slow.getNext();
}
System.out.println(slow.getValue());
}
}