题目描述:题目描述在O(1)时间删除链表结点

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

考查创新编程能力。

思路:

1.如果从头到尾遍历,时间O(n)

2.如果将待删除节点的下一个节点j复制到待删除节点i上,然后将i的下一个节点指向j的下一个节点,删除j的节点。

3.对于尾节点,需要从头开始遍历

4.对于只有一个节点的链表,要将*HeadNode设置为Nullptr.

5.时间复杂度

n-1个非尾节点,时间O(1)

1个尾节点,时间O(n)

最终((n-1)*O(1)+O(n))/n=O(1)符合题目要求

注意:

1.每次删除完节点后,要释放节点,即将节点的指针设为nullptr。

2.n-1个非尾节点,删除的是待删除节点的下一个pNext,而不是本身的节点。

3.最后一个尾节点,用while遍历,pNode指针向后指,找到最后一个节点,删除后,将pNode->Next设为nullptr。

  1. //已知该节点存在链表中
  2. void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted)
  3. {
  4. //1.如果链表头节点或待删除节点为空,返回
  5. if (!pListHead || !pToBeDeleted)
  6. return;
  7. //2.多个节点的链表,前n-1个非尾节点
  8. if (pToBeDeleted->m_pNext)
  9. {
  10. //2.1 pNext:待删除节点J的下个节点K
  11. ListNode* pNext = pToBeDeleted->m_pNext;
  12. //2.2 复制值J=K
  13. pToBeDeleted->m_nValue = pNext->m_nValue;
  14. //2.3 复制指针J->NEXT=K->NEXT
  15. pToBeDeleted->m_pNext = pNext->m_pNext;
  16. //2.4 删去下个节点K(pNext)
  17. delete pNext;
  18. //2.5 pNext设为空指针
  19. pNext = nullptr;
  20. }
  21. //3.只有一个节点的链表,删完要将头节点指针设为空
  22. else if(*pListHead==pToBeDeleted)
  23. {
  24. //3.1删除节点
  25. delete pToBeDeleted;
  26. //3.2 释放删除节点的指针
  27. pToBeDeleted = nullptr;
  28. //3.3 删除后将头节点设为空指针
  29. *pListHead = nullptr;
  30. }
  31. //4.如果是最后一个尾节点,就用遍历
  32. else
  33. {
  34. //4.1 pNode:遍历指针,从头开始
  35. ListNode* pNode = *pListHead;
  36. //4.2 while遍历找到pNode的下一个节点是要删除的节点
  37. while(pNode->m_pNext == pToBeDeleted)
  38. {
  39. //4.2.1 指针向后指
  40. pNode = pNode->m_pNext;
  41. }
  42. //4.3 将pNode的下一个节点设为空
  43. pNode->m_pNext = nullptr;
  44. //4.4 删除最后的节点
  45. delete pToBeDeleted;
  46. //4.5 释放指针
  47. pToBeDeleted = nullptr;
  48. }
  49. }

题目描述

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

思路:

1.确定函数的参数,头节点也可能被删除,所以函数声明应该为

void deleteDuplication(ListNode** pHead);

