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

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.单链表操作时,储存前一个节点的信息往往是有效的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/445042.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

探索式软件测试

James A.Whittaker [美] 詹姆斯惠特克(软件测试领域绝对的大师)著作《Exploratory Software Testing》,中文名《探索式软件测试》,记得当时被这本书深深吸引啦(我不知道有多少做测试的小伙伴看过这本书)&am…

Linux线程池的设计

我设计这个线程池的初衷是为了与socket对接的。线程池的实现千变万化,我得这个并不一定是最好的,但却是否和我心目中需求模型的。现把部分设计思路和代码贴出,以期抛砖引玉。个人比较喜欢搞开源,所以大家如果觉得有什么需要改善的…

算法(12)-leetcode-explore-learn-数据结构-双链表的设计

leetcode-explore-learn-数据结构-链表4双链表的设计本系列博文为leetcode-explore-learn子栏目学习笔记,如有不详之处,请参考leetcode官网:https://leetcode-cn.com/explore/learn/card/linked-list/所有例题的编程语言为python 双链表的设…

安全方面知识

什么是文件上传漏洞 文件上传漏洞是指 由于程序员在对用户文件上传部分的控制不足或者处理缺陷,而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件 这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。 这种攻击方式是…

CE游戏外挂工具

CHEAT ENGINE(以下简称CE)是我见过的最优秀的游戏作弊工具。它的优点多不胜数,虽然单独从搜索游 戏里面的数值来说,它并不比其他同类软件强多少,但它不仅仅是个游戏修改工具,它还有其他游戏修改软件所没有的一些特点,例…

外挂编程-动作模拟技术

几乎所有的游戏都有大量繁琐和无聊的攻击动作以增加玩家的 功力,还有那些数不完的迷宫,这些好像已经成为了角色游戏的代名词。现在,外挂可以帮助玩家从这些繁琐而无聊 的工作中摆脱出来。 1. 鼠标模拟技术 几乎所有的游戏中都使用了鼠标来改变角色的位置和方向,玩家仅用…

算法(13)-leetcode-explore-learn-数据结构-链表小结

leetcode-explore-learn-数据结构-链表51.小结2.例题2.1合并两个有序链表思路1:迭代思路2:递归2.2 两数相加2.3 扁平化多级双向链表2.4 复制带随机指针的链表2.5 旋转链表本系列博文为leetcode-explore-learn子栏目学习笔记,如有不详之处,请参考leetcode…

leetcode121买卖股票的最佳时机

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。 注意你不能在买入股票前卖出股票。 示例 1: 输入: [7,1,5,3,6,…

epoll的内核实现

epoll是由一组系统调用组成。 int epoll_create(int size); int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout); select/poll的缺点在于&#xff1…

算法(14)-数据结构-二叉树

leetcode-explore-learn-数据结构-二叉树10.概述1.深度优先遍历dfs1.1先序遍历-中左右1.2中序遍历-左中右1.3后序遍历-左右中2.广度优先遍历bfs3.遍历-常见问题3.1 二叉树的最大深度自顶向下自底向上3.2对称二叉树3.3路径总和4.重构-常见问题4.1根据中序和后序遍历序列构造二叉…

多进程鱼多线程的权衡选择

最近有好多人在网上问道做游戏开发框架用多线程还是多进程呢,或者两者之间的优缺点,等等类似的问题。下边小高就带您小小分析一下: 1、首先要明确进程和线程的含义:进程(Process)是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一…

leetcode322 零钱兑换

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。 示例 1: 输入: coins [1, 2, 5], amount 11 输出: 3 解释: 11 5 5 1 示例 2: 输入: coins [2],…

给数据减肥 让MySQL数据库跑的更快

在数据库优化工作中,使数据尽可能的小,使表在硬盘上占据的空间尽可能的小,这是最常用、也是最有效的手段之一。因为缩小数据,相对来说可以提高硬盘的读写速度,并且在查询过程中小表的内容处理时所占用的系统资源比较少…

算法(15)-leetcode-explore-learn-数据结构-运用递归解决二叉树的问题

leetcode-explore-learn-数据结构-二叉树2本系列博文为leetcode-explore-learn子栏目学习笔记,如有不详之处,请参考leetcode官网:https://leetcode-cn.com/explore/learn/card/data-structure-binary-tree/2/traverse-a-tree/7/

leetcode538 把二叉搜索树转换成累加树

给定一个二叉搜索树(Binary Search Tree),把它转换成为累加树(Greater Tree),使得每个节点的值是原来的节点值加上所有大于它的节点值之和。 对于每一个点来说,自己的父,和自己父的右子树都是大…

AWK常用命令华(1)

awk 调用: 1.调用awk:

AWk的调用精华

awk 的调用方式 awk 提供了适应多种需要的不同解决方案,它们是: 一、awk 命令行,你可以象使用普通UNIX 命令一样使用awk,在命令行中你也可以使用awk 程序设计语言,虽然awk 支持多行的录入,但是录入长长的命令行并保证其正 确无误却是一件令人头疼的事,因此,这种方法一般…

算法(16)-leetcode-explore-learn-数据结构-二叉树总结

leetcode-explore-learn-数据结构-二叉树3本系列博文为leetcode-explore-learn子栏目学习笔记,如有不详之处,请参考leetcode官网:https://leetcode-cn.com/explore/learn/card/data-structure-binary-tree/2/traverse-a-tree/7/所有例题的编程…

leetcode15 三数之和

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a b c 0 ?找出所有满足条件且不重复的三元组。 注意:答案中不可以包含重复的三元组。 例如, 给定数组 nums [-1, 0, 1,…

AWK再次认识--内置的参数,以及编写脚本

原本这是篇给公司内同事写的培训文章,对于初学awk的人还蛮有帮助,贴到这里与大家共享一下。 〇、前言 意见反馈,请mailto:datouwanggmail.com。 一、AWK简介 AWK名字来源于三位创造者Aho、Weinberger和Kernighan统称。 AWK擅长处理文本数据。…