描述

输入一个长度为 n 的链表,设链表中的元素的值为 ai ,返回该链表中倒数第k个节点。

如果该链表长度小于k,请返回一个长度为 0 的链表。

  • 要求:空间复杂度 O(n),时间复杂度 O(n)
  • 进阶:空间复杂度 O(1),时间复杂度 O(n)

类似题目:删除链表的倒数第n个节点

思路1:列表存储,取出倒数第k个节点

使用列表存储每个节点,取出倒数第K个节点。空间复杂度O(n)

public class Solution {
    public ListNode FindKthToTail (ListNode pHead, int k) {
         if(pHead == null) {
             return null;
         }
         ArrayList<ListNode> list = new ArrayList<ListNode>();
         while(pHead != null) {
             list.add(pHead);
             pHead = pHead.next;
         }
         if(k > list.size() || k == 0){
             return null;
         }
         return list.get(list.size() - k);
    }
}

思路2:统计链表长度,再次遍历

遍历统计链表长度n,再走n-k步

public class Solution {
    public ListNode FindKthToTail (ListNode pHead, int k) {
        int n = 0;
        ListNode p = pHead;
        while(p != null) {
            n++;
            p = p.next;
        }
        p = pHead;
        while(p != null) {
            if(n == k){
                return p;
            }
            p = p.next;
            n--;
        }
        return null;
    }
}

思路3:递归

出栈的时候倒数

public class Solution {
    public ListNode FindKthToTail (ListNode pHead, int k) {
        i = k;
        recur(pHead);
        return ret;
    }
    ListNode ret;
    int i;
    void recur(ListNode node) {
        if(node == null) {
            return;
        }
        recur(node.next);
        i--;
        if(i == 0){
            ret = node;
            return;
        }
    }
}

思路4:快慢指针

假设链表长度为n,快指针先走k步,慢指针再开始,当快指针到达终点n时,慢指针走了n-k步,即倒数第k个节点

public class Solution {
    public ListNode FindKthToTail (ListNode pHead, int k) {
        ListNode fast = pHead;
        ListNode slow = pHead;
        for(int i = 0; i < k; i++){
            if(fast == null) {
                return null;
            }
            fast = fast.next;
        }
        while(fast != null) {
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}