2.从头到尾遍历链表,确保pPreNode始终和下一个没有重复的节点连在一起。

  1. //函数的参数:ListNode** pHead。
  2. //因为头节点可能重复,会被删除,所以不用ListNode* pHead
  3. void DeleteDuplication(ListNode** pHead)
  4. {
  5. //1.如果是空链表或头节点为空,返回
  6. if (!pHead || !*pHead)
  7. return;
  8. //2.ListNode* pNode:初始化指向当前头节点*pHead
  9. ListNode* pNode = *pHead;
  10. //3.ListNode* pPreNode:指向上个节点,初始化为空
  11. ListNode* pPreNode = nullptr;
  12. //4.循环遍历
  13. while (pNode)
  14. {
  15. //4.1.新建一个节点pNext,指向下个节点
  16. ListNode* pNext = pNode->m_pNext;
  17. //4.2 设置标记:pNode节点是否需要删除
  18. bool needDetele = false;
  19. //4.3 如果下个节点pNext不为空,且pNode节点值和下个节点pNext的值相同,pNode节点就需要删除
  20. if (pNext!=nullptr && pNext->m_nValue == pNode->m_nValue)
  21. needDetele = true;
  22. //4.4 如果不需要删除,就遍历下一个
  23. if (!needDetele)
  24. {
  25. //4.4.1 上个节点pPreNode设为当前节点pNode
  26. pPreNode = pNode;
  27. //4.4.2 当前节点pNode设为下个节点pNext
  28. pNode = pNext;
  29. /* pNode->m_nValue = pNext->m_nValue;
  30. pNode->m_pNext = pNext->m_pNext;*/
  31. }
  32. //4.5 否则,开始删除
  33. else
  34. {
  35. //4.5.1 记录pNode值
  36. int value = pNode->m_nValue;
  37. //4.5.2 定义要删除的节点变量toBeDeleted,初始化为该节点
  38. ListNode* toBeDeleted = pNode;
  39. //4.5.3 循环遍历:如果toBeDeleted节点不为空,且等于下一个节点,就将toBeDeleted删除,
  40. while (toBeDeleted&&value == toBeDeleted->m_nValue)
  41. {
  42. //4.5.3.1 pNext指向toBeDeleted下个节点
  43. pNext = toBeDeleted->m_pNext;
  44. //4.5.3.2 删除toBeDeleted节点
  45. delete toBeDeleted;
  46. toBeDeleted = nullptr;
  47. //4.5.3.3 toBeDeleted节点赋值为下个节点pNext
  48. toBeDeleted = pNext;
  49. }
  50. //4.5.4 如果删除的是头节点,即pPreNode为空,将头节点改为下个节点
  51. if (!pPreNode)
  52. *pHead = pNext;
  53. //4.5.5 否则,将pPreNode的下个节点设置为下个节点pNext
  54. else
  55. pPreNode->m_pNext = pNext;
  56. //4.5.6 当前节点pNode设为下个节点pNext
  57. pNode = pNext;
  58. }
  59. }
  60. }

第二遍

  1. /*
  2. struct ListNode {
  3. int val;
  4. struct ListNode *next;
  5. ListNode(int x) :
  6. val(x), next(NULL) {
  7. }
  8. };
  9. */
  10. class Solution {
  11. public:
  12. ListNode* deleteDuplication(ListNode* pHead)
  13. {
  14. //1.如果链表为空或者头节点为空,返回nullptr
  15. if(!pHead)
  16. return nullptr;
  17. //2.pPreNode指向上一个节点,初始化为nullptr;
  18. ListNode* pPreNode = nullptr;
  19. //3.当前节点pNode,初始化指向头节点
  20. ListNode* pNode=pHead;
  21. //4.删除重复节点,while循环条件:pNode不为空
  22. while(pNode)
  23. {
  24. //4.1 pNext指向pNode下个节点
  25. ListNode* pNext= pNode->next;
  26. //4.2 bool标记pNode是否需要删除,默认值false
  27. bool needDelete=false;
  28. //4.3 更新needDelete标记值:如果pNode的值和下个节点pNext的值相等的话,这个节点需要删除
  29. if(pNext&&pNode->val==pNext->val)
  30. needDelete=true;
  31. //4.4 如果不需要删除,当前节点pNode向后指一个pNext,上一个节点pPreNode指向当前节点
  32. if(!needDelete)
  33. {
  34. pPreNode=pNode;
  35. pNode=pNext;
  36. }
  37. //4.5 否则需要删除
  38. else
  39. {
  40. //4.5.1 存放当前pNode的值int
  41. int value=pNode->val;
  42. //4.5.2 定义待删除的节点toBeDeleted
  43. ListNode* toBeDeleted=pNode;
  44. //4.5.2 如果待删除的节点toBeDeleted存在,且值等于当前pNode的值,则删除该节点
  45. while(toBeDeleted&&toBeDeleted->val==value)
  46. {
  47. //4.5.2.1 保存待删除节点的下个节点
  48. pNext=toBeDeleted->next;
  49. //4.5.2.2 删除该节点
  50. delete toBeDeleted;
  51. toBeDeleted=nullptr;
  52. //4.5.2.3 重新更新待删除的节点
  53. toBeDeleted=pNext;
  54. }
  55. //4.5.3 如果上个节点为空,即头节点被删除,头节点为pNext
  56. if(!pPreNode)
  57. pHead=pNext;
  58. //4.5.4上一个节点pPreNode指向当前节点
  59. else
  60. pPreNode->next=pNext;
  61. //4.6 将当前节点pNode向后指一个pNext
  62. pNode=pNext;
  63. }
  64. }
  65. //5. 返回链表
  66. return pHead;
  67. }
  68. };

