算法学习-----输出链表的倒数第k个节点

本文介绍三种高效算法来查找链表中倒数第K个节点的方法,包括使用栈、双指针等技巧,并确保程序具备良好的鲁棒性。

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

假设链表有n个节点,那么倒数第k个节点,就是从头结点开始数到n-k+1个节点;所以自然就会两种思路:
1、如果可以遍历链表两次的话,第一次计数得到链表节点个数,第二次直接循环找到第n-k+1个节点返回就是。
2、如果链表只允许遍历一次的话,就必须使用两个指针(or引用):第一个指针从头开始走k-1步,第二个指针从头开始走,第一个到链表尾部,第二个指针的所指的就是倒数第k个节点
注意程序的(Robust)鲁棒性(这里鲁棒性是指:程序检查输入是否合乎规范,对于不合理的输入进行合理的处理)

/*
public class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}*/
//方法一
import java.util.*;
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        if(k<=0||head==null) return null;
        Stack<ListNode> stack = new Stack<ListNode>();// 建立栈结构
     while(head!=null){//入栈操作
            stack.push(head);
            head = head.next;
        }
        if(k>stack.size()) return null;
        ListNode count = head;
        for(int i=1;i<=k;i++){//出栈操作
            count = stack.pop();           
        }
         return count;
    }
}

//方法二:
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        if(head ==null||k<=0) return null;
        ListNode h1 = head;
        ListNode h2 = head;
        for(int i=1;i<k;i++){//i应该指向第k个时,因为最后一次i 也+1了,但是不满足条件跳出循环了,第一次循环结束,h1指向了第二个,第k-1此循环结束,h1指向第k个
            if (h1==null)return null;
            h1 = h1.next;
        }
        //由于循环条件判断的是h1,不是h1.next,循环到第k-1次结束时,h1指向第k个(如果第k个节点不存在的话只能循环到第k-2次,指向第k-1个节点)所以最后h1指向第k个节点是否存在需要如下验证
        if(h1==null)return null;//最后一次不满足条件跳出循环了,所以需要验证h1循环的最后一次是否为空;
        while(h1.next!=null){//h1到最后一个节点,h2就是倒数第k个节点
            h1 = h1.next;
            h2 = h2.next;
        }
        return h2;
     }
}
//方法三(跟上面的方法二几乎完全一样,除了循环条件之外)
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        if(head==null||k<=0)return null;
        ListNode p = head,q = head;
        for(int i=1;i<k;i++){
            if(p.next!=null) p = p.next;//如果p节点后面还有节点,p指向后续节点
            else return null; //否则的话,说明节点数少于k个,返回空
            }
        if(p.next==null)return q;//如果此时k恰好是最后一个节点返回头结点
        while(p.next!=null){//如果k不是最后一个节点,循环,判断p是否有后续节点
            p = p.next;
            q = q.next;
            }
       return q;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值