1. 程式人生 > >LintCode 找到單鏈表倒數第n個節點

LintCode 找到單鏈表倒數第n個節點

給出連結串列 3->2->1->5->null和n = 2,返回倒數第二個節點的值1.

第一種方法:單鏈表只有頭指標,所以只能從頭部開始尋找,先遍歷一遍連結串列,確定連結串列中節點的個數k。然後從前往後第k-n+1個節點就是倒數第n個節點。一共遍歷2次連結串列

/**
 * Definition of ListNode
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *         this->val = val;
 *         this->next = NULL;
 *     }
 * }
 */
class Solution {
public:
    /**
     * @param head: The first node of linked list.
     * @param n: An integer.
     * @return: Nth to last node of a singly linked list. 
     */
    ListNode *nthToLast(ListNode *head, int n) {
        // write your code here
        ListNode* p;
        if ( head == NULL || n == 0 ) {
            return NULL;
        }
        p = head;
        int count = 0;
       while (p -> next != NULL) {
            p = p -> next;
            count++;
        }
        p = head;
        for ( int i = 0; i < count-n+1; i++) {
            p = p ->next;
        }
        return p;
    }
};


第二種方法:只遍歷一次連結串列。設定2個指標,當第一個指標從表頭向前走到第n-1個節點時,第二個指標開始從表頭出發。當第一個指標走到尾節點時,第二個指標的位置即為倒數第n個節點

class Solution {
public:
    /**
     * @param head: The first node of linked list.
     * @param n: An integer.
     * @return: Nth to last node of a singly linked list. 
     */
    ListNode *nthToLast(ListNode *head, int n) {
        // write your code here
        ListNode *p1 , *p2;
        // 邊界條件,如果連結串列為空,或者輸入的數字非正,返回空
        if ( head == NULL || n <= 0 ) {
            return NULL;
        }
        p1 = head;
        for ( int i = 0; i < n-1 ; i++ ) {
        // 第一個指標開始遍歷,保證輸入的n值小於連結串列的長度,否則返回空
            if ( p1 -> next != NULL ) {
                p1 = p1 -> next;
            } else {
                return NULL;
            }
        }
        p2 = head; // 第二個指標開始遍歷
        while ( p1 ->next != NULL ) {
            p1 = p1 ->next;
            p2 = p2 ->next;
        }
        return p2;
    }
};