大鹏一日同风起,扶摇直上九万里。

假令风歇时下来,犹能簸却沧溟水。

世人见我恒殊调,闻余大言皆冷笑。

宣父犹能畏后生,丈夫未可轻年少。

——李白《上李邕》

在现代,别人对你的文章冷嘲热讽,你来一句:“你行你上啊!”他可能就没脾气了。但是要换李白,他真的会上,因为他真的行!

题目描述:将链表的每两个节点翻转。不允许用新的节点。

例如:

给定链表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将链表元素两两交换元素(交换值、就地翻转)...相关推荐

  1. python入门算法_Python 算法入门教程

    分治算法介绍 今天我们聊一聊计算机中非常重要和常用的一种算法:分治算法.它在计算机领域应用广泛,几乎无处不在.不仅计算机领域,在信号处理领域,分而治之也是十分常见的一种信号处理方法.著名快速傅里叶变换 ...

  2. python分治算法_Python算法:分治法

    本节主要介绍分治法策略,提到了树形问题的平衡性以及基于分治策略的排序算法 本节的标题写全了就是:divide the problem instance, solve subproblems recur ...

  3. python堆排序算法_Python算法学习之堆和堆排序

    什么是堆? 堆是一种完全二叉树(请你回顾下上一章的概念),有最大堆和最小堆两种.最大堆: 对于每个非叶子节点 V,V 的值都比它的两个孩子大,称为 最大堆特性(heap order property) ...

  4. python魔方程序算法_python魔方程序算法_python算法(一)

    # 算法_01_顺时针打印矩阵 ## Question 如果一个3x3的矩阵[ [123] [456] [789] ] 按照从外向里以顺时针的顺序依次打印出每一个数字,那么得到的结果是() %!C. ...

  5. python中难的算法_Python算法很难吗?python神书《算法图解》PDF电子版分享给你

    许多小伙伴后台私信说,python算法让自己很头疼,有没有可以让算法像小说一样有趣的书籍资料呢?看这里吧!小宋为大家找到了这本<算法图解>的PDF电子版!让你在学习python的路上变得轻 ...

  6. python 从大到小循环_python算法(3) 插入排序

    python算法(3) 插入排序 算法分析 给出一个乱序的数列,将这个数列按从小大到(从大到小)重新排列 插入排序的的逻辑是从选这个数列,一个一个的插入一到一个新的数列中 如下: 初始数列: 5 1 ...

  7. python栈是什么意思_Python算法之栈(stack)的实现

    本文以实例形式展示了Python算法中栈(stack)的实现,对于学习数据结构域算法有一定的参考借鉴价值.具体内容如下: 1.栈stack通常的操作: Stack() 建立一个空的栈对象 push() ...

  8. python编程的50种基础算法_Python算法新手入门大全

    干货:GitHub标星2.6万!Python算法新手入门大全 Python已经成为最受欢迎的程序设计语言之一.自从2004年以后,python的使用率呈线性增长.2011年1月,它被TIOBE编程语言 ...

  9. python计算四元素组合算法_python – 算法,列表元素之间的最近点

    这种方法是一种强力方法,但使用类似于Dijkstra算法的消除方法,这导致了更少的情况(使得算法最有可能快几个数量级,特别是对于大型列表或大量列表).告诉我你是否理解它,我可以澄清一下.可以在此处找到 ...

最新文章

  1. 拥抱 Node.js 8.0,N-API 入门极简例子
  2. 苹果用户可以自修手机了!原厂零件工具都能买,网友:iScrew螺丝刀600多块?...
  3. java中字段值重复校验,Java中一些常见的字段校验
  4. 上网本 ubuntu debian android,关于Debian:在Android上的chroot ubuntu 16.04上,apt-get更新失败...
  5. 从应用到底层 36张图带你进入Redis世界
  6. 微信小程序学习日记day1
  7. WPF---数据绑定之ValidationRule数据校验综合Demo(七)
  8. 在DelayQueue中更改延迟,从而更改顺序
  9. python什么软件开发好_python怎样才能学好?python软件开发什么
  10. 原创 | 我说我了解集合类,面试官竟然问我为啥HashMap的负载因子不设置成1!?...
  11. 极限 lim(x^x-(sinx)^x)/(x²arctanx)
  12. 没有基础怎么学习Web前端?相关学习路线又是什么?
  13. 为什么有些人喜欢用fiddler来抓包?
  14. 86. php 绘图体系(2)
  15. 应用安全 - 代码审计 -Java
  16. Python之路-Day2
  17. 阿里云宝塔Linux服务器管理面版初始化地址不能登入(原创)
  18. java中mergesort函数怎么用,由mergeSort引发的一些思考
  19. PanDownload:登录百度账号提示浏览器版本太低,点击下载webkit内核,然后重启软件即可
  20. sourcetree拉取项目时报错,解决两个冲突

热门文章

  1. ACL 2019开源论文 | 基于Attention的知识图谱关系预测
  2. 抢票 | AI未来说学术论坛第八期 深度学习特别专场
  3. NAACL 2019最佳论文:量子概率驱动的神经网络
  4. 蓝桥备赛第三周 倍增+贪心+素数+约数
  5. Google Colab
  6. centos 6.5安装mysql5.7,centos6.5安装mysql5.7
  7. Spring Cloud Security:Oauth2实现单点登录
  8. 刚构桥的优缺点_连续刚构桥相对于连续梁来说有优点吗
  9. TRDD got lost again
  10. linux光盘补救,Linux_忘记root密码时使用Linux系统光盘进行补救的方法,救援模式即rescue ,这个模式主 - phpStudy...