1. 程式人生 > >【劍指Offer學習】【面試題15 :連結串列中倒數第k個結點】

【劍指Offer學習】【面試題15 :連結串列中倒數第k個結點】

題目:輸入一個連結串列,輸出該連結串列中倒數第k 個結點.為了符合大多數人的習慣,本題從1 開始計數,即連結串列的尾結點是倒數第1 個結點.例如一個連結串列有6 個結點,從頭結點開始它們的值依次是1 、2、3、4、5 、6。這個個連結串列的倒數第3 個結點是值為4 的結點.

連結串列結點定義如下:

public static class ListNode {
    int value;
    ListNode next;
}

解題思路:

為了實現只遍歷連結串列一次就能找到倒數第k 個結點,我們可以定義兩
個指標。第一個指標從連結串列的頭指標開始遍歷向前走k-1步,第二個指標保持不動;從第k 步開始,第二個指標也開始從連結串列的頭指標開始遍歷。由於兩個指標的距離保持在k-1 , 當第一個(走在前面的)指標到達連結串列的尾結點時,第二個指標(走在後面的)指標正好是倒數第k 個結點。

程式碼實現:

public class Test15 {
    public static class ListNode {
        int value;
        ListNode next;
    }

    /**
     * 輸入一個鍵表,輸出該連結串列中倒數第k 個結點.為了符合大多數人的習慣,
     * 本題從1開始計數,即連結串列的尾結點是倒數第1個結點.例如一個連結串列有6個結點,
     * 從頭結點開始它們的值依次是1、2、3、4、5 6。這個連結串列的倒數第3個結點是值為4的結點.
     *
     * @param head 連結串列的頭結點
     * @param k    倒數第k個結點
     * @return 倒數第k個結點
     */
public static ListNode findKthToTail(ListNode head, int k) { // 輸入的連結串列不能為空,並且k大於0 if (k < 1 || head == null) { return null; } // 指向頭結點 ListNode pointer = head; // 倒數第k個結點與倒數第一個結點相隔k-1個位置 // pointer先走k-1個位置 for (int i = 1; i < k; i++) {
// 說明還有結點 if (pointer.next != null) { pointer = pointer.next; } // 已經沒有節點了,但是i還沒有到達k-1說明k太大,連結串列中沒有那麼多的元素 else { // 返回結果 return null; } } // pointer還沒有走到連結串列的末尾,那麼pointer和head一起走, // 當pointer走到最後一個結點即,pointer.next=null時,head就是倒數第k個結點 while (pointer.next != null) { head = head.next; pointer = pointer.next; } // 返回結果 return head; } public static void main(String[] args) { ListNode head = new ListNode(); head.value = 1; head.next = new ListNode(); head.next.value = 2; head.next.next = new ListNode(); head.next.next.value = 3; head.next.next.next = new ListNode(); head.next.next.next.value = 4; head.next.next.next.next = new ListNode(); head.next.next.next.next.value = 5; head.next.next.next.next.next = new ListNode(); head.next.next.next.next.next.value = 6; head.next.next.next.next.next.next = new ListNode(); head.next.next.next.next.next.next.value = 7; head.next.next.next.next.next.next.next = new ListNode(); head.next.next.next.next.next.next.next.value = 8; head.next.next.next.next.next.next.next.next = new ListNode(); head.next.next.next.next.next.next.next.next.value = 9; System.out.println(findKthToTail(head, 1).value); // 倒數第一個 System.out.println(findKthToTail(head, 5).value); // 中間的一個 System.out.println(findKthToTail(head, 9).value); // 倒數最後一個就是順數第一個 System.out.println(findKthToTail(head, 10)); } }

執行結果:
這裡寫圖片描述