leetcode-explore-learn-数据结构-链表3

  • 1.反转一个链表
  • 2.移除链表元素
  • 3.奇偶链表
  • 4.回文链表
  • 5.小结

本系列博文为leetcode-explore-learn子栏目学习笔记,如有不详之处,请参考leetcode官网:https://leetcode-cn.com/explore/learn/card/linked-list/

所有例题的编程语言为python

1.反转一个链表

leetcode 206
思路1: 迭代求解,将当前结点next信息保存下来,然后将前一个节点的信息存入当前结点的next中。更新当前结点。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution(object):def reverseList(self, head):""":type head: ListNode:rtype: ListNode"""if head==None:return headpre_node=Nonecur_node=headwhile(cur_node):next_node=cur_node.nextcur_node.next=pre_nodepre_node=cur_nodecur_node=next_nodereturn pre_node

思路2:
递归:假设链表的其余部分都已经被翻转,现在该如何翻转它前面的部分。由最后一个开始往前不断翻转

class Solution(object):def reverseList(self, head):""":type head: ListNode:rtype: ListNode"""if head==None or head.next==None:return headp=self.reverseList(head.next)   # 记录最后一个结点作为头指针用的。head.next.next=headhead.next=Nonereturn p

2.移除链表元素

删除链表中等于给定值 val 的所有节点。
思路:遍历链表的每一结点,如果值等于给定值将其删除即可。
注意点:要删除链表节点时,可以使用哑结点技巧,防止删原链表的头结点。最后返回时,返回dummy.next即可。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution(object):def removeElements(self, head, val):""":type head: ListNode:type val: int:rtype: ListNode"""dummy=ListNode(0)dummy.next=headpre_node=dummycur_node=dummy.nextwhile(cur_node):next_node=cur_node.nextif cur_node.val==val:pre_node.next=next_node  # 删除结点else:pre_node=cur_nodecur_node=next_nodereturn dummy.next

3.奇偶链表

给定一个单链表,把所有奇数节点和偶数节点(节点 编号的奇偶性)分别排在一起。
思路1:原来的链表分成奇偶两个子链表,然后将偶链表链接到奇链表后面。
没有使用额外的空间,直接从原来的链表中截取。

# Definition for singly-linked list.
class ListNode(object):def __init__(self, x):self.val = xself.next = Noneclass Solution(object):def oddEvenList(self, head):""":type head: ListNode:rtype: ListNode"""if head==None:return headeven_h=ListNode(0)even_node=even_hcur_node=headi=1while(cur_node):next_node=cur_node.nextif i %2==0:cur_node.next=None   # 将node.next的值给设置为零,能防止成环even_node.next=cur_nodeeven_node=even_node.nextpre_node.next=next_nodeelse:pre_node=cur_nodecur_node=next_nodei+=1cur_node=head.nextpre_node=headwhile(cur_node):print(pre_node.val)pre_node=cur_nodecur_node=cur_node.nextpre_node.next=even_h.nextreturn head

4.回文链表

判断一个链表是否为回文链表。
o(n)时间复杂度,o(1)空间复杂度

思路1:可以先把链表装进数组中,判断数组中元素是否构成回文。数组的前后遍历比单链表方便。时间复杂度o(n),空间复杂度o(n)

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution(object):def isPalindrome(self, head):""":type head: ListNode:rtype: bool"""if not head or not head.next:return Truelst=[]p=headwhile(p):lst.append(p.val)p=p.nextreturn lst==lst[::-1]

思路2:翻转原链表,对照两个链表是否一致,如果回文链表应该是一致的,反之原链表不为回文链表。时间复杂度o(n),空间复杂度o(n)

# Definition for singly-linked list.
class ListNode(object):def __init__(self, x):self.val = xself.next = Noneclass Solution(object):def isPalindrome(self, head):""":type head: ListNode:rtype: bool"""if head==None or head.next==None:return True# 备份原链表head_be=ListNode(0)node=headnode_be=head_be    while(node):node_be.next=ListNode(node.val)node_be=node_be.nextnode=node.next# 转置原链表pre_node=Nonecur_node=headwhile(cur_node):next_node=cur_node.nextcur_node.next=pre_nodepre_node=cur_nodecur_node=next_node# 比较两个链表node_be=head_be.nextnode_af=pre_nodewhile(node_be and node_af):if node_be.val!=node_af.val:return Falsenode_be=node_be.nextnode_af=node_af.nextreturn True

思路三:避免使用 O(n)O(n) 额外空间的方法就是改变输入。

我们可以将链表的后半部分反转(修改链表结构),然后将前半部分和后半部分进行比较。比较完成后我们应该将链表恢复原样。虽然不需要恢复也能通过测试用例,因为使用该函数的人不希望链表结构被更改。

class Solution(object):def isPalindrome(self, head):""":type head: ListNode:rtype: bool"""if not head or not head.next:return True# 计算链表长度p1=headn=1while(p1.next):p1=p1.nextn+=1p1=headp2=headif n==2:if  head.val==head.next.val:return Trueelse:return False# 找链表中点for i in range(int(round(n/2.0))-1): # 0p1=p1.nexthalf_end=p1     # 前一半链表的最后一个节点# 翻转后一半链表p1=p1.nextpre_node=Nonefor i in range(int(n/2.0)): # 0,1next_node=p1.nextp1.next=pre_nodepre_node=p1p1=next_nodehalf_end.next=pre_nodep1=head# 比较前一半和翻转后的后一半。for i in range(int(round(n/2.0))): # 0,1p1=p1.nextfor i in range(int(n/2)):# 0,1if p1.val!=p2.val:return Falsep1=p1.nextp2=p2.nextreturn True

