如何找出单链表中的倒数第K个元素--Java版

本文介绍使用Java实现获取单链表倒数第K个元素的三种方法:计算链表长度再定位、快慢指针技巧及栈辅助。每种方法详细解释,并附带代码示例。

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

Java语言实现单链表中的倒数第K个元素

单链表是一种常用的数据结构,它由一系列节点组成,每个节点包含一个数据域和一个指向下一个节点的指针。本文将介绍如何使用Java语言找出单链表中的倒数第K个元素,包括使用多种方法进行实现。

方法一:先计算链表长度,再遍历到倒数第K个节点

这种方法比较简单,我们可以先遍历一遍链表,计算出链表的长度,然后再从头节点开始遍历,直到遍历到倒数第K个节点为止。具体的实现步骤如下:

  1. 遍历一遍链表,计算出链表的长度len
  2. 如果len小于K,则直接返回null。
  3. 否则,从头节点开始遍历链表,遍历到第len-K+1个节点即可。

下面是使用Java语言实现该方法的代码:

public ListNode findKthToTail(ListNode head, int k) {
    if (head == null || k <= 0) {
        return null;
    }
    int len = 0;
    ListNode p = head;
    while (p != null) {
        len++;
        p = p.next;
    }
    if (len < k) {
        return null;
    }
    p = head;
    for (int i = 0; i < len - k; i++) {
        p = p.next;
    }
    return p;
}

其中,ListNode表示单链表的节点,包含一个数据域和一个指向下一个节点的指针。head表示链表的头节点,k表示要查找的倒数第K个元素的位置。

在实现中,我们首先判断链表是否为空或K是否小于等于0,如果是,则直接返回null。然后,我们遍历一遍链表,计算出链表的长度len。接着,如果len小于K,则直接返回null。否则,我们再从头节点开始遍历链表,遍历到第len-K+1个节点即可。最后,返回该节点即可。

方法二:使用快慢指针

这种方法比较巧妙,我们可以使用两个指针,分别指向链表的头节点和倒数第K个节点,然后将第一个指针向前移动K个位置,最后将两个指针同时向前移动,直到第一个指针到达链表的末尾。具体的实现步骤如下:

  1. 定义两个指针pq,初始时都指向链表的头节点。
  2. 将指针p向前移动K个位置,并检查指针p是否到达链表的末尾。如果没有到达末尾,继续执行步骤3;否则,直接返回null。
  3. 将指针pq同时向前移动,直到指针p到达链表的末尾。
  4. 此时,指针q指向的节点就是倒数第K个节点。

下面是使用Java语言实现该方法的代码:

public ListNode findKthToTail(ListNode head, int k) {
    if (head == null || k <= 0) {
        return null;
    }
    ListNode p = head;
    ListNode q = head;
    for (int i = 0; i < k - 1; i++) {
        if (p.next != null) {
            p = p.next;
        } else {
            return null;
        }
    }
    while (p.next != null) {
        p = p.next;
        q = q.next;
    }
    return q;
}

其中,ListNode表示单链表的节点,包含一个数据域和一个指向下一个节点的指针。head表示链表的头节点,k表示要查找的倒数第K个元素的位置。

在实现中,我们首先判断链表是否为空或K是否小于等于0,如果是,则直接返回null。然后,我们定义两个指针pq,初始时都指向链表的头节点。接着,我们将指针p向前移动K个位置,并检查指针p是否到达链表的末尾。如果没有到达末尾,我们将指针pq同时向前移动,直到指针p到达链表的末尾。最后,返回指针q所指向的节点即可。

方法三:使用栈

这种方法比较简单,我们可以使用栈来存储链表中的所有节点,然后从栈顶开始弹出K个节点即可。具体的实现步骤如下:

  1. 定义一个栈,用于存储链表中的所有节点。
  2. 遍历链表,将每个节点压入栈中。
  3. 从栈顶开始弹出K个节点,最后弹出的节点就是倒数第K个节点。

下面是使用Java语言实现该方法的代码:

public ListNode findKthToTail(ListNode head, int k) {
    if (head == null || k <= 0) {
        return null;
    }
    Stack<ListNode> stack = new Stack<>();
    ListNode p = head;
    while (p != null) {
        stack.push(p);
        p = p.next;
    }
    if (stack.size() < k) {
        return null;
    }
    ListNode node = null;
   while (k > 0) { 
   	   node = stack.pop(); 
   	   k--; 
   } 
   return node; 
   }

其中,ListNode表示单链表的节点,包含一个数据域和一个指向下一个节点的指针。head表示链表的头节点,k表示要查找的倒数第K个元素的位置。

在实现中,我们首先判断链表是否为空或K是否小于等于0,如果是,则直接返回null。然后,我们定义一个栈,用于存储链表中的所有节点。接着,我们遍历链表,将每个节点压入栈中。如果栈的大小小于K,则直接返回null。否则,我们从栈顶开始弹出K个节点,最后弹出的节点就是倒数第K个节点。最后,返回该节点即可。

三种方法的时间复杂度均为O(N),其中N为链表的长度。但是,方法二和方法三的空间复杂度都为O(N),而方法一的空间复杂度为O(1)。因此,如果空间复杂度比较敏感,可以选择方法一。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值