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实现的百度贴吧网络爬虫实例
Apr 17 Python
Django自定义认证方式用法示例
Jun 23 Python
tensorflow saver 保存和恢复指定 tensor的实例讲解
Jul 26 Python
详解Python数据分析--Pandas知识点
Mar 23 Python
python机器学习实现决策树
Nov 11 Python
python几种常用功能实现代码实例
Dec 25 Python
Python如何使用paramiko模块连接linux
Mar 18 Python
Python爬虫实例——爬取美团美食数据
Jul 15 Python
Python必须了解的35个关键词
Jul 16 Python
Python通过format函数格式化显示值
Oct 17 Python
宝塔更新Python及Flask项目的部署
Apr 11 Python
Python 中面向接口编程
May 20 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
PHP常用代码
2006/11/23 PHP
菜鸟学PHP之Smarty入门
2007/01/04 PHP
php判断linux下程序问题实例
2015/07/09 PHP
php发送短信验证码完成注册功能
2015/11/24 PHP
linux下php上传文件注意事项
2016/06/11 PHP
Ajax搜索结果页面下方的分页按钮的生成
2012/04/05 Javascript
js实现一个省市区三级联动选择框代码分享
2013/03/06 Javascript
jquery.blockUI.js上传滚动等待效果实现思路及代码
2013/03/18 Javascript
js实现上传文件添加和删除文件选择框
2016/10/24 Javascript
AngularJS 获取ng-repeat动态生成的ng-model值实例详解
2016/11/29 Javascript
JS多物体实现缓冲运动效果示例
2016/12/20 Javascript
EasyUI修改DateBox和DateTimeBox的默认日期格式示例
2017/01/18 Javascript
微信小程序开发的四十个技术窍门总结(推荐)
2017/01/23 Javascript
Javascript基础回顾之(一) 类型
2017/01/31 Javascript
vue的Virtual Dom实现snabbdom解密
2017/05/03 Javascript
JavaScript Date对象应用实例分享
2017/10/30 Javascript
vue中使用ueditor富文本编辑器
2018/02/08 Javascript
JS工厂模式开发实践案例分析
2019/10/17 Javascript
vue如何使用async、await实现同步请求
2019/12/09 Javascript
js实现简单放大镜效果
2020/03/07 Javascript
JS中的变量作用域(console版)
2020/07/18 Javascript
[01:00:59]VP VS VG Supermajor小组赛胜者组第二轮 BO3第二场 6.2
2018/06/03 DOTA
在主机商的共享服务器上部署Django站点的方法
2015/07/22 Python
Python编程中归并排序算法的实现步骤详解
2016/05/04 Python
Python爬虫实战:分析《战狼2》豆瓣影评
2018/03/26 Python
Python正则表达式实现简易计算器功能示例
2019/05/07 Python
Python从列表推导到zip()函数的5种技巧总结
2019/10/23 Python
python、Matlab求定积分的实现
2019/11/20 Python
django model的update时auto_now不被更新的原因及解决方式
2020/04/01 Python
细说NumPy数组的四种乘法的使用
2020/12/18 Python
HTML5 常见面试题之PC端和移动端区别介绍
2018/01/22 HTML / CSS
美国户外生活方式品牌:Eddie Bauer
2016/12/28 全球购物
秋季红领巾广播稿
2014/01/27 职场文书
关于清明节的演讲稿
2014/09/13 职场文书
工作保证书
2015/01/17 职场文书
Java实现超大Excel文件解析(XSSF,SXSSF,easyExcel)
2022/07/15 Java/Android