python什么是交换算法_python算法-015将链表元素两两交换元素(交换值、就地翻转)...
大鹏一日同风起,扶摇直上九万里。
假令风歇时下来,犹能簸却沧溟水。
世人见我恒殊调,闻余大言皆冷笑。
宣父犹能畏后生,丈夫未可轻年少。
——李白《上李邕》
在现代,别人对你的文章冷嘲热讽,你来一句:“你行你上啊!”他可能就没脾气了。但是要换李白,他真的会上,因为他真的行!
题目描述:将链表的每两个节点翻转。不允许用新的节点。
例如:
给定链表Head->1->2->3->4->5->7->7->8
反转为链Head->2->1->4->3->7->5->8->7
这题是为了明天的题目做铺垫的,先来分析下这个题:本质上还是操作链表,之前我们做过类似的。不过,这次是翻转节点,节点有两个属性data和next,交换两个节点的值就可以完成了,这样不需要将节点位置改变。这太简单了,就像a=1,b=2,交换a,b的值一样那么简单,只需要用一个中间值tmp来保存就行:tmp=a a=b b=tmp。主要的问题就是如何遍历的问题,这也是个不是问题的问题。用一个指针即可完成,但是对于明天的题,并没有太大帮助。
下面来看利用next属性,如何做:
利用next属性必然会改变节点的位置,也就是链表结构会变,先来看看怎样改变
主两个指针,更好理解
图中我用红笔标出了操作顺序1、2、3、4:先pre->fast,然后fast->slow,最后slow->next,这里为什么会先把next->fast.next:因为在第二步时,得保存后面的链表,不然会丢失,这与a.b交换值是一个道理。这里的顺序也可以换成1、2、4、3,两个效果是一样的。
这里有一个注意的地方就是每次的循环条件:宗旨就是当后面的节点不够一组进行交换时,退出循环。但是如何知道后面不够一组呢?先来看下代码。
下面代码实现:
def function(head):
#判断链表是否为空,为空返回
if head.next is None or head.next.next is None:
return head
pre=head # 指向slow的前驱节点
slow=head.next
fast=slow.next
#slow和fast为相邻的节点
#next=fast.next
# 这里的循环条件要注意
# 链表的长度可能为奇数,也可能是偶数
# 每次四个指针会变换,因为是先操作再迭代下一组
# 再迭变换完后,如果fast指针后面只有一个元素,或者没有元素,这时
# 后面的无法再进行翻转,所以应该出循环,正常应该做完在判断的,
# 这里只能符合的才操作,因为用的指针多了一个。
while fast.next is not None and fast.next.next is not None:
next = fast.next #保存链表,因为要断开
pre.next=fast
fast.next=slow
slow.next=next
# # 上面的四句做的操作,见图
pre=slow
slow=next
fast=slow.next
#因为面的判断条件,最后一组,我们并没有翻转,这里操作下
next = fast.next
pre.next = fast
fast.next = slow
slow.next = next
return head
这里我用while fast.next is not None and fast.next.next is not None,这一句看起来很臃肿。
一组
这里我用了四个指针,链表的长度可能为奇数,也可能是偶数,每次四个指针会变换,因为是先操作再迭代下一组,在变换完后,如果fast指针后面只有一个元素,或者没有元素,这时后面的无法再进行翻转,所以应该出循环,按分析应该做完在判断的,但是因为涉及到一个next指针,每次都得确定还有next,才能操作,不然会报错,这里我还没找到一个好的解释办法。要注意的是,最后一组没有换位置,可以把最后的四行语句注释掉,看看结果就知道了。
image.png
鉴于此,我把指针减少了,只用一个主指针cur,用(cur,cur.next)这样一组来代替slow,fast。
这样的好处是,不用考虑fast是否有next.next,只看cur就行。操作是一样的:
image.png
代码实现:
def function(head):
if head is None or head.next is None:
return head
cur=head.next#当前遍历节点
pre=head#当前遍历节点的前驱节点
next=None#当前节点后继节点的后继节点
# 这里的循环条件可能不太一样,因为省掉了fast,所以考虑的东西就会变少。
while cur is not None and cur.next is not None:
next=cur.next.next
pre.next=cur.next
#这里可能一看不太好理解
# (cur.next).next
# 这样把cur.next看做一个节点,也就是之前的fast
cur.next.next=cur
cur.next=next
pre=cur
cur=next
return head
循环条件变了,我将他们放在一个文件里了,如果后者没问题,就可以把变换的链表变回去:
if __name__ == '__main__':
head = creatLink(6)
print("head:")
cur = head.next
while cur != None:
print(cur.data)
cur = cur.next
head = function_1(head)
print("\nAfterReverse_1:") # 这是用slow和fast的
cur = head.next
while cur != None:
print(cur.data)
cur = cur.next
head = function_2(head) # 这是cur
print("\nAfterReverse_2:")
cur = head.next
while cur != None:
print(cur.data)
cur = cur.next
输出结果:
image.png
全部代码:
import random
class LNode:
def __init__(self,arg):
self.data=arg
self.next=None
"""
题目描述:
给定链表Head->1->2->3->4->5->7->7->8
反转为链Head->2->1->4->3->7->5->8->7
要求:
方法:只用一个cur,用pre和next辅助反转。
"""
def creatLink(x):
i = 1
head = LNode(None)
tmp = None
cur = head
while i <= x:
n = random.randint(1, 9)
tmp = LNode(n)
cur.next = tmp
cur = tmp
i += 1
return head
#
#双指针法
def function_1(head):
#判断链表是否为空,为空返回
if head.next is None or head.next.next is None:
return head
pre=head # 指向slow的前驱节点
slow=head.next
fast=slow.next
#slow和fast为相邻的节点
#next=fast.next
# 这里的循环条件要注意
# 链表的长度可能为奇数,也可能是偶数
# 每次四个指针会变换,因为是先操作再迭代下一组
# 再迭变换完后,如果fast指针后面只有一个元素,或者没有元素,这时
# 后面的无法再进行翻转,所以应该出循环,正常应该做完在判断的,
# 这里只能符合的才操作,因为用的指针多了一个。
while fast.next is not None and fast.next.next is not None:
next = fast.next #保存链表,因为要断开
pre.next=fast
fast.next=slow
slow.next=next
# # 上面的四句做的操作,见图
pre=slow
slow=next
fast=slow.next
#因为面的判断条件,最后一组,我们并没有翻转,这里操作下
next = fast.next
pre.next = fast
fast.next = slow
slow.next = next
return head
def function_2(head):
if head is None or head.next is None:
return head
cur=head.next#当前遍历节点
pre=head#当前遍历节点的前驱节点
next=None#当前节点后继节点的后继节点
# 这里的循环条件可能不太一样,因为省掉了fast,所以考虑的东西就会变少。
while cur is not None and cur.next is not None:
next=cur.next.next
pre.next=cur.next
#这里可能一看不太好理解
# (cur.next).next
# 这样把cur.next看做一个节点,也就是之前的fast
cur.next.next=cur
cur.next=next
pre=cur
cur=next
return head
if __name__ == '__main__':
head = creatLink(6)
print("head:")
cur = head.next
while cur != None:
print(cur.data)
cur = cur.next
head = function_1(head)
print("\nAfterReverse_1:")
cur = head.next
while cur != None:
print(cur.data)
cur = cur.next
head = function_2(head)
print("\nAfterReverse_2:")
cur = head.next
while cur != None:
print(cur.data)
cur = cur.next
铺垫就到这里,明天的题目是:
将链表以k个一组翻转,不足k个也翻转,
给定链表Head->1->2->3->4->5->7->7->8
k=3
反转为链Head->3->2->1->7->5->4->8->7
会吗?
今天就这样,更多题目见GitHub,简书、微信:DKider。
Data Knowledge idea(我故意打的r),这是我寒假想的名字,还挺好,之前没有什么实际意义,现在它有了!
我会尽量加快写的速度,我还要留时间学其他的知识。加油吧!
python什么是交换算法_python算法-015将链表元素两两交换元素(交换值、就地翻转)...相关推荐
- python入门算法_Python 算法入门教程
分治算法介绍 今天我们聊一聊计算机中非常重要和常用的一种算法:分治算法.它在计算机领域应用广泛,几乎无处不在.不仅计算机领域,在信号处理领域,分而治之也是十分常见的一种信号处理方法.著名快速傅里叶变换 ...
- python分治算法_Python算法:分治法
本节主要介绍分治法策略,提到了树形问题的平衡性以及基于分治策略的排序算法 本节的标题写全了就是:divide the problem instance, solve subproblems recur ...
- python堆排序算法_Python算法学习之堆和堆排序
什么是堆? 堆是一种完全二叉树(请你回顾下上一章的概念),有最大堆和最小堆两种.最大堆: 对于每个非叶子节点 V,V 的值都比它的两个孩子大,称为 最大堆特性(heap order property) ...
- python魔方程序算法_python魔方程序算法_python算法(一)
# 算法_01_顺时针打印矩阵 ## Question 如果一个3x3的矩阵[ [123] [456] [789] ] 按照从外向里以顺时针的顺序依次打印出每一个数字,那么得到的结果是() %!C. ...
- python中难的算法_Python算法很难吗?python神书《算法图解》PDF电子版分享给你
许多小伙伴后台私信说,python算法让自己很头疼,有没有可以让算法像小说一样有趣的书籍资料呢?看这里吧!小宋为大家找到了这本<算法图解>的PDF电子版!让你在学习python的路上变得轻 ...
- python 从大到小循环_python算法(3) 插入排序
python算法(3) 插入排序 算法分析 给出一个乱序的数列,将这个数列按从小大到(从大到小)重新排列 插入排序的的逻辑是从选这个数列,一个一个的插入一到一个新的数列中 如下: 初始数列: 5 1 ...
- python栈是什么意思_Python算法之栈(stack)的实现
本文以实例形式展示了Python算法中栈(stack)的实现,对于学习数据结构域算法有一定的参考借鉴价值.具体内容如下: 1.栈stack通常的操作: Stack() 建立一个空的栈对象 push() ...
- python编程的50种基础算法_Python算法新手入门大全
干货:GitHub标星2.6万!Python算法新手入门大全 Python已经成为最受欢迎的程序设计语言之一.自从2004年以后,python的使用率呈线性增长.2011年1月,它被TIOBE编程语言 ...
- python计算四元素组合算法_python – 算法,列表元素之间的最近点
这种方法是一种强力方法,但使用类似于Dijkstra算法的消除方法,这导致了更少的情况(使得算法最有可能快几个数量级,特别是对于大型列表或大量列表).告诉我你是否理解它,我可以澄清一下.可以在此处找到 ...
最新文章
- 拥抱 Node.js 8.0,N-API 入门极简例子
- 苹果用户可以自修手机了!原厂零件工具都能买,网友:iScrew螺丝刀600多块?...
- java中字段值重复校验,Java中一些常见的字段校验
- 上网本 ubuntu debian android,关于Debian:在Android上的chroot ubuntu 16.04上,apt-get更新失败...
- 从应用到底层 36张图带你进入Redis世界
- 微信小程序学习日记day1
- WPF---数据绑定之ValidationRule数据校验综合Demo(七)
- 在DelayQueue中更改延迟,从而更改顺序
- python什么软件开发好_python怎样才能学好?python软件开发什么
- 原创 | 我说我了解集合类,面试官竟然问我为啥HashMap的负载因子不设置成1!?...
- 极限 lim(x^x-(sinx)^x)/(x²arctanx)
- 没有基础怎么学习Web前端?相关学习路线又是什么?
- 为什么有些人喜欢用fiddler来抓包?
- 86. php 绘图体系(2)
- 应用安全 - 代码审计 -Java
- Python之路-Day2
- 阿里云宝塔Linux服务器管理面版初始化地址不能登入(原创)
- java中mergesort函数怎么用,由mergeSort引发的一些思考
- PanDownload:登录百度账号提示浏览器版本太低,点击下载webkit内核,然后重启软件即可
- sourcetree拉取项目时报错,解决两个冲突
热门文章
- ACL 2019开源论文 | 基于Attention的知识图谱关系预测
- 抢票 | AI未来说学术论坛第八期 深度学习特别专场
- NAACL 2019最佳论文:量子概率驱动的神经网络
- 蓝桥备赛第三周 倍增+贪心+素数+约数
- Google Colab
- centos 6.5安装mysql5.7,centos6.5安装mysql5.7
- Spring Cloud Security:Oauth2实现单点登录
- 刚构桥的优缺点_连续刚构桥相对于连续梁来说有优点吗
- TRDD got lost again
- linux光盘补救,Linux_忘记root密码时使用Linux系统光盘进行补救的方法,救援模式即rescue ,这个模式主 - phpStudy...