5.小结

1.使用链表时不易调试,自己多尝试几个测试用例总是很有用的,通过输出链表节点的值来观测代码运行情况。

2.多指针时,为指针设定合适的名称,防止自己被搞混

3.单链表操作时,储存前一个节点的信息往往是有效的。

算法(11)-leetcode-explore-learn-数据结构-链表的经典问题相关推荐

  1. java算法判断链表有没有闭环_前端算法系列之二:数据结构链表、双向链表、闭环链表、有序链表...

    前言 上一次我们讲到了数据结构:栈和队列,并对他们的运用做了一些介绍和案例实践:我们也讲到了怎么简单的实现一个四则运算.怎么去判断标签是否闭合完全等等,anyway,今天接着和大家介绍一些数据结构: ...

  2. 获取用户列表为空_数据结构和算法(Golang实现)(15)常见数据结构-列表

    列表 一.列表 List 我们又经常听到 列表 List 数据结构,其实这只是更宏观的统称,表示存放数据的队列. 列表 List:存放数据,数据按顺序排列,可以依次入队和出队,有序号关系,可以取出某序 ...

  3. 数据结构 - 链表 - 面试中常见的链表算法题

    数据结构 - 链表 - 面试中常见的链表算法题 数据结构是面试中必定考查的知识点,面试者需要掌握几种经典的数据结构:线性表(数组.链表).栈与队列.树(二叉树.二叉查找树.平衡二叉树.红黑树).图. ...

  4. 写出一段代码将链表中的两个节点位置互换位置_面试 leetcode 算法专题系列(二)—— 链表...

    前言:只照着常考题去刷题确实是一种方法.但调研之后发现自己还是考虑不周,刷题刷的不应该是题,而是解题的思路和熟练程度.于是我决定重新组织一下刷题笔记的讲解顺序,不再以面试常考题来刷.而是以面试出题频率 ...

  5. leetcode旋转数组 c语言,leetcode explore 初级算法第三题,旋转数组代码实现

    leetcode explore 初级算法第三题,旋转数组代码实现.原题链接: 题目分析 因为题目不是很长,这里把题目贴出来: 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. ...

  6. Leetcode算法Java全解答--19. 删除链表的倒数第N个节点

    Leetcode算法Java全解答–19. 删除链表的倒数第N个节点 文章目录 Leetcode算法Java全解答--19. 删除链表的倒数第N个节点 题目 想法 结果 总结 代码 我的答案 大佬们的 ...

  7. 数据结构与算法之打印两个有序链表公共部分和判断一个链表是否具有回文结构

    数据结构与算法之打印两个有序链表公共部分和判断一个链表是否具有回文结构 目录 打印两个有序链表公共部分 判断一个链表是否具有回文结构 1. 打印两个有序链表公共部分 1.问题描述 思路:Node1和N ...

  8. Python数据结构与算法(2.6)——块状链表

    Python数据结构与算法(2.6)--块状链表 0. 学习目标 1. 块状链表简介 1.1 块状链表介绍 1.2 块状链表中结点类 1.3 块状链表中块类 2. 块状链表的实现 2.1 块状链表的初 ...

  9. 刻意练习:LeetCode实战 -- Task09. 环形链表

    背景 本篇图文是LSGO软件技术团队组织的 第二期基础算法(Leetcode)刻意练习训练营 的打卡任务.本期训练营采用分类别练习的模式,即选择了五个知识点(数组.链表.字符串.树.贪心算法),每个知 ...

最新文章

  1. 一个很好的Qt教程个人主页
  2. 拷贝构造,操作符重载
  3. [css]你有使用过preload、preconnect、prefetch这些属性吗?说说它们都有什么作用?
  4. 前端学习(2818):小程序学习之新建页面
  5. 持续定义Saas模式云数据仓库+BI
  6. 数据库系统中事务的ACID原则
  7. php 多级分成手机版,PHP 层级菜单数组处理,由一级数组转换为多级数组的递归实现...
  8. .NET面试题系列(二十)XX
  9. 决策树之随机森林和GBDT
  10. 第五十七章 Caché 函数大全 $REPLACE 函数
  11. SQL注入原理及联合查询
  12. 银河土星_不要购买三星银河笔记20
  13. 树莓派11bullseye换源/Opencv安装
  14. 光盘刻录系列之二刻录光盘的程序步骤
  15. 一年内经验前端面试题记录
  16. doris数据库环境搭建报错(invalid cluster id. ignore)
  17. 解读高端PCB板的设计工艺!
  18. 如何用钢笔工具抠图ps教程ps学习
  19. 程序员自我修养阅读笔记——运行库
  20. pycharm格式化代码快捷键Ctrl+Alt+L失效解决方案

热门文章

  1. magicbook linux系统换w7,荣耀magicbook怎么安装win7 荣耀magicbook安装win7方法
  2. python socket发包_一个python发包的脚本
  3. python迭代器创建序列_Python 中迭代器与生成器实例详解
  4. 利用arcgis将execl数据可视化(点)
  5. 【转】ABP源码分析三十:ABP.RedisCache
  6. 【转】细说.NET中的多线程 (二 线程池)
  7. 【转】CLR Profiler 性能分析工具 (转)
  8. 【转】C#中ToString()格式详解
  9. 【转】WCF Odata 开放数据协议应用
  10. [你必须知道的.NET]第三十四回,object成员,不见了!