LintCode 找到单链表倒数第n个节点&删除倒数第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;
    }
};

 

 

给定一个链表,删除链表的倒数第 个节点,并且返回链表的头结点。(medium)

同样适用快慢指针的方法,但是要注意可能删除的是第一个节点


class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(head == NULL || n<=0) return NULL;

        ListNode *p1 = head;
        ListNode *p2 = head;
        for(int i=0; inext;
        }

        if(p2 == NULL) return head->next; //删除的是第一个节点
        while(p2->next != NULL){
            p1 = p1->next;
            p2 = p2->next;
        }
        p1->next = p1->next->next;
        return head;
    }
};

 

 

 

你可能感兴趣的:(算法刷题)