剑指offer——链表中倒数第K个节点

题目一:输入一个链表,输出该链表中倒数第k个结点。

方法一:假设整个链表有n个节点,那么倒数第k个节点就是从头节点开始的第n-k+1个节点。第一次遍历统计出链表中节点的个数,第二次就能找到倒数第k个节点。

  /**
     *
     * 得到链表节点个数m
     * 注意的是不要使用head统计节点,因为链表指针移动过去了,还得移动回来
     */
    public ListNode FindKthToTail(ListNode head,int k) {
        if(head==null || k<=0)
        {
            return null;
        }
        int count=0;
        ListNode h=head;
        while(h!=null)
        {
            count++;
            h=h.next;

        }
        ListNode l=head;
        for(int i=0;i<count-k;i++)
        {
           l=l.next;
        }
        if(k>count)
        {
            return null;
        }else {
            return l;
        }
    }

方法二:只需要遍历链表一次。第一个指针从链表的头指针开始遍历向前走k-1步,第二个指针保持不动。从第k步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在k-1,当第一个指针到达尾节点时,第二个指针正好指向倒数第k个节点。

需要考虑下面三种情况:

  • 输入的链表节点的总个数小于k,由于第一个指针需要走k-1步,会由于空指针造成程序崩溃
  • 输入的参数k为0。由于k是一个无符号整数,在k-1中得到的将不是-1。因此,也会造成程序崩溃。
  • 输入的链表节点是个空指针,由于代码会试图访问空指针指向的内存,从而造成程序崩溃。

所以针对这三个问题,要分别进行处理:

 public ListNode FindKthToTail1(ListNode head,int k){
        if(head==null || k<=0)
        {
            return null;
        }
        ListNode l=head;
        ListNode r=head;
        for(int i=0;i<k-1;i++)
        {
           if(l.next==null)
           {
               return null;
           }
           l=l.next;
        }
        while(l.next!=null)
        {
            l=l.next;
            r=r.next;
        }
        return r;
    }

相关使用两个指针的题目:求链表的中间节点,如果链表中节点总数是奇数,则返回中间节点;如果节点总数是偶数,则返回中间两个节点中的任意一个。解法:定义两个指针,同时从链表的头结点出发,一个指针走一步,另一个指针一次走两步。当走的快的指针走到链表末尾是,走的慢的指针正好在链表中间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值