python无序链表删除重复项的方法


Posted in Python onJanuary 17, 2020

题目描述:

给定一个没有排序的链表,去掉重复项,并保留原顺序 如: 1->3->1->5->5->7,去掉重复项后变为:1->3->5->7

方法:

  1. 顺序删除
  2. 递归删除

1.顺序删除

由于这种方法采用双重循环对链表进行遍历,因此,时间复杂度为O(n**2)
在遍历链表的过程中,使用了常数个额外的指针变量来保存当前遍历的结点,前驱结点和被删除的结点,所以空间复杂度为O(1)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time  : 2020/1/15 20:55
# @Author : buu
# @Software: PyCharm
# @Blog  :https://blog.csdn.net/weixin_44321080
class LNode:
  def __init__(self, x):
    self.data = x
    self.next = None

def removeDup(head):
  """
  对带头结点的无序单链表删除重复的结点
  顺序删除:通过双重循环直接在链表上进行删除操作
  即,外层循环用一个指针从第一个结点开始遍历整个链表,内层循环从外层指针指向的下一个结点开始,
  遍历其余结点,将与外层循环遍历到的的指针所指的结点的数据域相同的结点删除
  :param head: 头指针
  :return:
  """
  if head is None or head.next is None:
    return
  outerCur = head.next
  innerCur = None
  innerPre = None
  while outerCur is not None:
    innerCur = outerCur.next
    innerPre = outerCur
    while innerCur is not None:
      if outerCur.data == innerCur.data:
        innerPre.next = innerCur.next
        innerCur = innerCur.next
      else:
        innerPre = innerCur
        innerCur = innerCur.next
    outerCur = outerCur.next

if __name__ == '__main__':
  i = 1
  head = LNode(6)
  tmp = None
  cur = head
  while i < 7:
    if i % 2 == 0:
      tmp = LNode(i + 1)
    elif i % 3 == 0:
      tmp = LNode(i - 2)
    else:
      tmp = LNode(i)
    cur.next = tmp
    cur = tmp
    i += 1
  print("before removeDup:")
  cur = head.next
  while cur is not None:
    print(cur.data, end=' ')
    cur = cur.next
  removeDup(head)
  print("\nafter removeDup:")
  cur = head.next
  while cur is not None:
    print(cur.data, end=' ')
    cur = cur.next

结果:

python无序链表删除重复项的方法

2.递归

此方法与方法一类似,从本质上而言,由于这种方法需要对链表进行双重遍历,所以时间复杂度为O(n**2)
由于递归法会增加许多额外的函数调用,所以从理论上讲,该方法效率比方法一低

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time  : 2020/1/15 21:30
# @Author : buu
# @Software: PyCharm
# @Blog  :https://blog.csdn.net/weixin_44321080
class LNode:
  def __init__(self, x):
    self.data = x
    self.next = None
def removeDupRecursion(head):
  """
  递归法:将问题逐步分解为小问题,即,对于结点cur,首先递归地删除以cur.next为首
  的子链表中重复的结点;接着删除以cur为首的链表中的重复结点,
  :param head:
  :return:
  """
  if head.next is None:
    return head
  pointer = None
  cur = head
  head.next = removeDupRecursion(head.next)
  pointer = head.next
  while pointer is not None:
    if head.data == pointer.data:
      cur.next = pointer.next
      pointer = cur.next
    else:
      pointer = pointer.next
      cur = cur.next
  return head
def removeDup(head):
  """
  对带头结点的单链表删除重复结点
  :param head: 链表头结点
  :return:
  """
  if head is None:
    return
  head.next = removeDupRecursion(head.next)
if __name__ == '__main__':
  i = 1
  head = LNode(6)
  tmp = None
  cur = head
  while i < 7:
    if i % 2 == 0:
      tmp = LNode(i + 1)
    elif i % 3 == 0:
      tmp = LNode(i - 2)
    else:
      tmp = LNode(i)
    cur.next = tmp
    cur = tmp
    i += 1
  print("before recursive removeDup:")
  cur = head.next
  while cur is not None:
    print(cur.data, end=' ')
    cur = cur.next
  removeDup(head)
  print("\nafter recurseve removeDup:")
  cur = head.next
  while cur is not None:
    print(cur.data, end=' ')
    cur = cur.next

结果:

python无序链表删除重复项的方法

引申:从有序链表中删除重复项