网友的

  1. class Solution {
  2. public:
  3. ListNode* deleteDuplication(ListNode* pHead)
  4. {
  5. if (pHead==NULL)
  6. return NULL;
  7. if (pHead!=NULL && pHead->next==NULL)
  8. return pHead;
  9. ListNode* current;
  10. if ( pHead->next->val==pHead->val){
  11. current=pHead->next->next;
  12. while (current != NULL && current->val==pHead->val)
  13. current=current->next;
  14. return deleteDuplication(current);
  15. }
  16. else {
  17. current=pHead->next;
  18. pHead->next=deleteDuplication(current);
  19. return pHead;
  20. }
  21. }
  22. };

第18题:在O(1)时间删除链表结点+删除链表中重复的节点的更多相关文章

  1. 【IT笔试面试题整理】删除无序链表中重复的节点

    [试题描述]定义一个函数,输入一个链表,删除无序链表中重复的节点 [参考代码] 方法一: Without a buffer, we can iterate with two pointers: &qu ...

  2. 【剑指offer】删除链表中重复的节点,C++实现(链表)

    0.简介       本文是牛客网<剑指offer>笔记. 1.题目 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针.例如,链表1-> ...

  3. php实现删除链表中重复的节点

    php实现删除链表中重复的节点 一.总结 二.php实现删除链表中重复的节点 题目描述: 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1 ...

  4. 剑指offer——面试题18.1:删除链表中重复的节点

    // 面试题18(二):删除链表中重复的结点 // 题目:在一个排序的链表中,如何删除重复的结点?例如,在图3.4(a)中重复 // 结点被删除之后,链表如图3.4(b)所示. #include &l ...

  5. 【Offer】[18-2] 【删除链表中重复的节点】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3- ...

  6. AcWing 29. 删除链表中重复的节点

    题目地址 https://www.acwing.com/problem/content/description/27/ 来源:剑指Offer 题目描述在一个排序的链表中,存在重复的结点,请删除该链表中 ...

  7. 剑指offer(56)删除链表中重复的节点

    一直忘记更新了,把剑指offer更新完吧.... 题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3-&g ...

  8. pta 奇数值结点链表&&单链表结点删除

    本题要求实现两个函数,分别将读入的数据存储为单链表.将链表中奇数值的结点重新组成一个新的链表.链表结点定义如下: struct ListNode { int data; ListNode *next; ...

  9. python实现剑指offer删除链表中重复的节点

    题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...

随机推荐

  1. 在邮箱服务器上执行Powershell命令Get-MessageTrackingLog 报错

    开启对应的服务即可. 中文环境: 英文环境:

  2. POJ2758 Checking the Text 哈希

    注意到插入次数挺少的,于是每次暴力重构,然后哈希+二分 #include<cstdio> #include<iostream> #include<algorithm> ...

  3. Restful 4 -- 认证组件、权限组件、频率组件、url注册器、响应器、分页器

    一.认证组件.权限组件.频率组件总结:  只有认证通过的用户才能访问指定的url地址,比如:查询课程信息,需要登录之后才能查看,没有登录,就不能查看,这时候需要用到认证组件 1.认证组件格式 写一个认 ...

  4. Excel去除空行

    本文转载至:https://baijiahao.baidu.com/s?id=1590204478648348952&wfr=spider&for=pc,需要详细信息可链接查看 方法一 ...

  5. LeetCode 225 Implement Stack using Queues 用队列实现栈

    1.两个队列实现,始终保持一个队列为空即可 class MyStack { public: /** Initialize your data structure here. */ MyStack() ...

  6. POJ 1556 E - The Doors

    题意:给定n堵墙,现在要你从(0,5)走去(10,5)的最短距离 思路:刚开始还想模拟,就是从(0,5)走,每次x向右一格,然后判断有没和线段相交就可以.但是它的们有可能是小数形式给出的,这样就GG了 ...

  7. FTP连接报530 User 用户名 cannot log in home directory inaccessible的解决方法

    在server 2003新建ftp用户并开启IIS的Ftp功能之后,有时在连接这个ftp的时候会出现530 User 用户名 cannot log in home directory inaccess ...

  8. GitHub上易于高效开发的Android开源项目TOP20--适合新手

    1. android-async-http android-async-http是Android上的一个异步.基于回调的HTTP客户端开发包,建立在Apache的HttpClient库上. 2. an ...

  9. 学习笔记:《JavaScript高级程序设计》

    第1章 JavaScript简介 1.一个完整的JavaScript实现应该由三部分组成:核心(ECMAScript),文档对象模型(DOM)和浏览器对象模型(BOM). 2.Web浏览器只是ECMA ...

  10. UEditor百度编辑器

    第一步:首先下载ueditor编译器,地址:http://ueditor.baidu.com/website/ 下载完解压之后就这个: 第二步:我会把文件名utf-8-jsp这个文件名改为uedito ...