zoukankan      html  css  js  c++  java
  • (剑指Offer)面试题13:在O(1)时间内删除链表结点

    题目:

    在给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间内删除该结点。链表结点与函数的定义如下:

    struct ListNode{
    int val;
    ListNode* next;
    };
    
    void deleteNode(ListNode** pListHead,ListNode* pToBeDeleted)
    

    思路:

    删除链表结点的一般思路是:从头指针开始遍历,找到要删除结点的前一结点pPrev,然后pPrev->next=pToBeDeleted->next,(还需考虑删除结点是否为头结点),这样的时间复杂度为O(n)。

    而题目要求为O(1),找到删除结点的前一结点复杂度为O(n),但找到后一结点的复杂度为O(1),如果我们把后一结点的东西拷贝到要删除结点上,再把后一结点删除,岂不就是相当于把当前需要删除的结点删除了?

    ListNode* pNext=pToBeDeleted->next;
    pToBeDeleted->val=pNext->val;
    pToBeDeleted->next=pNext->next;
    delete pNext;
    pNext=NULL;

    考虑特殊情况,如果要删除的结点为头结点和尾结点怎么办?

    头结点:要删除的结点为头结点,删除之后,链表为空,此时需要将头结点置为NULL,这时候改变的头指针的内存地址,因此需要传递二级指针,*pHead=NULL;

    尾结点:要删除的结点为尾结点,尾结点没有后一结点,因此,不能通过上述方法来解决,还要回到传统的遍历方法,找到它的前一结点,然后将它的下一结点置为NULL,同时删除尾指针。

    代码:

    struct ListNode{
    int val;
    ListNode* next;
    };
    
    void deleteNode(ListNode** pListHead,ListNode* pToBeDeleted){
        if(pListHead==NULL || pToBeDeleted==NULL)
            return;
        if(pToBeDeleted->next!=NULL){
            ListNode* pNext=pToBeDeleted->next;
            pToBeDeleted->val=pNext->val;
            pToBeDeleted->next=pNext->next;
            delete pNext;
            pNext=NULL;
        }
        else if(*pListHead==pToBeDeleted){
            delete pToBeDeleted;
            pToBeDeleted=NULL;
            *pListHead=NULL;
        }
        else{
            ListNode* pNode=*pListHead;
            while(pNode->next!=pToBeDeleted)
                pNode=pNode->next;
            pNode->next=NULL;
            delete pToBeDeleted;
            pToBeDeleted=NULL;
        }
    }
  • 相关阅读:
    light oj 1105 规律
    light oj 1071 dp(吃金币升级版)
    light oj 1084 线性dp
    light oj 1079 01背包
    light oj 1068 数位dp
    light oj 1219 树上贪心
    light oj 1057 状压dp TSP
    light oj 1037 状压dp
    矩阵快速幂3 k*n铺方格
    矩阵快速幂2 3*n铺方格
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4643070.html
Copyright © 2011-2022 走看看