上述介绍的方法也适用于链表有序的情况,但是由于上述方法没有充分利用到链表有序这个条件,因此,算法的性能肯定不是最优的。本题中,由于链表具有有序性,因此不需要对链表进行两次遍历。所以有如下思路:
用cur指向链表的第一个结点,此时需要分为以下两种情况讨论:

  • 如果cur.data == cur.next.data,则删除cur.next结点;
  • 如果cur.data != cur.next.data,则cur=cur.next,继续遍历其余结点;

总结

以上所述是小编给大家介绍的python无序链表删除重复项的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
Python SQLite3数据库操作类分享
Jun 10 Python
Django中实现点击图片链接强制直接下载的方法
May 14 Python
Python使用Redis实现作业调度系统(超简单)
Mar 22 Python
Python读取和处理文件后缀为.sqlite的数据文件(实例讲解)
Jun 27 Python
在django中使用自定义标签实现分页功能
Jul 04 Python
Python中进程和线程的区别详解
Oct 29 Python
基于Python os模块常用命令介绍
Nov 03 Python
python实现截取屏幕保存文件,删除N天前截图的例子
Aug 27 Python
一文解决django 2.2与mysql兼容性问题
Jul 15 Python
Python如何使用27行代码绘制星星图
Jul 20 Python
使用Python的开发框架Brownie部署以太坊智能合约
May 28 Python
从np.random.normal()到正态分布的拟合操作
Jun 02 Python
Python实现投影法分割图像示例(一)
Jan 17 #Python
np.dot()函数的用法详解
Jan 17 #Python
python使用numpy实现直方图反向投影示例
Jan 17 #Python
对python中 math模块下 atan 和 atan2的区别详解
Jan 17 #Python
python 计算方位角实例(根据两点的坐标计算)
Jan 17 #Python
Python autoescape标签用法解析
Jan 17 #Python
flask利用flask-wtf验证上传的文件的方法
Jan 17 #Python
You might like
10个超级有用值得收藏的PHP代码片段
2015/01/22 PHP
PHP实现上传多图即时显示与即时删除的方法
2017/05/09 PHP
PHP实现负载均衡的加权轮询方法分析
2018/08/22 PHP
thinkPHP框架实现类似java过滤器的简单方法示例
2018/09/05 PHP
js 目录列举函数
2008/11/06 Javascript
Extjs 3.3切换tab隐藏相应工具栏出现空白解决
2013/04/02 Javascript
JS父页面与子页面相互传值方法
2014/03/05 Javascript
jQuery 判断图片是否加载完成方法汇总
2015/08/10 Javascript
详解JS正则replace的使用方法
2016/03/06 Javascript
jQuery通过ajax快速批量提交表单数据
2016/10/25 Javascript
JavaScript常见的五种数组去重的方式
2016/12/15 Javascript
seajs模块压缩问题与解决方法实例分析
2017/10/10 Javascript
浅谈Angular 的变化检测的方法
2018/03/01 Javascript
vue项目环境变量配置的实现方法
2018/10/12 Javascript
ES6基础之展开语法(Spread syntax)
2019/02/21 Javascript
ES6 Object属性新的写法实例小结
2019/06/25 Javascript
[37:45]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS Orenda
2014/05/22 DOTA
Python和Ruby中each循环引用变量问题(一个隐秘BUG?)
2014/06/04 Python
Python中的赋值、浅拷贝、深拷贝介绍
2015/03/09 Python
处理Python中的URLError异常的方法
2015/04/30 Python
python统计字母、空格、数字等字符个数的实例
2018/06/29 Python
Python正则表达式实现简易计算器功能示例
2019/05/07 Python
PyQt5实现从主窗口打开子窗口的方法
2019/06/19 Python
树莓派+摄像头实现对移动物体的检测
2019/06/22 Python
Django用户身份验证完成示例代码
2020/04/03 Python
django和flask哪个值得研究学习
2020/07/31 Python
用CSS3实现无限循环的无缝滚动的示例代码
2017/11/01 HTML / CSS
英国折扣高尔夫商店:Discount Golf Store
2019/11/19 全球购物
奥地利婴儿用品和玩具购物网站:baby-markt.at
2020/01/26 全球购物
shell程序中如何注释
2012/02/17 面试题
行政助理工作职责范本
2014/03/04 职场文书
辞职信怎么写
2015/02/27 职场文书
吧主申请感言怎么写
2015/08/03 职场文书
Python中json.load()和json.loads()有哪些区别
2021/06/07 Python
详解Java实践之适配器模式
2021/06/18 Java/Android
PHP中多字节字符串操作实例详解
2021/08/23 PHP