LeetCode-19

Posted zpchya

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode-19相关的知识,希望对你有一定的参考价值。

2019/04/03

方法一:遍历两次链表,第一次遍历得到链表的长度,第二次遍历找到倒数第n个节点并删除它。

时间复杂度为O(6n),空间复杂度为O(1)

 

方法二:遍历一遍链表,遍历链表的同时将各节点地址放入容器中,遍历结束后通过容器下表删除倒数第n个节点。

时间复杂度为O(4n),空间复杂度为O(n)

ListNode* removeNthFromEnd(ListNode* head, int n) {
    vector<ListNode*> nodeVector;    //创建一个节点容器
    ListNode* pWorkNode = head;
    int i = 0;    //链表长度
        
    while (pWorkNode)    //遍历链表
    {
        nodeVector.push_back(pWorkNode);    //将各个节点放入容器中
        pWorkNode = pWorkNode->next;
        ++i;
    }
        
    int j = i + 1 - n;    //待删除节点序号
    if (1 == j)    //如果删除的是第一个节点
    {
        pWorkNode = head->next;
        delete head;
        head = pWorkNode;
    }
    else
    {
        nodeVector[j - 2]->next = nodeVector[j - 1]->next;
        delete nodeVector[j - 1];
    }
        
    return head;
}

    这个算法实现非常差,时间复杂度并没有比遍历两边链表低多少,空间复杂度却变大很多。想的时候只记得降低遍历次数,没有更深的去想怎么降低遍历次数的同时使得空间复杂度仍是O(1)。

 

方法三:这个算法是看了别人才反应过来的,关键就在于怎么在依次遍历中确定这个节点顺序排在第几位。

时间复杂度为O(2n), 空间复杂度为O(1)

ListNode* removeNthFromEnd(ListNode* head, int n) {
    ListNode* pFirstNode = new ListNode(0);    //为了统一删除节点的操作
    pFirstNode->next = head;
    ListNode* pWorkNode1 = head;    //确定待删除节点的顺序位置
    ListNode* pWorkNode2 = pFirstNode;     //遍历到待删除节点

    while(n--)
        pWorkNode1 = pWorkNode1->next;
    while(pWorkNode1)    //遍历到待删除节点的前一个节点
    {
        pWorkNode1 = pWorkNode1->next;
        pWorkNode2 = pWorkNode2->next;
    }
    pWorkNode1 = pWorkNode2->next;
    pWorkNode2->next = pWorkNode1->next;
    delete pWorkNode1;

    return pFirstNode->next;  
}

总结:做题的时候就要多想,并不是说怎么把它实现了,而是怎么把它实现的更好,实现了有没有更好的方法,要多想!

 

以上是关于LeetCode-19的主要内容,如果未能解决你的问题,请参考以下文章

leetcode-----19. 删除链表的倒数第N个节点

LeetCode 19. 删除链表的倒数第N个节点

LeetCode(19) - Remove Nth Node From End of List

LeetCode - 19 - 删除链表的倒数第N个节点 - Java

LeetCode 19 - 删除链表的倒数第N个节点 - [链表]

LeetCode 19. 删除链表的倒数第 N 个结点