剑指offer-13:在O(1)时间删除链表结点

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

4月份找实习时滴滴视频面,就是出的这道题目,当时舍友提示说覆盖即可。

分析:

  • 一般的单链表中删除节点,遍历该链表,发现下一个是待删点,则删除。从头查找复杂度是O(n),因为我们需要找到待删点的前一个点。
  • 题目给定该结点的指针,要删除该结点,直接删则链表就断了。
  • 链表利用指针连接起来,非常灵活。可以把待删节点的下一个节点复制给待删点,然后删掉后面的点。就可以达到题目要求的结果。

注意:

  • 此题思路清晰,需要关注几个边界情况。如待删点为尾结点时,则必须从头开始遍历得到次尾结点。
  • 如果链表中只有一个结点,删除该结点,则需要把头指针置空。
  • 其余则属于正常情况的删除即可。

代码:

// offer-13-O(1)ListDelete.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>

using namespace std;

// 链表结点定义
struct ListNode{
    int value;
    ListNode * pnext;
};

// 删除某给定的结点
void DeleteNode(ListNode ** pListHead, ListNode * pToBedelete)
{
    // 指针判断
    if(!pListHead || !pToBedelete)
        return;

    // 如果不是尾结点,属于正常中间的某结点
    if(pToBedelete->pnext != nullptr)
    {
        ListNode * ptmp = pToBedelete->pnext;
        pToBedelete->value = ptmp->value;
        pToBedelete->pnext = ptmp->pnext;

        delete ptmp;
        ptmp = nullptr;
    }

    // 如果是尾结点,判断是不是只有一个结点
    else if(*pListHead == pToBedelete)
    {
        delete pToBedelete;
        pToBedelete = nullptr;
        *pListHead = nullptr;
    }

    // 如果是尾结点且链表有多个结点,需从头遍历
    else
    {
        ListNode * ptmp = *pListHead;
        while(ptmp->pnext != pToBedelete)
        {
            ptmp = ptmp->pnext;
        }
        ptmp->pnext = nullptr;
        delete pToBedelete;
        pToBedelete = nullptr;
    }
}


int _tmain(int argc, _TCHAR* argv[])
{

    return 0;
}

对于n-1个非尾结点而言,可以在O(1)时间把下一个结点的内存复制到需要删除的结点,并删除下一个结点;

对于尾结点而言,仍然需要顺序查找,时间复杂度是O(n)。总的平均时间复杂度是 [(n1)O(1)+O(n)]/n=O(1) ,符合要求。

但是它还基于一个假设:要删除的结点的确在链表中。我们需要O(n)的时间才可以判断链表中是否包含某个结点,因此确保工作交给了函数的调用者。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值