剑指offer面试题22(java版):链表中倒数第K个节点

welcome to my blog

剑指offer面试题22(java版):链表中倒数第K个节点

题目描述

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

笔记

  • 要进行健壮性判断: 输入的节点为null; k<=0都是异常情况

复杂度

  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

第二次做

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

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        //倒数第零个节点,没有定义
        if(head==null || k==0) return null;
        /*
        如果链表长度达不到k该怎么检查出来?
        只能一个一个遍历,如果遍历的个数没有到k就遇到null了,则返回null
        所以判断条件是:遍历的个数与链表是否结尾
        */
        /*
        创建两个指针,fast和slow相隔k-1个节点,这样fast到达最后一个节点的话,
        slow位于倒数第k个节点
        
        注意:不要让fast到达null,这样的话fast和slow得相隔k个节点,
        由于slow和fast的起点是head,所以相隔k个节点的话需要链表中有k+1个节点
        这样判断的话就麻烦了,比如链表只有k个节点,检查长度时fast走到了null,
        此时不能返回null,需要配合k进行判断,就变麻烦了。
        所以一步到位,让fast和slow相隔k-1个节点,不满足就说明链表长度小于k,返回null
        */
        ListNode slow = head, fast = head;
        //先让fast往前走k-1步,确保链表中有k个节点
        //本题要牢记的细节:先移动再判断(逻辑问题;脑中过一遍)
        for(int i=0; i<k-1; i++){
            fast = fast.next;
            if(fast == null)
                return null;
        }
        //slow,fast一起走,直到fast走到最后一个节点
        while(fast.next != null){
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
}
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        // input check
        if(head == null || k<=0)
            return null;
        //execute 
        ListNode fast = head;
        ListNode slow = head;
        // 下面这个循环让fast位于第K个Node上; 非正常退出循环说明链表长度不足K
        for(int i = 0; i < k - 1; i++){ // 包括slow在内, 从slow到fast是K个节点; 所以fast得先向前移动K-1步
            if(fast.next == null)
                return null; // 链表长度不足K
            fast = fast.next;
        }
        while(fast.next != null){
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}

极其简洁的代码

先掌握上面那种方法, 感觉一般面试时主要是思维缜密性的体现

public ListNode FindKthToTail(ListNode head,int k) { 
        ListNode p, q;
        p = q = head;
        int i = 0;
        for (; p != null; i++) {
            if (i >= k)
                q = q.next;
            p = p.next;
        }
        return i < k ? null : q;
    }

你可能感兴趣的:(剑指offer,剑指offer)