174. 删除链表中倒数第n个节点 (remove-nth-node-from-end-of-list)(c++)----lintcode面试题之链表

(一)题目要求:

给定一个链表,删除链表中倒数第n个节点,返回链表的头节点。

(二)示例:

给出链表1->2->3->4->5->null和 n = 2.

删除倒数第二个节点之后,这个链表将变成1->2->3->5->null.

(三)题解:

方法一:

/**
 * Definition of ListNode
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *         this->val = val;
 *         this->next = NULL;
 *     }
 * }
 */

//方法一
//(1)计算链表长度 len
//(2)删除倒数第n个结点,相当于删除正数第 len-n+1 个结点
//(3)结点指针后移(从1 移到 len-n+1  需移动 len-n 次)删除该结点

class Solution {
public:
    /*
     * @param head: The first node of linked list.
     * @param n: An integer
     * @return: The head of linked list.
     */
    ListNode * removeNthFromEnd(ListNode * head, int n) {
        // write your code here
        ListNode * p_current = head,*p_prev = head;
        int len = 0;
        //(1)计算链表长度 len
        while(p_current)
        {
          p_current = p_current->next;
          len++;
        }
        p_current = head;
        //(2)删除倒数第n个结点,相当于删除正数第 len-n+1 个结点
        if(n<=len && n>0)
        {
          //(3)结点指针后移(从1 移到 len-n+1  需移动 len-n 次)删除该结点
		  for(int i =0;i<len-n;i++)
          {
             p_prev = p_current;
             p_current = p_current->next;
          }
         //无头结点的链表,第一个结点都需要单独处理
          if(p_current == head)
           head = p_current->next;
          else
           p_prev->next = p_current->next;
           
          delete p_current;    
        }
        
        return head;
         
    }
};
方法二:两根指针的思想
//方法二:

class Solution {
public:
    /*
    题意:删除链表中倒数第n个结点,尽量只扫描一遍。
    使用两个指针扫描,当第一个指针扫描到第N个结点后,
    第二个指针从表头与第一个指针同时向后移动,
    当第一个指针指向空节点时,另一个指针就指向倒数第n个结点了
    */
    ListNode* removeNthFromEnd(ListNode* head, int n) {
		//此处引入虚拟头结点,是为方便处理n==len的情况
		//使其和处理其他情况的方法一致
        ListNode *res = new ListNode(0);
        res->next = head;
        ListNode *tmp = res;
        for (int i = 0; i < n; i++) {
            head = head->next;
        }
		//移动指针使tmp->next指向删除结点
        while (head != NULL) {
            head = head->next;
            tmp = tmp->next;
        }
		//此时tmp指向要删除结点的前一个结点
        tmp->next = tmp->next->next;
        return res->next;
    }
};

//也可将参数改为 n-1  和 head->next
class Solution {
public:
    /*
     * @param head: The first node of linked list.
     * @param n: An integer
     * @return: The head of linked list.
     */
    ListNode * removeNthFromEnd(ListNode * head, int n) {
        // write your code here
        ListNode *res = new ListNode(0);
        res->next = head;
        ListNode *tmp = res;
        for (int i = 0; i < n-1; i++) {
            head = head->next;
        }
        while (head->next != NULL) {
            head = head->next;
            tmp = tmp->next;
        }
        tmp->next = tmp->next->next;
        return res->next;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值