NO16:
输入一个链表,输出该链表中倒数第K个结点。
为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。
例如一个链表有6个结点,从头结点开始它们的值依次是1,2,3,4,5,6。
这个链表的倒数第3个结点是值为4的结点。
(注意代码健壮性,考虑输入空指针,链表结点总数少于k,输入的k参数为0)
下面的解法用了两个指针,只需遍历一次链表。
写一个链表类:
/**
* @author zhaonan
* 单向链表
*/
public class Node {
String data;
Node next;
public Node(String data) {
super();
this.data = data;
}
public Node(String data, Node next) {
super();
this.data = data;
this.next = next;
}
public void setData(String data) {
this.data = data;
}
public String getData() {
return data;
}
public void setNext(Node next) {
this.next = next;
}
public Node getNext() {
return next;
}
}
解题代码:
import com.company.base.Node;
public class NO16 {
public static void main(String[] args) {
Node node1 = new Node("1");
Node node2 = new Node("2");
Node node3 = new Node("3");
Node node4 = new Node("4");
Node node5 = new Node("5");
Node node6 = new Node("6");
node1.setNext(node2);
node2.setNext(node3);
node3.setNext(node4);
node4.setNext(node5);
node5.setNext(node6);
NO16A no16A = new NO16A();
System.out.println(no16A.findDataFromTail(node1, 3).getData());
}
}
class NO16A{
public Node findDataFromTail(Node head, int k){
if (head == null){
throw new RuntimeException("链表不能为空!");
}
if (k <= 0){
throw new RuntimeException("k值必须为正!");
}
int step = 0;
Node temp1 = head;
Node temp2 = head;
while (temp1.getNext() != null){
temp1 = temp1.getNext();
step++;
if (step >= k){
temp2 = temp2.getNext();
}
}
//节点数 == 步数 + 1
if (step + 1< k){
throw new RuntimeException("k值不能大于链表的长度!");
}
return temp2;
}
}
运行结果:
4
Process finished with exit code 0
举一反三:
当我们用一个指针遍历链表不能解决问题的时候,可以尝试用两个指针来便利链表。可以让其中一个指针遍历的速度快一些(比如一次在链表上走两步,或者让它先在链表上走若干步)。