链表倒数第k个结点

本文介绍了一种高效算法,仅需遍历一次链表即可找到单链表中倒数第K个节点的方法,并附带了详细的思路解析及Java实现代码。

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

题目描述

输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。例如,一个链表有6个结点,从头结点开始他们的值依次是1、2、3、4、5、6,则倒数第3个结点是4。

链表结点定义如下:

/*
public class ListNode {
    int val;
    ListNode next = null;


    ListNode(int val) {
        this.val = val;
    }
}*/


思路分析

    为了得到倒数第k个结点,很自然的想法是先走到链表的尾端,再从尾端回溯k步,可是本题中的单链表的结点没有从后往前的指针,所以这种思路行不通。

    假设整个链表有n个结点,那么倒数第k个结点就是从头结点开始的第n-k+1个结点,如果我们可以得到链表中结点的个数n,那么我们只要从头结点往后走n-k+1步就可以了。得到结点个数仍需要遍历一遍链表。

    但是上述方法需要遍历链表两次,但是往往要求我们只能遍历一次链表,此时如何实现呢?

    为了实现只遍历一次链表,我们可以定义两个指针:第一个指针从链表的头指针开始遍历向前走k-1,第二个指针保持不动;从第k步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离始终保持在k-1,当第一个指针(走在前面的)到达链表尾结点时,第二个指针刚好指向倒数第k个结点。

    关于如何想到这个方法,可以逆向思考:倒数第k个结点与尾结点之间正好差k-1个结点,所以只要从最开始,让两个结点相差k-1个结点,然后在此基础上“同步前进”,当前面的指针到达尾结点时,后面的结点即到达指定位置。


注意    

        为保证代码的鲁棒性,有三个特殊情况需要注意:

        1.链表为空链表。2.k为0。  3.链表的结点总数大于n。


Java实现

public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        //特殊值处理,很重要!
        //考虑输入为空链表或者k为0,都为特殊情况,返回null
        if(head==null||k==0)
            return null;
        //先走的指针
        ListNode p1=head;
        //后走的指针
        ListNode p2=null;
        for(int i=1;i<=k-1;i++){
            //判断当输入的k是否大于实际链表中元素的个数          
            if(p1.next!=null)
                p1=p1.next;
            //如果在循环内部,p.next==null,则证明此时k是大于实际链表的元素个数的,返回空
            else
                return null;
        }
        //p1和p2之间始终相差k-1个元素,当p1指向尾结点时,p2指向的结点刚好为要查找的结点
        p2=head;
        while(p1.next!=null){
            p1=p1.next;
            p2=p2.next;
        }
          
        return p2;
  
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值