java算法leetcode_对话之反转链表

Posted jyshe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java算法leetcode_对话之反转链表相关的知识,希望对你有一定的参考价值。

人物:

两个人,我,小铮.

: 今天,我来讲解如何反转链表.

> class Solution {
> 	public ListNode reverseList(ListNode head) {
> 		//申请节点,pre和 cur,pre指向null
> 		ListNode pre = null;
> 		ListNode cur = head;
> 		ListNode tmp = null;
> 		while(cur!=null) {
> 			//记录当前节点的下一个节点
> 			tmp = cur.next;
> 			//然后将当前节点指向pre
> 			cur.next = pre;
> 			//pre和cur节点都前进一位
> 			pre = cur;
> 			cur = tmp;
> 		}
> 		return pre;
> 	}
> } 

还是需要一个临时节点的,然后判断当前不为空,然后就无限循环,循环什么呢?

是的,当前节点先拍张照,然后把当前的节点中,(一个节点有两块,前一个,当前)或(当前,下一个) ,你可能会疑问为什么不是3个,第三个是内容值吧(内容值就是当前?).

这是我猜测的,根据历史和代码猜测. 为什么要拍照当前的下一个?,一个一个向前移动,加一个临时的东西,是最容易操作的,而且直接效率高.

是不是感觉和冒泡的交换差不多,是的,就是交换下一个这种操作. 问题是:这是向前移动还是向后移动.宏观上不好判断是前移还是后移.

大体上看,把下一个给了现在的.就是 前移.

还有初始化没有说.等会说. 卧槽,忘记说目的了.

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

总结来说.题目反转,可以不反转打印前一个吗,不行,所以反转.

技术图片

  1. 需要一个临时节点的

  2. 链表结构 -->[当前值,下一个地址]

  3. 初始化.

    1. 需要在方法里建立3个节点,pre意思是前一个:设置为null,多设节点好方便操作和理解,说不定还是必须的
    2. 第二个代表当前cur,是要操作的节点的head,不是null
    3. 第三个是pre,意思是前一个,这个不是循环链表也需要前一个,代表一个意思,用来操作
  4. 判断当前不为空,然后就无限循环

  5. 循环的内容是:

    1. 当前节点的下一个节点整体(是节点)先拍张照,拍照留存给临时.

    2. 对于当前节点的下一个(head的下一个)就像这样[当前值,下一个地址],把pre粘上去,意思就是pre(当前的前一个的内存地址)(样子是引用,就像ListNode pre这样),这个操作的作用是什么呢?

      为什么要把pre==null,给下一个呢?因为pre是最后要返回的,不弄一个这个东西,后面不好返回,下一步要给pre这个东西上东西.

    3. 上东西.把当前对象(节点地址)给pre,这就是把地址前移.方法最后返回的就是pre,就是原来的地址呀.

    4. 最后就是点题了,就是操作第一步的temp,拍照肯定是要用的.临时给当前. 什么意思呢? 临时是当前的下一个,给当前,就是最简单的移动. 是不是对当前感到疑惑? 那个是当前. --->在这一个循环中,当前就是head.永远不变,最后返回的是pre.

看这个动图是不是超级疑惑,我也是.等会解释.

上面的流程还是有点混乱,我再解释一下. 过程很简单 3个z.都是连接的操作的. 循环完,第一个就删除了,4变成第1个.

开始的赋值,两个null,是有用的.只有第一次循环是null,后面都不是,这个要注意了.

? 其实要想成3条两座小船 [a1,a2] [b1,b2] [c1,c2] . b1是内容,b指b的地址,就是整体 . c的地址==b2.

现在b是head.

可以说c==b2. (所以说,每一个值都与三个有关联 a.a2=b —> b.b2=c )


tmp = cur.next; 第一步,c 拍照 .拍照,偷拍下一个,放入手机,拍照是拍照的当前这个船的尾巴.

? 第一步 null(手机)=b2 .


cur.next = pre; 第二步,b2放pre(前一个),就是当前的前一个a, 如果最开始就放null,否则就是把第一个删除了后.原来的第一个.头的前面是nulll,所以a1,a2是null.

如果到了第二个循环,a2==b就是pre.因为第一次的第三步,cur给了pre.

第二步总结说就是 : 被拍照的人 换位为 排队的前一个人. 被拍照的人呢?在相机里呢. 结束当前节点,斩断.就像香肠一样,从案板上一刀之后,消失了,到你的独自里面了. 然后有一个线连接. 因为a是空的,所以,现在是a,b都被斩断了. 一轮循环完成,就是一刀斩断. (pre== null == a == a的地址) --> 第二步就是 b2=a

重新总结: 第二步: 把一刀斩断的东西,用线连接给当前的香肠. 更为简单的就是

? 扔锚.


pre = cur; 就是 a=b. 第一次为什么操作两个节点呢?null,a不算节点,不a算节点. 每一次循环要操作3个节点.

每个循环主要是操作前两个节点,就是当前和前一个,这也是为什么叫 前移 了.第三步,总结

? 空间转换 简单说: 问题复杂的原因就是.next是一个节点.a.next=b=a2.这样说就容易乱.b给a让人很难理解,b的地址给了pre,a不是pre,pre代表的是前.(前,中,后)不永远代表某一个值,它像一个游泳池,固定就有三个游泳池.船abc,也是呀,只能代表3个状态,以前,现在,未来. 不能代表一长链子的某3个.如果当做具体的3个东西,就很容易混乱.

b的船给了a, 换船. 如果是第一步,a的船呢?第一步,a就没有船,a的船被吃了.

b的船给a, b船上的人呢?b1,b2,a1,a2 哪里去了呢? 这一步意思是, b的船给了a,a第一次是null当然是从宇宙消失了.这一步之后, pre---这个节点永远的有了数值.不在是虚幻的了.

我们很容易把下一次的循环和第一次联系起来,如果使用换船来比喻,应该是把a的人和船换为b的位置,所以不能使用换船理解.

b成为了新的 ‘前一个节点‘.所以:

? 第三步: b船的人全部到了a船,现在成为了以前,中间游泳池的人到了前面的游泳池. 已经算换位置了.现在看,第二步就已经开始换人了,一切居然悄无声息的进行了这么多,你还没有意识到. 第二步. 已经把 前船的位置(或者说整体压缩)给了船里的b2,第三步,中船给前船,直接移动就好了,没有过多的想法,然后第四步,后船给中船.后后船给后船是什么时候的操作呢?

cur.next.next是什么呢? 就是 temp.next . 问题是,什么时候,temp.next 给值? 这不就是下一个循环的开始嘛. 一次处理的是三个节点,不是4个.3.next-----不操作.

第一步的拍照缓存技术.


cur = tmp;


按理说只要两个就可以了呀,当前下一个(地址).不需要知道上一个的地址.知道上一个是不是就是双向链表? 对的.

小铮 : 小哥哥真厉害.


以上是关于java算法leetcode_对话之反转链表的主要内容,如果未能解决你的问题,请参考以下文章

Java算法 每日一题 编号206:反转链表

Java算法 每日一题 编号206:反转链表

Java算法 每日一题 编号206:反转链表

算法LeetCode 反转链表(递归)关键步骤理解

leetcode之反转链表图文详解

leetcode刷题18.反转链表——Java版