剑指offer java NO16

本文介绍了一种高效查找链表中倒数第K个结点的方法,使用双指针技术仅需遍历一次链表。通过具体实例展示了算法的实现过程,并提供了完整的Java代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

举一反三:
当我们用一个指针遍历链表不能解决问题的时候,可以尝试用两个指针来便利链表。可以让其中一个指针遍历的速度快一些(比如一次在链表上走两步,或者让它先在链表上走若干步)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值