鏈表中倒數第k個節點

輸入一個鏈表,輸出該鏈表中倒數第k個結點。爲了符合大多數人的習慣,本題從1開始計數,即鏈表的尾結點是倒數第1個節點。例如一個鏈表有6個結點,從頭結點開始他們的值依次是1,2,3,4,5,6。這個鏈表的倒數第3個節點是值爲4的結點。
思路1:爲了得到倒數第k個節點,很自然的想法是先走到鏈表的尾端,再從尾端回溯K步。可是我們從鏈表結點的定義看出本題中的鏈表是單向鏈表,單向鏈表的節點只有從前往後的指針而沒有從後往前的指針,因此這種思路是行不通的。既然不能從尾結點開始遍歷這個鏈表,還是回頭頭結點上。假設整個鏈表有n個結點,那麼倒數第k個結點就是從頭開始的第n-k+1個結點。如果我們能夠得到鏈表中節點的個數n,那麼我們只要從頭節點開始往後走n-k+1步就可以了。如何得到節點數n,只需要從頭開始遍歷鏈表,每經過一個節點,計數器加1就行了。也就是我們需要遍歷鏈表兩次,第一次統計出鏈表中結點的個數,第二次就能找到倒數第k個結點。但是更好的方法是只需要遍歷鏈表一次。
思路2:爲了實現只遍歷鏈表一次就能找到倒數第K個節點,我們可以定義兩個指針。第一個指針從鏈表的頭指針開始遍歷向前走K-1,第二個指針保持不動。從第k步開始,第二個指針也開始從鏈表的頭指針開始遍歷。由於兩個指針的距離保持在k-1,當第一個(走在前面的)指針到達鏈表的尾結點時,第二個指針(走到後面的)指針正好是倒數第K個結點。
注意:需要考慮以下幾種情況,維持代碼的魯棒性。如果輸入的鏈表爲空,如果輸入的鏈表的結點數少於K個,如果輸入的參數k=0;三種情況都要考慮到,才能更魯棒性。
相關題目:①求鏈表的中間結點。如果鏈表中結點總數爲奇數,返回中間結點;如果結點總數爲偶數,返回中間兩個結點的任意一個。爲了解決這個問題,我們也可以定義兩個指針,同時從鏈表的頭結點出發,一個指針一次走一步,另一個指針一次走兩步。當走得快的指針走到鏈表的末尾時,走得慢的指針正好在鏈表的中間。
②判斷一個單向鏈表是否形成了環狀結構。和前面的問題一樣,定義兩個指針,同時從鏈表的頭結點出發,一個指針一次走一步,另一個指針一次走兩步。如果走得快的指針追上了走得慢的指針,那麼鏈表就是環形鏈表;如果走得快的指針走到了鏈表的末尾都沒有追上第一個指針,那麼鏈表就不是環形鏈表。
舉一反三:當我們用一個指針遍歷鏈表不能解決問題的時候,可以嘗試用兩個指針來遍歷鏈表。可以讓其中一個指針遍歷的速度快一些(比如一次在鏈表上走兩步),或者讓它現在鏈表上走若干步。

/*
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;} 
        ListNode node =head;
        for(int i=1;i<k;i++){
            if(head.next!=null){
                head=head.next;
            }else{
                return null;
            }
        }

        while(head.next!=null){
            head=head.next;
            node=node.next;
        }

        return node;
    }
}
發佈了64 篇原創文章 · 獲贊 1 · 訪問量 6738
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章